向 DataSource 添加值时,带有 CollectionView 的 IBDesignable 崩溃
Posted
技术标签:
【中文标题】向 DataSource 添加值时,带有 CollectionView 的 IBDesignable 崩溃【英文标题】:IBDesignable with CollectionView crashes when add value to DataSource 【发布时间】:2018-06-07 20:14:38 【问题描述】:我正在开发一个小型 UIView
组件,该组件在 UICollectionView
中显示主题标签,出于某些原因,我需要通过 Interface Builder 使其“可编辑”...因此,我将其设为 IBDesignable
。
除了在prepareForInterfaceBuilder
中之外,一切都有效
到达self.hashtags.append(hashtag)
行时,这会崩溃。如果我删除这一行,则视图会在情节提要上正确呈现,如果我再次放置 ---> 崩溃...经过我所有的调试,似乎 IB 无法访问此属性或看到它为零。
我无法调试任何东西,Xcode 不允许我在 Storyboard > Editor 中调试选定的视图(在 macOS Mojave 上会导致错误)。我的视图没有.xib
,并且都需要init
的
我还检查了 Console.app 中的日志,但什么也没有。这是 Storyboard 给出的主要错误信息:
Main.storyboard: error: IB Designables: Failed to render and update auto layout status for PublishViewController (tSg-9E-Vz3): agent throw an exception.
代码(重要的)
@IBDesignable
class HashtagView: UIView
@IBOutlet weak var height: NSLayoutConstraint?
var collectionView: UICollectionView =
let layout = UICollectionViewFlowLayout()
let view = UICollectionView(frame: .zero, collectionViewLayout: layout)
return view
()
open var hashtags: [HashTag] = []
override init(frame: CGRect)
super.init(frame: frame)
setup()
required init?(coder aDecoder: NSCoder)
super.init(coder: aDecoder)
setup()
override func prepareForInterfaceBuilder()
super.prepareForInterfaceBuilder()
setup()
self.hashtags.append(HashTag(word: "it works")) < CRASH
self.collectionView.reloadData()
self.layoutSubviews()
设置函数()
func setup()
self.backgroundColor = UIColor.clear
self.backgroundColor = UIColor.Custom.ligthGray
self.clipsToBounds = true
self.layer.cornerRadius = self.cornerRadius
let alignedFlowLayout = AlignedCollectionViewFlowLayout(horizontalAlignment: .left, verticalAlignment: .top)
alignedFlowLayout.minimumLineSpacing = 5.0
alignedFlowLayout.minimumInteritemSpacing = 7.0
alignedFlowLayout.sectionInset = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
self.collectionView.collectionViewLayout = alignedFlowLayout
self.collectionView.translatesAutoresizingMaskIntoConstraints = false
self.collectionView.delegate = self
self.collectionView.dataSource = self
self.collectionView.backgroundColor = UIColor.clear
self.collectionView.isScrollEnabled = false
self.collectionView.register(UINib(nibName: "RemovableTagCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "RemovableTagCollectionViewCell")
self.addSubview(self.collectionView)
self.collectionView.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true
self.collectionView.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true
self.collectionView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
self.collectionView.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
【问题讨论】:
设置函数在哪里? @agibson007 刚刚添加了它。我确定它不是从这里通过它没有任何问题 不太确定 collectionView 是否可以是 IBDesignable。也许一个 UIStackview 代替 @agibson007 好吧,我也不确定......然后我看到有人在这样做......但是,UICollectionView 似乎不是问题...... 【参考方案1】:所以设置肯定是相关的。显然 IB 在尝试为您的 UICollectionView 加载您的单元格时崩溃了。它无法加载 Nib 文件。它与它同时崩溃的附加没有任何关系。我复制了您的问题,然后用代码创建了一个单元格,一切正常。让我知道这是否有助于并回答您的问题。所有必需的代码都在那里。
import UIKit
struct HashTag
var word:String?
class HashCollectionViewCell: UICollectionViewCell
lazy var wordLabel : UILabel =
let lbl = UILabel(frame: self.bounds)
lbl.font = UIFont.systemFont(ofSize: 17)
lbl.textColor = .black
return lbl
()
override init(frame: CGRect)
super.init(frame: frame)
self.addSubview(wordLabel)
required init?(coder aDecoder: NSCoder)
super.init(coder: aDecoder)
self.addSubview(wordLabel)
func configureWithTag(tag:HashTag)
wordLabel.text = tag.word
@IBDesignable
class HashTagView: UIView
private var sizingLabel = UILabel(frame: .zero)
lazy var collectionView: UICollectionView =
let layout = UICollectionViewFlowLayout()
let view = UICollectionView(frame: self.bounds, collectionViewLayout: layout)
view.autoresizingMask = [.flexibleWidth,.flexibleHeight]
return view
()
var hashtags: [HashTag] = [HashTag(word: "this works")]
override init(frame: CGRect)
super.init(frame: frame)
setup()
required init?(coder aDecoder: NSCoder)
super.init(coder: aDecoder)
setup()
func setup()
sizingLabel.font = UIFont.systemFont(ofSize: 17)
self.addSubview(collectionView)
collectionView.frame = self.bounds
collectionView.backgroundColor = self.backgroundColor
collectionView.register(HashCollectionViewCell.self, forCellWithReuseIdentifier: "hashCell")
self.addSubview(collectionView)
for x in 0..<10
addHashTag(tag: "This is more \(x)")
collectionView.delegate = self
collectionView.dataSource = self
func addHashTag(tag:String)
let newHash = HashTag(word: tag)
self.hashtags.append(newHash)
override func layoutSubviews()
super.layoutSubviews()
collectionView.frame = self.bounds
extension HashTagView: UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
return hashtags.count
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "hashCell", for: indexPath) as? HashCollectionViewCell
let tag = self.hashtags[indexPath.item]
cell.configureWithTag(tag: tag)
return cell
return UICollectionViewCell()
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
let tag = self.hashtags[indexPath.item]
sizingLabel.text = tag.word
sizingLabel.sizeToFit()
return sizingLabel.frame.size
结果:
2) 您可以将 nib 加载到以编程方式创建的单元格中,它会起作用。一个示例看起来像这样,而不是作为编程单元格的部分。
带有视图扩展的单元格代码,在单元格内使用 nib:
extension UIView
func loadNib() -> UIView
let bundle = Bundle(for: type(of: self))
let nibName = type(of: self).description().components(separatedBy: ".").last!
let nib = UINib(nibName: nibName, bundle: bundle)
return nib.instantiate(withOwner: self, options: nil).first as! UIView
class HashCollectionViewCell: UICollectionViewCell
var hashTagNib : HashTagNibView?
override init(frame: CGRect)
super.init(frame: frame)
setup()
required init?(coder aDecoder: NSCoder)
super.init(coder: aDecoder)
setup()
func setup()
if let htn = HashTagNibView().loadNib() as? HashTagNibView
hashTagNib = htn
hashTagNib?.frame = self.bounds
hashTagNib?.autoresizingMask = [.flexibleWidth,.flexibleHeight]
self.addSubview(htn)
func configureWithTag(tag:HashTag)
if let htn = hashTagNib
htn.hashTagButtonLabel.setTitle(tag.word, for: .normal)
笔尖设置如下所示:
这可能会给你更多的灵活性,这取决于你在做什么,结果是相似的,除了在 nib 示例中我使用了 UIButton。
【讨论】:
我在家的时候试试。谢谢! 是的,似乎是原因。这很奇怪。我可以知道我调试了所有这些并弄清楚了吗? 好吧,我在顶部的编辑器中单击并单击调试选定视图。在 Xcode 完全崩溃之前,我短暂地看到了堆栈跟踪。它再也不会出现了。但是我评论了除了追加之外的所有内容并且没有崩溃。只有在 colllectionview 开始加载之后它才会崩溃(空数组没有加载也没有崩溃)所以我很快但将一个程序单元放在一起,它工作得很好。这样做有一段时间了,所以真的从来没有被我想解决的问题难住。学会了如何隔离问题。如果这是可以接受的答案,请接受。 @FrenchFalcon 我确实为您添加了一种在单元格内使用笔尖视图的方法,它应该可以工作。很好奇集合视图无法将笔尖直接加载为单元格。我认为是因为当使用 IBDesignable 时,它只调用带有框架的 init。 这太棒了。谢谢。我的 Xcode 完全充满了错误,并且崩溃是它报告的唯一内容。然后是一长串的重建、清理甚至删除 DerivedData。在我这边,调试选定的视图给我一个“无法附加 PID 错误”,主要是因为 Xcode beta 和 macOS beta,所以我没有机会看到这个错误的出现。你知道为什么不能直接将单元格作为笔尖加载,而是将其内容作为实际笔尖加载吗?以上是关于向 DataSource 添加值时,带有 CollectionView 的 IBDesignable 崩溃的主要内容,如果未能解决你的问题,请参考以下文章
concurrentPerform UnsafeMutablePointer.deinitialize 向数组添加值时出错
向 Firebase 实时数据库添加新值时如何保存当前日期/时间