重用集合视图的 XIB 视图作为其他视图的一部分?

Posted

技术标签:

【中文标题】重用集合视图的 XIB 视图作为其他视图的一部分?【英文标题】:Reusing XIB views for collectionviews as a partial for other views? 【发布时间】:2017-03-13 16:01:33 【问题描述】:

我想为集合视图和其他视图重用一个 XIB 文件。

例如,我有一张卡片需要显示为集合视图单元格,但我也想为独立页面使用相同的 xib/view。

即;

我想对集合视图和普通视图使用相同的卡片图像,就像它是部分视图一样;因此可以在我需要的任何地方使用它。

我这样注册我的手机;

self.myCollectionView.register(UINib(nibName: "MyCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "myCellIdentifier")

那就用吧;

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
        let cell:MyCollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: "myCellIdentifier", for: indexPath) as! MyCollectionViewCell

...

我尝试使用我创建的 UIView 强制转换 dequeueReusableCell 代码,但它不喜欢以这种方式使用视图。

单元格和我的 XIB 视图文件都是独立的 swift 文件,因此它不在情节提要中。

如何将一个 uiview 用于集合视图,然后在其他页面上重复使用相同的视图?

非常感谢

总结

我想在应用的很多地方使用一个 UIView 和 XIB 文件

目前,我有一个使用 UICollectionViewCell 和关联的 XIB 文件的集合视图

我想在应用的很多地方使用同一个 XIB 文件。

如何在我的集合视图和应用程序中我需要它的地方重用相同的 UIView?

谢谢

【问题讨论】:

澄清一下,您有一个collectionViewCell,并且在单元格内您有一个从笔尖加载视图的视图,对吗? (a) 我有一个我创建的 swift 文件;它是一个自定义的子类 UICollectionViewCell。它有一个 XIB 文件。 (b) 我想在应用程序的其他地方重用相同的 XIB,包括所有插座和连接。 你能说明一下吗? 我会尝试在我的问题中详细阐述 “我如何在我的收藏视图和应用程序中我需要它的地方重用相同的 UIView?”我想我的问题是为什么你觉得这很困难。您所要做的就是加载 nib 文件并在每次需要“部分”的新副本时拉出视图。问题是你不知道怎么做吗? 【参考方案1】:

(a) 我有一个我创建的 swift 文件;它是一个自定义的子类 UICollectionViewCell。它有一个 XIB 文件。

在集合视图中注册 nib。在cellForItemAt 中,当您需要一个单元格时,将其出列。您将从笔尖收到收藏视图单元格的副本。根据需要配置它。退货吧。

(b) 我想在应用程序的其他地方重复使用相同的 XIB,包括所有插座和连接

加载笔尖并拉出第一个(也是唯一的)顶层视图。您将从笔尖收到收藏视图单元格的副本。将其作为子视图添加到界面中的视图中。

(最简单的方法是通过 UINib 及其 instantiate 方法。这将返回***对象的数组。)

确实,通常不会将集合视图单元格用作普通视图的子视图。但是我想不出任何反对它的理由;毕竟,一个视图就是一个视图。

(如果您不想这样做,我可以考虑解决方法;例如,将 nib 中的视图设为自定义 UIView 并通过加载 nib 并将该视图放入单元格中来配置每个单元格。这将介绍一些不便之处,但它会使笔尖更普遍可用。)


我做了一个简单的例子。这是笔尖,非常简单,因为它只是一个示例:

这是我的应用程序,显示一个集合视图(在蓝色背景上显示四个单元格)以及从笔尖提取并粘贴到界面中的视图:

这是整个代码:

class MyView : UIView 
    @IBOutlet var iv : UIImageView?


class MyCell : UICollectionViewCell 
    var v : MyView?


class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate 
    @IBOutlet weak var cv: UICollectionView!

    override func viewDidLoad() 
        super.viewDidLoad()
        self.cv.register(MyCell.self, forCellWithReuseIdentifier: "cell")
        let arr = UINib(nibName: "View", bundle: nil).instantiate(withOwner: nil, options: nil)
        let v = arr[0] as! UIView
        self.view.addSubview(v)
        v.frame.origin = CGPoint(x:20, y:300)
    

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 
        return 4
    

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! MyCell
        if cell.v == nil 
            let arr = UINib(nibName: "View", bundle: nil).instantiate(withOwner: nil, options: nil)
            let v = arr[0] as! MyView
            cell.contentView.addSubview(v)
            cell.v = v
        
        print(cell.v?.iv) // image view
        return cell
    


注意子类和出口的使用。 cell.v 将我们带到视图,所以cell.v?.iv 将我们带到图像视图 - 现在我们可以根据需要执行进一步的配置。因此,为了从 nib 到达子视图,我们添加了一层间接性,但这似乎是一个很小的代价。

【讨论】:

是的,我想用带有 XIB 的独立 UIView 替换我当前的 UICollectionViewCell;然后这个相同的 UIView 将可以在其他地方使用。我一直在查看 github 和其他 *** 帖子,看看其他人是如何加载视图的,这方面的代码似乎可以理解 出列单元格就是出列 UICollectionViewCell;我尝试用一​​个简单的 UIView 替换它,但它不喜欢 UIViews 被用作dequeueReusableCell 我已经看到人们通过 UINib 实例加载视图的示例,所以我将尝试这些。 如果您在 nib 中的***对象不是 UICollectionViewCell,您将无法通过注册 nib 来获取它作为您的单元格。正如我在上面建议的解决方法中所说,您必须注册 UICollectionViewCell 类、获取单元格、加载 nib、提取视图并将其填充到单元格中。但是,当然,前提是该单元格不是重复使用的单元格。缺点是您的出口将是子视图的出口,而不是单元格本身。但你也许可以忍受。 添加了一个屏幕截图,显示这可以工作。我使用了上一段中描述的解决方法,笔尖中的***对象是视图,而不是单元格。

以上是关于重用集合视图的 XIB 视图作为其他视图的一部分?的主要内容,如果未能解决你的问题,请参考以下文章

我可以使用 UIView(.xib 和类)作为许多视图的视图基础示例吗?

如何同时支持纵向和横向模式 - XIB 的可重用视图

使用自动布局的 xib 添加为子视图时不显示

Collection View Xib Cell Bug 中的表视图

具有相同 XIB 单元格和按钮的多个集合视图

尽管已正确初始化,XIB 视图仍不显示任何内容