【问题标题】:Change label text when selecting UICollectionViewCell选择 UICollectionViewCell 时更改标签文本
【发布时间】:2018-10-19 09:36:05
【问题描述】:

我有一个类,我在其中定义了一个 CollectionView,我将其用作自定义 TabBar。它有三个单元格,每个单元格代表另一个选项卡。当我选择一个选项卡(因此是 CollectionView 的一个单元格)时,我想更新视图中标签的文本。

在 tabs.swift 中(所有的魔法都发生在设置自定义标签栏的地方),我添加了以下函数:

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

    let uvController = UserViewController()
    uvController.longLabel.text = "Test"

}

在 UserViewController 中,我这样称呼它:

let ProfileTabs: profileTabs = {

    let tabs = profileTabs()
    return tabs

}()

它显示了我想要的所有选项卡,但是当我选择它时,标签不会更新。但是,当我执行打印操作时,它会返回标签的值:

print(uvController.longLabel.text)

这将返回我在设置标签时定义的值,因此我实际上可以访问标签,但它不会按照我的意愿更新。关于为什么没有发生这种情况的任何见解?

【问题讨论】:

  • uvController是你定义的Custom UICollectionView吗?
  • @EdisonLo 不,uvController 指的是 UIViewController 包含我的主视图的所有元素。所以tabs.swift只引用了TabBar,它定义在UserViewController中(见上面的代码),高度为44px,下面是longLabel,也是UserViewController中定义的,我要更新一下。

标签: ios swift uicollectionview uilabel


【解决方案1】:
let uvController = UserViewController()

这行是问题。

您实例化一个新的 UserViewController 而不是引用您当前的 UserViewController,这样标签就不一样了。可以打印(UserViewController)查看,地址应该不一样。

我的建议是你可以在 Tabs.swift 中定义一个协议,并让你的 UserViewController 成为它的委托,以接收更新操作。

同时,let ProfileTabs: profileTabs 也不是一个好的命名约定,通常自定义类应该是大写字母而不是变量。

【讨论】:

  • 很有意义,它让我走上了正轨,谢谢!我还将 ProfileTabs 更改为 profileTabs ,反之亦然 - 我通常会像你提到的那样命名所有内容,但显然在这个上犯了一个错误。谢谢!
【解决方案2】:

这一行 - let uvController = UserViewController() 创建了一个不在屏幕上的 UserViewController 的新实例。您需要参考已经向用户显示的那个。你可以这样做:

  1. 最快的方法。 只需在 ProfileTabs 初始化程序中传递实例。像这样:

    class ProfileTabs {
        let parentViewController: UserViewController
    
        init(withParent parent: UserViewController) {
            self.parentViewController = parent
        }
    
        // and then change to :
       func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    
            parentViewController.longLabel.text = "Test"
    
        }
    }
    
  2. 更清洁的方式。使用委托。

    protocol ProfileTabsDelegate: class {
        func profileTabs(didSelectTab atIndex: Int)
    }
    
    class ProfileTabs {
        weak var delegate: ProfileTabsDelegate?
    
        init(withDelegate delegate: ProfileTabsDelegate) {
            self.delegate = delegate
        }
    
        // and then change to :
       func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
            delegate?.profileTabs(didSelectTab: indexPath.item)
    
        }
    }
    

    然后在UserViewController

    extension UserViewController: ProfileTabsDelegate {
        func profileTabs(didSelectTab atIndex: Int) {
            longLabel.text = "Test"
        }
    }
    

【讨论】:

  • 试图实现这一点,但它抛出了这个错误:在从初始化程序返回之前,所有路径上都没有调用“super.init” - 我已经覆盖 init 来设置我的框架(覆盖 init(frame: CGRect),我在其中调用 super.init(frame:frame))。我可以将这两者结合起来吗?
  • 是的,你可以。或者您可以在初始化后通过属性传递parentViewController/delegate。不过,您必须将其公开。
  • 我该怎么做 - 初始化后将其作为属性传递?我似乎无法让它工作。当我试图将它们结合起来时,它也抛出了一些错误。以前从未这样做过,所以我对如何正确地做一些疯狂的猜测,但显然我一直在做错。
  • let pTabs = ProfileTabs() 然后pTabs.delegate = self,或pTabs.parentViewController = self,具体取决于您选择的路线。
  • 我让它工作了。我必须将 parentViewController 设为可选。然后在我的函数 setupViews() 中声明选项卡。现在按预期工作!谢谢你一千次!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-03-30
  • 1970-01-01
  • 2013-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-18
相关资源
最近更新 更多