嵌套自定义视图中UICollectionView始终为nil问题求助
遇到嵌套自定义视图里控件为nil的情况,通常都是视图初始化、IBOutlet连接或者加载时机出了问题,我给你列几个最常见的排查方向:
检查EBPhotosView的初始化逻辑
如果你的EBPhotosView是用XIB/Storyboard创建的,那在EBEventDetailsView中添加它时,必须通过XIB加载,而不是直接用init(frame:)初始化。后者不会加载XIB里的控件,导致collectionView始终为nil。正确的加载方式应该是:let photosView = EBPhotosView(nibName: "EBPhotosView", bundle: nil) // 接着设置frame或约束,再添加到EBEventDetailsView的视图层级中要是你用的是Storyboard,确保EBPhotosView在EBEventDetailsView的Storyboard场景里已经正确添加,并且其类属性设置为
EBPhotosView,而不是默认的UIView。验证UICollectionView的IBOutlet连接
打开EBPhotosView的XIB,右键点击UICollectionView,检查它的IBOutlet是否正确连接到EBPhotosView代码中的collectionView属性。也可以反过来,在代码中右键@IBOutlet weak var collectionView: UICollectionView!,看是否指向XIB里的集合视图。如果连接断开或者拼写错误,运行时这个属性就会是nil。确认视图加载时机
你是不是在EBPhotosView还未完成初始化时就访问了collectionView?比如在EBEventDetailsView的init、awakeFromNib方法里直接操作SecondView的collectionView?这时候EBPhotosView的viewDidLoad还没执行,控件还没完成初始化。建议把对collectionView的操作放在EBPhotosView的viewDidLoad里,或者给EBPhotosView添加一个初始化完成的回调,通知上层视图再进行操作。纯代码创建的特殊检查
如果EBPhotosView是完全用代码创建的,那你需要确认是否手动初始化了UICollectionView并将其添加到视图层级中。比如有没有写类似这样的代码:override init(frame: CGRect) { super.init(frame: frame) setupCollectionView() } required init?(coder: NSCoder) { super.init(coder: coder) setupCollectionView() } private func setupCollectionView() { let layout = UICollectionViewFlowLayout() let collectionView = UICollectionView(frame: bounds, collectionViewLayout: layout) collectionView.dataSource = self collectionView.delegate = self collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "Cell") addSubview(collectionView) // 设置约束(如果用AutoLayout) collectionView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ collectionView.topAnchor.constraint(equalTo: topAnchor), collectionView.leadingAnchor.constraint(equalTo: leadingAnchor), collectionView.trailingAnchor.constraint(equalTo: trailingAnchor), collectionView.bottomAnchor.constraint(equalTo: bottomAnchor) ]) self.collectionView = collectionView // 赋值给类属性 }如果漏了初始化、添加到视图或者赋值给属性,collectionView自然会是nil。
你可以按这个顺序逐一排查,大部分情况下都是前三个原因导致的问题。
内容的提问来源于stack exchange,提问作者rameez

