如何实现可以显示图像或作为输入属性提供的自定义 UIView 的 CollectionViewCell?
Posted
技术标签:
【中文标题】如何实现可以显示图像或作为输入属性提供的自定义 UIView 的 CollectionViewCell?【英文标题】:How to implement a CollectionViewCell that can either display an image or a custom UIView provided as input property? 【发布时间】:2017-01-18 20:36:50 【问题描述】:我有一个collectionView 单元格,它应该显示一个图像或一个生成为自定义UIView
的图标(比如说IconView
)。
目前,我通过将UIImageView
和IconView
作为子视图添加到容器视图来实现这一点。
当提供图像时,UIImageView
的图像属性会简单地更新。当提供新的IconView
时,它当前总是作为子视图添加到容器视图中。因此,在添加之前,首先检查IconView
是否已经添加,如果已经添加,则删除。
虽然这个实现有效,但它不是很优雅,而且似乎效率不高,因为当行数增加时会导致滚动问题。
是否有更好(更有效)的方法来为单个 CollectionViewCell 实现这一点?
class CustomCell: UICollectionViewCell
internal var image: UIImage?
didSet
self.imageView.image = image!
internal var iconView: IconView?
didSet
if !(self.iconContainerView.subviews.flatMap $0 as? IconView.isEmpty)
self.iconView!.removeFromSuperview()
self.iconView!.translatesAutoresizingMaskIntoConstraints = false
self.iconContainerView.addSubview(self.iconView!)
self.image = nil
fileprivate var imageView: UIImageView!
fileprivate var iconContainerView: UIView!
fileprivate var layoutConstraints = [NSLayoutConstraint]()
override init(frame: CGRect)
super.init(frame: frame)
// ContainerView
self.iconContainerView = UIView()
self.iconContainerView.translatesAutoresizingMaskIntoConstraints = false
self.contentView.addSubview(self.iconContainerView)
// ImageView
self.imageView = UIImageView()
self.imageView.translatesAutoresizingMaskIntoConstraints = false
self.iconContainerView.addSubview(self.imageView)
required init?(coder aDecoder: NSCoder)
fatalError("init(coder:) has not been implemented")
override func layoutSubviews()
super.layoutSubviews()
self.iconContainerView.leadingAnchor.constraint(equalTo: self.contentView.leadingAnchor).isActive = true
self.iconContainerView.widthAnchor.constraint(equalToConstant: 60).isActive = true
self.iconContainerView.heightAnchor.constraint(equalToConstant: 60).isActive = true
self.iconContainerView.centerYAnchor.constraint(equalTo: self.contentView.centerYAnchor).isActive = true
// Deactivate non-reusable constraints
_ = self.layoutConstraints.map $0.isActive = false
self.layoutConstraints = [NSLayoutConstraint]()
if let iconView = self.iconView
self.imageView.isHidden = true
self.layoutConstraints.append(iconView.centerYAnchor.constraint(equalTo: self.iconContainerView.centerYAnchor))
self.layoutConstraints.append(iconView.centerXAnchor.constraint(equalTo: self.iconContainerView.centerXAnchor))
self.layoutConstraints.append(iconView.heightAnchor.constraint(equalToConstant: 40))
self.layoutConstraints.append(iconView.widthAnchor.constraint(equalToConstant: 40))
else
self.imageView.isHidden = false
self.iconView?.isHidden = true
self.layoutConstraints.append(self.imageView.leadingAnchor.constraint(equalTo: self.iconContainerView.leadingAnchor))
self.layoutConstraints.append(self.imageView.trailingAnchor.constraint(equalTo: self.iconContainerView.trailingAnchor))
self.layoutConstraints.append(self.imageView.topAnchor.constraint(equalTo: self.iconContainerView.topAnchor))
self.layoutConstraints.append(self.imageView.bottomAnchor.constraint(equalTo: self.iconContainerView.bottomAnchor))
_ = self.layoutConstraints.map $0.isActive = true
【问题讨论】:
你不能使用两个不同的UICollectionViewCell
s有什么原因吗?
我使用的 collectionView 单元格相当长,图像/图标是唯一的布局差异。我不知道两个 UICollectionView 是否会提高性能,因为可以重用的单元格更少。此外,它需要在每个类和一个公共父类中重复所有约束。不是很有吸引力,但如果这是我会考虑的唯一方式。但是真的不能在单个单元格中显示自定义视图吗?
【参考方案1】:
设置时不要广告和删除 IconView。将两者添加到同一位置并更改 isHidden、alpha 或不透明度或bringSubviewToFront。这对主线程的密集程度要低得多。
【讨论】:
是的,但是每次渲染单元格时都应该显示一个全新的“IconView”。如果仅更新了 IconView 的属性,您的建议将是正确的(就像我已经为 UIImageView 所做的那样,在提供 IconView 时将被设置为隐藏)。理想情况下,IconView 也应该作为属性提供......有什么想法吗?以上是关于如何实现可以显示图像或作为输入属性提供的自定义 UIView 的 CollectionViewCell?的主要内容,如果未能解决你的问题,请参考以下文章
如何加载保存到我的标记 ID 的图像并显示在该特定标记的自定义信息窗口中?
Spring Boot - 如何通过实现 BeforeAllCallback 的自定义扩展类设置或覆盖 application.yml 中定义的属性?