【发布时间】:2020-12-12 16:43:04
【问题描述】:
我目前正在尝试在我的集合视图的每个单元格之间实现自定义分隔线视图。我在网上找到了这个答案,它在行间距中添加了自定义视图 (link)。
private let separatorDecorationView = "separator"
final class CustomFlowLayout: UICollectionViewFlowLayout {
override init() {
super.init()
register(SeparatorView.self,
forDecorationViewOfKind: separatorDecorationView)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
let layoutAttributes = super.layoutAttributesForElements(in: rect) ?? []
let lineWidth = self.minimumLineSpacing
var decorationAttributes: [UICollectionViewLayoutAttributes] = []
// skip first cell
for layoutAttribute in layoutAttributes where layoutAttribute.indexPath.item > 0 {
let separatorAttribute = UICollectionViewLayoutAttributes(forDecorationViewOfKind: separatorDecorationView,
with: layoutAttribute.indexPath)
let cellFrame = layoutAttribute.frame
separatorAttribute.frame = CGRect(x: cellFrame.origin.x,
y: cellFrame.origin.y - lineWidth,
width: cellFrame.size.width,
height: lineWidth)
separatorAttribute.zIndex = Int.max
decorationAttributes.append(separatorAttribute)
}
return layoutAttributes + decorationAttributes
}
}
private final class SeparatorView: UICollectionReusableView {
private let imageView: UIImageView = {
let iv = UIImageView(image: UIImage(named: "cell-divider"))
iv.contentMode = .scaleAspectFit
iv.translatesAutoresizingMaskIntoConstraints = false
return iv
}()
override init(frame: CGRect) {
super.init(frame: frame)
addSubview(imageView)
imageView.leftAnchor.constraint(equalTo: leftAnchor).isActive = true
imageView.rightAnchor.constraint(equalTo: rightAnchor).isActive = true
imageView.topAnchor.constraint(equalTo: topAnchor).isActive = true
imageView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func apply(_ layoutAttributes: UICollectionViewLayoutAttributes) {
self.frame = layoutAttributes.frame
}
}
这个解决方案确实有效,我可以看到分隔线。但是,当用户单击其中一个单元格时,就会出现问题。我想要的行为是让单元格在单击单元格时展开以显示更多详细信息。我实现这一点的方式是跟踪选择了哪些indexPaths,如果在sizeForItemAt 中选择了它们,则返回更大的尺寸。在didSelectItemAt 中,我重新加载了集合视图。这种方法在我使用普通的UICollectionViewFlowLayout 时有效,但是当我尝试使用我的自定义流布局(上图)时,我得到了以下崩溃:
no UICollectionViewLayoutAttributes instance for -layoutAttributesForDecorationViewOfKind: separator at path <NSIndexPath: 0xf75c5b66b8a0a8ab> {length = 2, path = 0 - 6}
我尝试查找解决方案,发现这两个堆栈溢出 here 和 here 但我尝试的答案似乎都不起作用。
我试过了:
- 当我重新加载集合视图时布局无效。
- 实现一个缓存,当我在自定义布局中覆盖
layoutAttributesForItem时,我会从该缓存返回。
在这一点上,任何帮助将不胜感激!
【问题讨论】:
标签: swift uicollectionviewlayout uicollectionviewflowlayout