请参阅以下每个项目的边界(边界间距)
使用集合视图Header我能够实现以下输出,但坚持如何将分隔符放在uicollection视图中。行内的单元格数也是动态的。
和最后一行不应该是底部分隔符 任何帮助都非常感谢..
对于实现以下布局,我只使用带有节标题的集合视图 我已经完成了以下输出
所有部分都已折叠
每个展开的部分只剩下分隔符部分 我无法弄清楚如何使用装饰视图实现相同的效果。
答案 0 :(得分:2)
你可以这样做,
以下是布局寻找的方式,
以下是用于此的代码,
<强> CollectionViewController 强>,
class ViewController: UICollectionViewController {
let images = ["Apple", "Banana", "Grapes", "Mango", "Orange", "Strawberry"]
init() {
let collectionViewLayout = DecoratedFlowLayout()
collectionViewLayout.register(HorizontalLineDecorationView.self,
forDecorationViewOfKind: HorizontalLineDecorationView.decorationViewKind)
collectionViewLayout.register(VerticalLineDecorationView.self,
forDecorationViewOfKind: VerticalLineDecorationView.decorationViewKind)
super.init(collectionViewLayout: collectionViewLayout)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
collectionView?.backgroundColor = UIColor.white
collectionView?.register(CollectionViewCell.self,
forCellWithReuseIdentifier: CollectionViewCell.CellIdentifier)
}
}
extension ViewController: UICollectionViewDelegateFlowLayout {
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return images.count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: CollectionViewCell.CellIdentifier,
for: indexPath) as! CollectionViewCell
let name = images[indexPath.item]
cell.imageView.image = UIImage(named: "\(name).png")
cell.label.text = name
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return .zero
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 10 + DecoratedFlowLayout.horizontalLineWidth
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 0
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width = (collectionView.bounds.size.width - DecoratedFlowLayout.verticalLineWidth) * 0.5
return CGSize(width: width,
height: width + 20)
}
}
<强> CollectionViewCell 强>,
class CollectionViewCell: UICollectionViewCell {
static let CellIdentifier = "CollectionViewCellIdentifier"
var imageView: UIImageView!
var label: UILabel!
override init(frame: CGRect) {
super.init(frame: frame)
createViews()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func createViews() {
imageView = UIImageView(frame: .zero)
imageView.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(imageView)
label = UILabel(frame: .zero)
label.font = UIFont.systemFont(ofSize: 20)
label.textAlignment = .center
label.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(label)
NSLayoutConstraint.activate([
imageView.topAnchor.constraint(equalTo: contentView.topAnchor),
imageView.leftAnchor.constraint(equalTo: contentView.leftAnchor),
imageView.rightAnchor.constraint(equalTo: contentView.rightAnchor),
label.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
label.leftAnchor.constraint(equalTo: contentView.leftAnchor),
label.rightAnchor.constraint(equalTo: contentView.rightAnchor),
label.topAnchor.constraint(equalTo: imageView.bottomAnchor),
label.heightAnchor.constraint(equalToConstant: 20)
])
}
}
<强> DecoratedFlowLayout 强>,
class DecoratedFlowLayout: UICollectionViewFlowLayout {
static let verticalLineWidth: CGFloat = 20
static let horizontalLineWidth: CGFloat = 20
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
minimumLineSpacing = 40 // should be equal to or greater than horizontalLineWidth
}
override init() {
super.init()
minimumLineSpacing = 40
}
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
guard let attributes = super.layoutAttributesForElements(in: rect) else {
return nil
}
var attributesCopy: [UICollectionViewLayoutAttributes] = []
for attribute in attributes {
attributesCopy += [attribute]
let indexPath = attribute.indexPath
if collectionView!.numberOfItems(inSection: indexPath.section) == 0 {
continue
}
let firstCell = IndexPath(item: 0,
section: indexPath.section)
let lastCell = IndexPath(item: collectionView!.numberOfItems(inSection: indexPath.section) - 1,
section: indexPath.section)
if let attributeForFirstItem = layoutAttributesForItem(at: firstCell),
let attributeForLastItem = layoutAttributesForItem(at: lastCell) {
let verticalLineDecorationView = UICollectionViewLayoutAttributes(forDecorationViewOfKind: VerticalLineDecorationView.decorationViewKind,
with: IndexPath(item: 0, section: indexPath.section))
let firstFrame = attributeForFirstItem.frame
let lastFrame = attributeForLastItem.frame
let frame = CGRect(x: collectionView!.bounds.midX - DecoratedFlowLayout.verticalLineWidth * 0.5,
y: firstFrame.minY,
width: DecoratedFlowLayout.verticalLineWidth,
height: lastFrame.maxY - firstFrame.minY)
verticalLineDecorationView.frame = frame
attributesCopy += [verticalLineDecorationView]
}
let contains = attributesCopy.contains { layoutAttribute in
layoutAttribute.indexPath == indexPath
&& layoutAttribute.representedElementKind == HorizontalLineDecorationView.decorationViewKind
}
let numberOfItemsInSection = collectionView!.numberOfItems(inSection: indexPath.section)
if indexPath.item % 2 == 0 && !contains && indexPath.item < numberOfItemsInSection - 2 {
let horizontalAttribute = UICollectionViewLayoutAttributes(forDecorationViewOfKind: HorizontalLineDecorationView.decorationViewKind,
with: indexPath)
let frame = CGRect(x: attribute.frame.minX,
y: attribute.frame.maxY + (minimumLineSpacing - DecoratedFlowLayout.horizontalLineWidth) * 0.5,
width: collectionView!.bounds.width,
height: DecoratedFlowLayout.horizontalLineWidth)
horizontalAttribute.frame = frame
attributesCopy += [horizontalAttribute]
}
}
return attributesCopy
}
override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
return true
}
}
装饰视图
class VerticalLineDecorationView: UICollectionReusableView {
static let decorationViewKind = "VerticalLineDecorationView"
let verticalInset: CGFloat = 40
let lineWidth: CGFloat = 4.0
let lineView = UIView()
override init(frame: CGRect) {
super.init(frame: frame)
lineView.backgroundColor = .black
addSubview(lineView)
lineView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
lineView.widthAnchor.constraint(equalToConstant: lineWidth),
lineView.topAnchor.constraint(equalTo: topAnchor, constant: verticalInset),
lineView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -verticalInset),
lineView.centerXAnchor.constraint(equalTo: centerXAnchor),
])
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
class HorizontalLineDecorationView: UICollectionReusableView {
let horizontalInset: CGFloat = 20
let lineWidth: CGFloat = 4.0
static let decorationViewKind = "HorizontalLineDecorationView"
let lineView = UIView()
override init(frame: CGRect) {
super.init(frame: frame)
lineView.backgroundColor = .black
addSubview(lineView)
lineView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
lineView.heightAnchor.constraint(equalToConstant: lineWidth),
lineView.leftAnchor.constraint(equalTo: leftAnchor, constant: horizontalInset),
lineView.rightAnchor.constraint(equalTo: rightAnchor, constant: -horizontalInset),
lineView.centerYAnchor.constraint(equalTo: centerYAnchor),
])
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
我希望你可以利用它并调整价值以满足你自己的需要。一些计算可能有意义改变到某种程度。但是,我希望你能够了解如何实现这一目标。
答案 1 :(得分:0)
如果列数始终为2,为什么不向单元格添加三个视图(分隔符),两个侧面和一个底部。对于右侧的单元格,隐藏最右侧的分隔符,反之亦然,左侧的单元格。 隐藏底部的分隔符以查看最后一行的单元格。 这有点像黑客,但实施起来要简单得多。
答案 2 :(得分:0)
自定义UICollectionviewcell
(我想你可能已经这样做了),
现在在自定义UICollectionviewcell
上放两个UIView -
UIView
,宽度为1或2(按照
必需)和高度等于单元格高度,给出黑色背景
颜色为UIView
。UIView
,具有1或2个点高度(根据需要),此时间宽度等于单元格宽度,为UIView
提供黑色背景颜色。
并调整空间。
我觉得这个技巧对你有用。