连接的 IBOutlets 未初始化

Posted

技术标签:

【中文标题】连接的 IBOutlets 未初始化【英文标题】:Connected IBOutlets are not initialized 【发布时间】:2014-08-06 00:00:36 【问题描述】:

我已经在 Swift 中实现了自定义 UICollectionViewCell 类,使用 UICollectionViewCotroller 创建了故事板,分配了我的自定义控制器类、自定义单元格类、单元格 ID 等...基本上所有使 UICollectionViewController 工作所需的一切。

在故事板单元原型中,我添加了一些视图并将它们作为 IBOutlets 连接到我的自定义单元类:

这里是我的 IBOutlets 代码(如您所见,它们已连接):

我也在我的控制器中注册了自定义单元类:

self.collectionView.registerClass(MyCollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier)

当我在代码中将单元格出列时,它会返回我的自定义类型的单元格,但两个 IBOutlets 都没有初始化(等于 nil

    let cell = collectionView?.dequeueReusableCellWithReuseIdentifier(reuseIdentifier,
    forIndexPath: indexPath) as MyCollectionViewCell

    if let path = indexPath 
        // Crash here as imageView is nil
        cell.imageView.image = imagesArray[path.item] 
    

崩溃日志:

fatal error: unexpectedly found nil while unwrapping an Optional value

如果我在上面的if 语句上设置断点并执行po cell 我有这个输出:

(lldb) po cell
0x00007fa799f4cdf0
 
  UIKit.UICollectionViewCell = 
    UIKit.UICollectionReusableView = 
      UIKit.UIView = 
        UIKit.UIResponder = 
          ObjectiveC.NSObject = 
        
      
    
  
  selectionView = nil
  imageView = nil

任何想法为什么 IBOutlets 没有被初始化?

【问题讨论】:

【参考方案1】:

这是因为 IBOutlets 稍后在initWithCoder 完成后连接。

要在连接后设置控件,您可以在 UIColletionViewCell 子类中覆盖 - applyLayoutAttributes:

override func applyLayoutAttributes(layoutAttributes: UICollectionViewLayoutAttributes) 
    setupControls()

根据文档,它是一个空方法,意味着被覆盖以便将自定义布局属性应用于视图。听起来差不多。

【讨论】:

【参考方案2】:

从 Beta5 开始,我遇到了同样的问题,但使用 xib 而不是使用情节提要。 在 xib 的情况下,似乎是

的问题
init(nibName: nil, bundle: nil) 

没有选择默认的 xib 文件名。当我更改为显式 nibName

init(nibName: "MyClass", bundle: nil) 

然后它又开始工作了。故事板也有同样的问题 - 如果有办法强制故事板名称,我会尝试。

【讨论】:

【参考方案3】:

好吧,我也遇到了这个问题,我的问题是通过将 Register api of collection view 注释为以下代码 sn-p 来解决的。我相信我们正在使用 storyboard 。我们已经提供了所有信息,例如 (Class , outlets 和 identifier ) 。所以情节提要处理这一切。

func configureCollectionView(isNib:Bool = false)

    if isNib
    
        //collectionView.register(UINib(nibName: "GalleryCell", bundle:nil), forCellWithReuseIdentifier: identifier)
    
    else
    
        //collectionView.register(PhotoCell.self,forCellWithReuseIdentifier:identifier);
    


【讨论】:

【参考方案4】:

如果这是 beta 4 或 5,并且我认为它基于 IBOutlets 是可选的,那么您是否在类中重写了 initWithCoder?即使是一个除了调用超级之外什么都不做的人?丢失可能是您的问题。

编辑:您是否尝试过确保重用标识符在情节提要和代码中都匹配?

【讨论】:

它是 Beta5。在 Beta5 中,IBOutlets 被初始化(在 Ctrl-drag 上自动)为IBOutlet weak var variableName: VarType。是的,我覆盖了 initWithCoder。这是 Beta5 中的编译时错误 - 如果 UIView 子类没有覆盖它,您将无法构建您的应用程序。 没错。它不再只是崩溃,而是一个真正的错误。

以上是关于连接的 IBOutlets 未初始化的主要内容,如果未能解决你的问题,请参考以下文章

在为自定义视图调用 NSBundle(使用 loadNibName)后访问 IBOutlets 的最佳方法

使用 IBOutlets 将视图控制器初始化为自定义视图

iOS - Interface Builder Outlets 未初始化

故事板 instantiateViewControllerWithIdentifier 未设置 IBOutlets

所有 IBOutlets 都是零

当在 nib 中声明 UITableView 时,UITableViewCell nil IBOutlets [重复]