在没有情节提要的情况下在 UIView 中添加 UICollectionView

Posted

技术标签:

【中文标题】在没有情节提要的情况下在 UIView 中添加 UICollectionView【英文标题】:Adding UICollectionView inside UIView without Storyboards 【发布时间】:2017-06-04 15:01:02 【问题描述】:

我有一个名为 myVC 的 ViewController 和 UITablewView - myTable

我想要添加一些 UIView 作为 myTable's headerView 从代码。所以在 myVC 的 viewDidLoad() 方法中我添加了这段代码

    let topView = TopView()
    topView.frame.size.height = 100
    topView.frame.size.width = myTable.frame.width
    myTable.tableHeaderView = featuredEventsView

我还创建了一个名为 TopView.swift 的文件,看起来像

class TopView : UIView 
    override init(frame: CGRect) 
        super.init(frame: frame)            
        self.backgroundColor = .red
    

    required init?(coder aDecoder: NSCoder) .....

它正在正常工作。我在 myTable 的 headerView 中看到红色 UIView。

现在我想在 topView 中添加 UICollectionView,但这里有问题。我正在尝试做类似的事情

class TopView : UIView, UICollectionViewDataSource, UICollectionViewDelegate 
    override init(frame: CGRect) 
        super.init(frame: frame)            
        self.backgroundColor = .red

        addSubview(myCollectionView)
    

    required init?(coder aDecoder: NSCoder) .....

let myCollectionView : UICollectionView = 
        let cv = UICollectionView()
        cv.translatesAutoresizingMaskIntoConstraints = false
        cv.delegate = self as! UICollectionViewDelegate
        cv.dataSource = self as! UICollectionViewDataSource
        cv.backgroundColor = .yellow
        return cv
    ()

我还创建了 UICollectionViewDataSource 所需的函数,但构建后应用程序崩溃。我做错了什么?

【问题讨论】:

“应用程序在构建后崩溃” ... 错误消息?您是否通过调试来找出导致崩溃的确切位置? "libc++abi.dylib: 以 NSException 类型的未捕获异常终止" - 这就是我所看到的 - 我怎样才能得到更多? 设置调试断点,逐行逐行执行,直到找到导致崩溃的确切代码。 好的,在 let topView = TopView() 之后就崩溃了 之后的代码行是什么?或者你的意思是它会在inside那条线中崩溃?就像在TopView init 中一样?如果是这样,在哪条线上?而且您必须得到的错误比您在此处显示的要多...您是否打开了调试控制台窗格?除了“libc++abi.dylib:以未捕获的NSException类型的异常终止”之外,真的有什么都没有吗? 【参考方案1】:

你有两个问题:

1) 你初始化你的 UICollectionView 不正确,因为你必须给它一个布局。你需要这样的东西(使用你想要的任何框架,但如果你继续使用自动布局也没关系):

let layout = UICollectionViewFlowLayout()
let cv = UICollectionView(frame: CGRect.zero, collectionViewLayout: layout)

2) 初始化属性时,不能在闭包内引用“self”。这是因为 if 可能尚未初始化(如本例所示),因此您无法保证使用它是安全的。

我认为如果你使用这样的惰性初始化应该没问题(而且你甚至不需要强制转换'self'):

lazy var myCollectionView : UICollectionView = 
    let layout = UICollectionViewFlowLayout()
    let cv = UICollectionView(frame: CGRect.zero, collectionViewLayout: layout)
    cv.translatesAutoresizingMaskIntoConstraints = false
    cv.delegate = self
    cv.dataSource = self
    cv.backgroundColor = .yellow
    return cv
()

使用惰性方法应该延迟到 self 被初始化,因此可以安全使用。

【讨论】:

以上是关于在没有情节提要的情况下在 UIView 中添加 UICollectionView的主要内容,如果未能解决你的问题,请参考以下文章

在没有任何情节提要参考的情况下在控制器之间传递数据

在 Swift 3 中使用 didSelect 和 navigationController 在没有情节提要的情况下在 TableViewControllers 之间传递数据

如何在不添加另一个 UIView 的情况下为情节提要中的 uitableViewCell 制作等宽分隔符?

是否可以在不使用情节提要的情况下在 xib 文件中创建原型内容 UITableview?

使用 Swift 向 UIView 添加碰撞

将 UIView 添加到情节提要