为什么我们需要通过dequeueReusableCell函数获得的upcasting cell?

时间:2018-01-17 10:56:26

标签: ios swift uicollectionview

我对

中的事实感到非常困惑
 override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! MessageCell
    if let message = messages?[indexPath.item] {
        cell.message = message
    }
    cell.timeLibel
    return cell
}

我应该将单元格向上转换为由reuseIdentifier隐含的类。事实证明(在我的情况下)deqeueReusableCell函数的结果不是MessageCell类,即使我已经注册了它

 collectionView?.register(MessageCell.self, forCellWithReuseIdentifier: cellId)

此外,当我试图通过

看到它是真实的而不是MessageCell实例
cell.isKind(of: MessageCell.self)

它返回true。但是在我尝试访问MessageCell类的实例属性的同时,它会抛出一个错误"类型' UICollectionViewCell'没有会员的消息"

但参考说:

  

在您的委托方法中取消适当的视图后,   配置其内容并将其返回到集合视图以供使用。

并参考UICollectionViewDataSource:

  

您对此方法的实施负责创建,   配置并返回给定项目的相应单元格。   你这样做是通过调用   dequeueReusableCell(withReuseIdentifier:for :)方法集合   查看并传递与该单元格对应的重用标识符   你想要的类型。

为什么我们需要向上转播 let cell = collectionView.dequeueReusableCell(withReuseIdentifier:cellId,for:indexPath)

这是MessageCell等

 class MessageCell: BaseCell {
var message: Message? {
    didSet {
        nameLabel.text = message?.friend?.name
        if let profileImageName = message?.friend?.profileImageName {
            profileImageView.image = UIImage(named: profileImageName)
            messageLabel.text = message?.text
        }
    }
}
let profileImageView: UIImageView = {
    let imageView = UIImageView()
    imageView.contentMode = .scaleAspectFill
    imageView.layer.cornerRadius = 34
    imageView.layer.masksToBounds = true

    return imageView
}()

let dividerLineView: UIView = {
    let view = UIView()
    view.backgroundColor = UIColor(white: 0.5, alpha: 0.5)
    return view
}()
    let nameLabel: UILabel = {
    let label = UILabel()
    label.text = "Mark Zuckerberg"
    label.font = UIFont.systemFont(ofSize: 18)
//    label.backgroundColor = UIColor.brown
    return label
}()

let messageLabel: UILabel = {
    let label = UILabel()
    label.text = "Your friends message and something else..."
    label.textColor = UIColor.darkGray
    label.font = UIFont.systemFont(ofSize: 14)
//    label.backgroundColor = UIColor.green
    return label
}()


let timelabel : UILabel = {
    let label = UILabel()
    label.text = "12:05 pm"
    label.font = UIFont.systemFont(ofSize: 16)
    label.textAlignment = .right
//    label.textColor = UIColor.white
//    label.backgroundColor = UIColor.black
    return label

}()

let hasReadImageView: UIImageView = {
    let imageView = UIImageView()
   imageView.contentMode = .scaleAspectFill
    imageView.layer.cornerRadius = 10
    imageView.layer.masksToBounds = true

    return imageView
}()
override func setupViews() {

    addSubview(profileImageView)
     addSubview(dividerLineView)
    profileImageView.image = UIImage(named: "zuckprofile")
    hasReadImageView.image = UIImage(named: "zuckprofile")
    setupContainerView()

    addConstraintsWithFormat( "H:|-12-[v0(68)]|", views: profileImageView)
    addConstraintsWithFormat( "V:[v0(68)]", views: profileImageView)
    addConstraint(NSLayoutConstraint(item: profileImageView, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1, constant: 0))
    addConstraintsWithFormat( "H:|-82-[v0]|", views: dividerLineView)
    addConstraintsWithFormat( "V:[v0(1)]|", views: dividerLineView)



}
func setupContainerView() {
    let containerView = UIView()
     addSubview(containerView)

    addConstraintsWithFormat("H:|-90-[v0]|", views: containerView)
    addConstraintsWithFormat(  "V:[v0(50)]", views: containerView)
    addConstraint(NSLayoutConstraint(item: containerView, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1, constant: 0))
    containerView.addSubview(nameLabel)
    containerView.addSubview(messageLabel)
    containerView.addSubview(timelabel)
    containerView.addSubview(hasReadImageView)
    containerView.addConstraintsWithFormat( "H:|[v0][v1(80)]-12-|", views: nameLabel, timelabel )
    containerView.addConstraintsWithFormat( "V:|[v0(26)][v1(24)]|", views: nameLabel,messageLabel )
    containerView.addConstraintsWithFormat( "H:|[v0]-8-[v1(20)]-12-|", views: messageLabel, hasReadImageView )
    containerView.addConstraintsWithFormat("V:[v0(20)]|", views: hasReadImageView)
    containerView.addConstraintsWithFormat( "V:|[v0(24)]", views: timelabel)
   addConstraint(NSLayoutConstraint(item: nameLabel, attribute: .centerY, relatedBy: .equal, toItem: timelabel, attribute: .centerY, multiplier: 1, constant: -1.4 ))


}

}



 extension UIView {
func addConstraintsWithFormat(_ format: String , views: UIView...) {
    var viewsDictionary = [String: UIView]()
    for (index, view) in views.enumerated() {
        let key = "v\(index)"
        viewsDictionary[key] = view
        view.translatesAutoresizingMaskIntoConstraints = false
    }
    addConstraints(NSLayoutConstraint.constraints(withVisualFormat: format, options: NSLayoutFormatOptions(), metrics: nil, views: viewsDictionary))
}
}



 class BaseCell : UICollectionViewCell {
let a = 5
override init(frame: CGRect) {
    super.init(frame: frame)
    setupViews()
    layer.masksToBounds = true
}
required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

func setupViews() {
    backgroundColor = UIColor.blue

}
 }

1 个答案:

答案 0 :(得分:1)

dequeueReusable用于内存效率目的。它在较低级别的工作方式我的朋友有关于https://medium.com/ios-seminar/why-we-use-dequeuereusablecellwithidentifier-ce7fd97cde8e

的详细解释

我希望它能回答你的问题。