社区您好,我想实现一个 UICollectionviewCell,其大小为 110,每行最初有 3 个单元格
1.) 现在需要做一些修改,这样第一行应该有 3 个单元格,但第二行应该有 2 个单元格
2.) 第一个单元格大小应为 220,第二个单元格大小保持不变 110
3.) 在第三行中,它将具有与第一行相同的结构
4.) 但在第 4 行,第一个单元格大小将为 110,第二个单元格大小将为 220
它将以相同的结构重复以获取更多数据
我可以设计为每行 3 个单元格,但对于休息,我需要帮助
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
let width = (self.view.frame.size.width - 12 * 3) / 3
let height = width * 1.5
return CGSize(width: width, height: height)
}
一种方法是实施
sizeForItemAt
。
您可以使用模运算符 (
%
) 来确定该行应该有 2 个还是 3 个单元格,如下所示:
let itemsPerRow: CGFloat = indexPath.item % 5 < 3 ? 3 : 2
这将为您提供 3-2-3-2-3... 模式。
这是一个简单的例子...
我们将使用这个单元类 - 单个标签,在所有四个边上都约束 8 个点:
class SomeCell: UICollectionViewCell {
let theLabel: UILabel = {
let v = UILabel()
v.backgroundColor = UIColor(white: 0.9, alpha: 1.0)
v.textAlignment = .center
v.font = .systemFont(ofSize: 24.0, weight: .regular)
return v
}()
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
func commonInit() -> Void {
theLabel.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(theLabel)
let g = contentView.layoutMarginsGuide
NSLayoutConstraint.activate([
theLabel.topAnchor.constraint(equalTo: g.topAnchor, constant: 8.0),
theLabel.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 8.0),
theLabel.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -8.0),
theLabel.bottomAnchor.constraint(equalTo: g.bottomAnchor, constant: -8.0),
])
}
}
然后这个视图控制器类:
class ThreeTwoViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let fl = UICollectionViewFlowLayout()
fl.scrollDirection = .vertical
fl.minimumLineSpacing = 12.0
fl.minimumInteritemSpacing = 0.0
fl.sectionInset = .init(top: 8.0, left: 8.0, bottom: 8.0, right: 8.0)
let cv = UICollectionView(frame: .zero, collectionViewLayout: fl)
cv.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(cv)
let g = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
cv.topAnchor.constraint(equalTo: g.topAnchor, constant: 0.0),
cv.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 0.0),
cv.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: 0.0),
cv.bottomAnchor.constraint(equalTo: g.bottomAnchor, constant: 0.0),
])
cv.register(SomeCell.self, forCellWithReuseIdentifier: "c")
cv.dataSource = self
cv.delegate = self
cv.backgroundColor = .systemYellow
}
}
extension ThreeTwoViewController: UICollectionViewDataSource, UICollectionViewDelegateFlowLayout, UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 30
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "c", for: indexPath) as! SomeCell
cell.backgroundColor = .systemBlue
cell.theLabel.text = "\(indexPath.item)"
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let itemsPerRow: CGFloat = indexPath.item % 5 < 3 ? 3 : 2
var sidePadding: CGFloat = 0.0
var itemPadding: CGFloat = 12.0
if let fl = collectionView.collectionViewLayout as? UICollectionViewFlowLayout {
sidePadding = fl.sectionInset.left + fl.sectionInset.right
if itemPadding < fl.minimumInteritemSpacing {
itemPadding = fl.minimumInteritemSpacing
}
}
let paddingSpace: CGFloat = itemPadding * (itemsPerRow - 1) + sidePadding
let availableWidth: CGFloat = collectionView.frame.width - paddingSpace
let widthPerItem: CGFloat = availableWidth / itemsPerRow
let cellHeight: CGFloat = widthPerItem * 1.5
return CGSize(width: widthPerItem, height: cellHeight)
}
}
这给了我们这个输出: