UIViewController xib 文件包含一个带有自定义单元格的集合视图

Posted

技术标签:

【中文标题】UIViewController xib 文件包含一个带有自定义单元格的集合视图【英文标题】:UIViewController xib file containing a collectionview with a custom cell 【发布时间】: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 建议的那样创建另一个故事板。也许这样是不可能的。 【参考方案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 文件,也许它不是为此而设计的。

以上是关于UIViewController xib 文件包含一个带有自定义单元格的集合视图的主要内容,如果未能解决你的问题,请参考以下文章

iOS3、iOS4、xibbed UIViewController 及显示数据

如何在没有xib文件的情况下使用uiviewcontroller

如何从 .XIB 加载 UIViewController?

如何在 .xib 文件上创建的 UIViewController 中设置 UITableView

你真的了解UIViewController生命周期吗?

UIViewController XIB 的首选惯用语