【问题标题】:UIViewController xib file containing a collectionview with a custom cellUIViewController xib 文件包含一个带有自定义单元格的集合视图
【发布时间】:2018-12-18 18:03:07
【问题描述】:

我有一个 xib 文件,其中包含一个名为 FullScreenGalleryVCUIViewController。它包含一个UICollectionView,其中包含一个自定义UICollectionViewCell,其标识符为fullscreen_cell

当我想创建一个新的FullScreenGalleryVC 时,我调用FullscreenGalleryVC.display(from: self)

函数如下:

class func display(from sourcevc:UIViewController){
    let vc=UINib(nibName: "FullscreenGalleryVC", bundle: nil).instantiate(withOwner: nil, options: nil)[0] as! FullscreenGalleryVC
    sourcevc.present(vc, animated: true, completion: nil)
}

我收到此错误:

无法将一种视图出列:UICollectionElementKindCell with 标识符 fullscreen_cell - 必须为 标识符或连接情节提要中的原型单元


如果我将自定义单元格放在另一个 xib 文件中并调用 register(nibClass, forCellWithReuseIdentifier: cellId),它会正常工作。

如果我不将此 FullScreenGalleryVC 类放在单独的 xib 文件中(并将其保存在我的主故事板中),它会正常工作。


但是我在应用程序和操作扩展中都使用这个类,这就是为什么我想使用一个通用文件而不是复制所有内容的原因。 有没有办法做到这一点,或者我必须将自定义单元格放在不同的 xib 文件中才能使其工作?

【问题讨论】:

  • 你实现override init(frame: CGRect) { super.init(frame: frame) }required public init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) }Bundle.main.loadNibNamed("yourXib", owner: self, options: nil)了吗?
  • @canister_exister 不,我为什么需要它?
  • 因为你创建了xib。查看一些教程,例如:medium.com/@umairhassanbaig/… 和这个:medium.com/@brianclouser/…
  • 您找到解决方案了吗?
  • 还没有。我检查了你的链接,但它们没有帮助。我知道如何从 xib 文件创建自定义视图或单元格,但这种情况是特定的。我想我要么需要为单元格制作一个单独的 xib,要么像@Bappaditya 建议的那样创建另一个故事板。也许这样是不可能的。

标签: ios swift uicollectionview uicollectionviewcell xib


【解决方案1】:

如果您是 FullScreenGalleryVC 控制器的 xib 文件,那么您应该使用 register(nibClass, forCellWithReuseIdentifier: cellId) 告诉集合视图如何创建给定类型的新单元格。

let cellNib = UINib(nibName: "FullScreenGalleryCell", bundle: .main) 
collectionView.register(cellNib, forCellWithReuseIdentifier: "fullscreen_cell")

如果您使用storyboard,则集合视图已经知道指定cellId

在我看来,您可以将storyboard 用于FullScreenGalleryVC,并将其用于其他类。

从特定的storyboard 中呈现一个 viewController,

let storyboard = UIStoryboard(name: "YourStoryboardName", bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier: "storyboardId")
self.present(controller, animated: true, completion: nil)

【讨论】:

  • 如果我使用let nibCell=UINib(nibName: "FullScreenGalleryCell", bundle: nil)register(nibCell, forCellWithReuseIdentifier: "fullscreen_cell") 我得到Could not load NIB in bundle。如果我改用 xib 文件名:let nibCell=UINib(nibName: "FullscreenGalleryVC", bundle: nil)register(nibCell, forCellWithReuseIdentifier: "fullscreen_cell") 我得到 invalid nib registered for identifier (fullscreen_cell)
  • 试试这个,let cellNib = UINib(nibName: "FullScreenGalleryCell", bundle: .main)collectionView.register(cellNib, forCellWithReuseIdentifier: "fullscreen_cell")
  • 我收到Could not load NIB in bundle 'NSBundle <.../AppName.app> (loaded)' with name 'FullScreenGalleryCell'
  • 这是来自上述案例的完整错误消息:invalid nib registered for identifier (fullscreen_cell) - nib must contain exactly one top level object which must be a UICollectionReusableView instance
  • 它适用于单独的故事板,但我不知道如何使其适用于 xib 文件,也许它不是为此而设计的。