UICollectionView多个部分和标题
我正在努力尝试在我的集合视图中做每个部分的标题的多个部分。 我不知道Obj-C,我已经find了大量的教程,但一直没能弄清楚如何将其转换成Swift。
我的所有数据都是静态的,所以我需要的是某种数组或字典,我可以用它来创build多个部分。 我已经有一个集合视图,有1个部分可以工作,所以如果你有任何洞察力或代码多个部分会有所帮助。
我知道如何设置多个部分使用
func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int { return sectionData.count }
我认为我需要帮助的主要事情是实现这个function
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { }
并设置数据!
UICollectionView和UITableView几乎完全一样,所以如果你知道如何在Swift中的UITableView中做多个部分,你的帮助也是赞赏
cellForItemAtIndexPath
函数处理每个部分的单元格填充,它不处理部分或补充cellForItemAtIndexPath
,因此不是创build节标题时需要帮助的主要内容。
你需要实现的方法是viewForSupplementaryElementOfKind
。 其签名是:
func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {}
假设您的collectionView对于1个部分正确工作(您已经正确填写了cellForItemAtIndexPath的正文,并且您的sectionData数组正确地反映了您要显示的部分的数量),那么您应该能够使用以下指针实现部分标题:
除了单元格, UICollectionView
还支持“补充”视图对象,通常用于页眉或页脚。 这些补充视图与UICollectionViewCell
对象非常相似。 与cellForItemAtIndexPath
处理单元格的方式相同, viewForSupplementaryElementOfKind
函数处理补充视图。
要实现它,你需要先准备好你的ViewController。 首先编辑您的布局对象,以反映适当的标题大小,每个标题将遵守:
let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout() layout.headerReferenceSize = CGSize(width: self.view.frame.size.width, height: 30)
注:我正在使用UICollectionViewFlowLayout
接下来,如果你还没有这样做,创build一个SectionHeader类来定义每个节标题对象,这样你就可以用你的collectionView对象来注册这个类:
collectionView!.registerClass(SectionHeaderView.self, forSupplementaryViewOfKind:UICollectionElementKindSectionHeader, withReuseIdentifier: "SectionHeaderView");
在这里,传入的第一个和第三个参数与UICollectionViewCell类注册相同,此方法中的第一个参数是对您创build的部分头类的引用。 第三个是补充视图的重用标识符。
第二个参数是Supplementary Views特有的,它设置了SupplementaryViewtypes,在这个例子中是一个头文件,UICollectionViewFlowLayout类提供的常量stringUICollectionElementKindSectionHeader
用于它。 如果您注意到viewForSupplementaryElementOfKind
上的参数,则稍后将以kind: String
参数的kind: String
传入kind: String
参数。
用与你的cellForItemAtIndexPath函数相同的方法填充viewForSupplementaryElementOfKind
的主体 – 使用dequeueReusableSupplementaryViewOfKind
方法创build一个SectionHeader对象,然后根据需要设置任何属性(标签,颜色等),最后返回标题对象。
希望这可以帮助!!
参考点:
这是为我工作的代码
创build标题单元格。 为了做到这一点,我创build了一个自定义的单元格类和一个笔尖做graphics编辑器中的单元格的自定义
在viewDidLoad中添加以下内容
self.collectionView?.registerNib(UINib(nibName: "KlosetCollectionHeaderViewCell", bundle: nil), forSupplementaryViewOfKind:UICollectionElementKindSectionHeader, withReuseIdentifier: "HeaderCell")
然后你添加委托function
override func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> KlosetCollectionHeaderViewCell { let headerCell = collectionView.dequeueReusableSupplementaryViewOfKind(kind, withReuseIdentifier: "HeaderCell", forIndexPath: indexPath) as? KlosetCollectionHeaderViewCell return headerCell! }
这将把HeaderCell放在PFCollectionView的SectionView中把你添加到xib文件的单元格中显示的控件以及出口和动作
在创build和注册自定义页眉(和/或页脚)后,您可以轻松地为不同部分指定不同的页眉(或页脚)。 这是一个例子:
override func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView { switch kind { case UICollectionElementKindSectionHeader: let section = indexPath.section switch section { case 0: let userHeader = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: homeHeaderReuseIdentifier, for: indexPath) as! UserHeader return userHeader default: let postHeader = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: sectionSpacingHeaderReuseIdentifier, for: indexPath) as! PostHeader return postHeader } case UICollectionElementKindSectionFooter: let userFooter = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: homeFooterReuseIdentifier, for: indexPath) as! UserFooter return userFooter default: return UICollectionReusableView() } }
请务必指定正确的部分数量:
override func numberOfSections(in collectionView: UICollectionView) -> Int { return 2 }
为Swift-3工作的解决scheme
i)创build自定义单元格&&相应的xib
class SectionHeaderView: UICollectionViewCell { static let kReuseIdentifier = "SectionHeaderView" @IBOutlet weak var invitationsSectionHeader: UILabel! @IBOutlet weak var numberOfPerson: UILabel! }
ii)为HeaderView注册自定义集合视图单元格
self.collectionView.register(UINib(nibName: SectionHeaderView.kReuseIdentifier, bundle: nil), forSupplementaryViewOfKind:UICollectionElementKindSectionHeader, withReuseIdentifier: SectionHeaderView.kReuseIdentifier)
iii)调用委托function呈现自定义标题视图。
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView { switch kind { case UICollectionElementKindSectionHeader: let headerView: SectionHeaderView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: SectionHeaderView.kReuseIdentifier, for: indexPath) as! SectionHeaderView return headerView default: return UICollectionReusableView() } }
iv)提到自定义页眉视图的高度
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize { return CGSize(width:collectionView.frame.size.width, height:30) }
定义你的UICollectionViewCell,这将是你的头类视图的类UICollectionElementKindSectionHeader – 在我的情况下,我有两个头 – OfferHeaderCell和APRHeaderCell定义如下:
verticalCollectionView.register(UINib(nibName: "OfferHeaderCell", bundle: nil), forSupplementaryViewOfKind:UICollectionElementKindSectionHeader, withReuseIdentifier: "OfferHeaderCell") verticalCollectionView.register(UINib(nibName: "APRHeaderCell", bundle: nil), forSupplementaryViewOfKind:UICollectionElementKindSectionHeader, withReuseIdentifier: "APRHeaderCell")
继续并为每个部分返回一个头部,然后在此UICollectionViewDelegateFlowLayout函数中将部分头部的大小设置为零
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize { if(section==0) { return CGSize.zero } else if (section==1) { return CGSize(width:collectionView.frame.size.width, height:133) } else { return CGSize(width:collectionView.frame.size.width, height:100) } }
重要的是为两个不同的部分定义viewForSupplementaryElementOfKind,如下所示:
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView { var reusableview = UICollectionReusableView() if (kind == UICollectionElementKindSectionHeader) { let section = indexPath.section switch (section) { case 1: let firstheader: OfferHeaderCell = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "OfferHeaderCell", for: indexPath) as! OfferHeaderCell reusableview = firstheader case 2: let secondHeader: APRHeaderCell = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "APRHeaderCell", for: indexPath) as! APRHeaderCell reusableview = secondHeader default: return reusableview } } return reusableview }
最后,数据源,
func numberOfSections(in collectionView: UICollectionView) -> Int { return 3 } func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { if (section==2) { return 2 } return 0 } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = verticalCollectionView.dequeueReusableCell(withReuseIdentifier: "ReviseOfferCell", for: indexPath) cell.backgroundColor = UIColor.white return cell }
注意:不要忘记添加UICollectionFlowLayout,如下所示:
// MARK:UICollectionViewDelegateFlowLayout
extension MakeAnOfferController: UICollectionViewDelegateFlowLayout { func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { if indexPath.item == 0 { return CGSize(width: self.view.frame.size.width, height: 626.0) } return CGSize() } func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize { if(section==0) { return CGSize.zero } else if (section==1) { return CGSize(width:collectionView.frame.size.width, height:133) } else { return CGSize(width:collectionView.frame.size.width, height:100) } } }