代码之家  ›  专栏  ›  技术社区  ›  Scaraux

当向数据源添加值时,ibdesignable with collectionview崩溃

  •  0
  • Scaraux  · 技术社区  · 7 年前

    我正在做一个小的 UIView 组件,该组件在 UICollectionView 出于某些原因,我需要通过界面生成器使其“可编辑”…所以,我成功了 IBDesignable .

    一切正常,除非在 prepareForInterfaceBuilder 我正在尝试将对象附加到 datasource ,因此当列表集成到故事板的某个位置时,它会显示一些内容。

    到达线路 self.hashtags.append(hashtag) ,这就崩溃了。如果我删除这一行,则视图将在情节提要上正确呈现,如果我再次将其放置--->崩溃…经过我所有的调试,ib似乎无法访问这个属性或看到它为零。

    我无法调试 任何东西 ,xcode不允许我在脚本编辑器中调试所选视图(在macos mojave上会导致错误)。我的观点没有 .xib ,并且两者都是必需的 init

    我还查看了console.app中的日志,结果什么也没有。以下是故事板给出的主要错误消息:

    main.storyboard:错误:ib designables:未能呈现和更新publishviewcontroller(tsg-9e-vz3)的自动布局状态:代理引发异常。

    代码(重要的是)

    @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
    }
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   agibson007    7 年前

    所以设置肯定是相关的。显然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
        }
    }
    

    结果: enter image description here

    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设置如下: nib

    这可能会给你更多的灵活性,这取决于你在做什么,结果是相似的,除了在nib的例子中,我使用了一个uibutton。 enter image description here