我对
中的事实感到非常困惑 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
}
}
答案 0 :(得分:1)
dequeueReusable用于内存效率目的。它在较低级别的工作方式我的朋友有关于https://medium.com/ios-seminar/why-we-use-dequeuereusablecellwithidentifier-ce7fd97cde8e
的详细解释我希望它能回答你的问题。