CollectionView - 每个部分的列数不同
Posted
技术标签:
【中文标题】CollectionView - 每个部分的列数不同【英文标题】:CollectionView - Different number of columns in each section 【发布时间】:2018-02-27 19:54:00 【问题描述】:我想要以下示例的集合视图。但无法弄清楚我该如何实现它。它在第一部分有 3 列,在第二部分有 2 列。
请大家帮忙!!!
【问题讨论】:
@branden 给出的示例可以按您的意愿工作。 【参考方案1】:覆盖 sizeForItemAtIndexPath
并执行以下操作:
- (NSInteger)itemPerRow:(UICollectionView *)collectionView forSection:(NSInteger)section
if (section == 0)
return 3;
return 2;
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
NSInteger itemsPerRow = [self itemsPerRow:collectionView forSection:indexPath.section];
CGFloat itemSpacing = ((UICollectionViewFlowLayout *)collectionViewLayout).minimumInteritemSpacing;
UIEdgeInsets insets = [self collectionView:collectionView layout:collectionViewLayout insetForSectionAtIndex:indexPath.section];
CGFloat width = (collectionView.bounds.size.width - (itemSpacing * (itemsPerRow - 1))) - (insets.left + insets.right);
width /= itemsPerRow;
return CGSizeMake(floor(width), floor(width));
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section
return UIEdgeInsetsMake(20.0, 20.0, 20.0, 20.0);
这会根据节中每行的项目数以及项目间的间距以及节的插图来计算每个项目的大小。它将“降低” itemWidth 以确保 X 数量的项目适合(由于舍入问题)。
【讨论】:
我认为您的 itemsPerRow 函数名称可能有错字【参考方案2】:这是一个完整的示例,显示基于部分的不同单元格大小。
import UIKit
class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout
let data: [ (headerTitle: String, items: [String]) ] = [
// Section 1
("Header 1", ["cell1", "cell2", "cell3", "cell4", "cell5", "cell6"]),
// Section 2
("Header 2", ["cell1", "cell2", "cell3", "cell4", "cell5", "cell6"])
]
// Create collectionView
lazy var collectionView: UICollectionView =
let cv: UICollectionView = UICollectionView(frame: .zero, collectionViewLayout: self.layout)
cv.contentInset.left = self.layout.minimumInteritemSpacing
cv.contentInset.right = self.layout.minimumInteritemSpacing
// register cell class
cv.register(Cell.self, forCellWithReuseIdentifier: Cell.id)
// register header
cv.register(Header.self, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: Header.id)
// set data source
cv.dataSource = self
cv.delegate = self
return cv
()
// Create collection view layout
lazy var layout: UICollectionViewFlowLayout =
let l: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
l.minimumInteritemSpacing = 5 // horizontal space between cells
l.minimumLineSpacing = 5 // vertical space between cells
return l
()
override func viewDidLoad()
super.viewDidLoad()
collectionView.backgroundColor = .white
view.addSubview(collectionView)
override func viewWillLayoutSubviews()
super.viewWillLayoutSubviews()
collectionView.frame = view.bounds
var threeRowsSize: CGSize
// Tell layout to put 3 items in a row
let width: CGFloat = collectionView.bounds.width/3 - (2 * layout.minimumInteritemSpacing)
return CGSize(width: width, height: width)
var twoRowsSize: CGSize
// Tell layout to put 2 items in a row
let width: CGFloat = collectionView.bounds.width/2 - (2 * layout.minimumInteritemSpacing)
return CGSize(width: width, height: width)
func numberOfSections(in collectionView: UICollectionView) -> Int
return data.count
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
return data[section].items.count
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: Cell.id, for: indexPath) as! Cell
cell.textLable.text = data[indexPath.section].items[indexPath.row]
return cell
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView
let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: Header.id, for: indexPath) as! Header
header.textLable.text = data[indexPath.section].headerTitle
return header
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize
return CGSize(width: collectionView.bounds.width, height: 50)
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
if indexPath.section == 0
return threeRowsSize//threeRowsSize
return twoRowsSize
// Cell
final class Cell: UICollectionViewCell
static let id: String = "cellId"
let textLable: UILabel = UILabel()
override init(frame: CGRect)
super.init(frame: frame)
textLable.textAlignment = .center
contentView.addSubview(textLable)
textLable.backgroundColor = .lightGray
required init?(coder aDecoder: NSCoder)
fatalError("init(coder:) has not been implemented")
override func layoutSubviews()
super.layoutSubviews()
textLable.frame = bounds
// Make it somewhat circular
textLable.layer.cornerRadius = textLable.bounds.width/3
textLable.layer.masksToBounds = true
// Header
final class Header: UICollectionReusableView
static let id: String = "headerId"
let textLable: UILabel = UILabel()
override init(frame: CGRect)
super.init(frame: frame)
backgroundColor = .cyan
textLable.textAlignment = .left
addSubview(textLable)
required init?(coder aDecoder: NSCoder)
fatalError("init(coder:) has not been implemented")
override func layoutSubviews()
super.layoutSubviews()
textLable.frame = bounds
【讨论】:
以上是关于CollectionView - 每个部分的列数不同的主要内容,如果未能解决你的问题,请参考以下文章