我有一个UICollectionView
,我想动态地应用两个不同的布局。
UICollectionViewFlowLayout
:具有相同大小的单元格和圆形图像的布局。
var flowLayout: UICollectionViewFlowLayout {
let flowLayout = UICollectionViewFlowLayout()
flowLayout.itemSize = CGSize(width: UIScreen.main.bounds.width/3, height: 140)
flowLayout.sectionInset = UIEdgeInsetsMake(0, 0, 0, 0)
flowLayout.scrollDirection = UICollectionViewScrollDirection.vertical
flowLayout.minimumInteritemSpacing = 0.0
return flowLayout
}
Pintrest Layout
:
https://www.raywenderlich.com/392-uicollectionview-custom-layout-tutorial-pinterest
例如:当用户单击“配置文件”按钮时,将显示FlowLayout并以圆形显示单元格。当用户单击“图片”按钮时,将应用最细布局,单元格将以具有动态高度的矩形形状显示。
最初,CollectionView具有1.flowLayout,它看起来很完美。但是,当我单击“图片”按钮时,Pintrest布局与先前的布局混淆了,如上图所示。
以下是更改布局的代码。
if isGrid {
let horizontal = flowLayout
recentCollectionView.setCollectionViewLayout(horizontal, animated: true)
recentCollectionView.reloadData()
}
else {
let horizontal = PinterestLayout()
horizontal.delegate = self
recentCollectionView.setCollectionViewLayout(horizontal, animated: true)
recentCollectionView.reloadData()
}
ViewHiarchy:
我有一个包含标题和一个底部单元格的主Collection-view.cell包含我要对其应用多个布局的其他Collection-view。每个布局都有两个不同的单元格。我希望底部单元格的大小等于content集合视图的内容大小,以便用户可以垂直滚动整个主集合视图。
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
var cell : UICollectionViewCell!
switch isGrid {
case true:
cell = collectionView.dequeueReusableCell(withReuseIdentifier: "SearchProfileCell", for: indexPath)
if let annotateCell = cell as? SearchProfileCell {
annotateCell.photo = photos[indexPath.item]
}
case false:
cell = collectionView.dequeueReusableCell(withReuseIdentifier: "AnnotatedPhotoCell", for: indexPath)
if let annotateCell = cell as? AnnotatedPhotoCell {
annotateCell.cellwidth = collectionView.contentSize.width/3
annotateCell.photo = photos[indexPath.item]
}
}
cell.contentView.layer.cornerRadius = 0
return cell
}
个人资料和图片按钮操作的代码。
@IBAction func pictureClick(sender:UIButton) {
isGrid = false
self.searchCollectionView.reloadData()
}
@IBAction func profilClick(sender:UIButton) {
isGrid = true
self.searchCollectionView.reloadData()
}
答案 0 :(得分:2)
我认为问题不在布局内部,而可能在cellForItemAt内部。如果两种布局都使用不同的单元格,则不要在cellForItemAt方法中比较布尔值。您应该比较布局类的类型 像下面的代码:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if collectionView.collectionViewLayout.isKind(of: PinterestLayout.self) {
// return cell for PinterestLayout
guard let annotateCell = collectionView.dequeueReusableCell(withReuseIdentifier: "SearchProfileCell", for: indexPath) as? SearchProfileCell else {
fatalError("SearchProfileCell Not Found")
}
annotateCell.photo = photos[indexPath.item]
return annotateCell
} else {
// return cell for flowLayout
guard let annotateCell = collectionView.dequeueReusableCell(withReuseIdentifier: "AnnotatedPhotoCell", for: indexPath) as? AnnotatedPhotoCell else {
fatalError("AnnotatedPhotoCell Not Found")
}
annotateCell.cellwidth = collectionView.contentSize.width/3
annotateCell.photo = photos[indexPath.item]
return annotateCell
}
}
还需要更新布局更改操作方法,例如:
@IBAction func pictureClick(sender:UIButton) {
isGrid = false
self.collectionView?.collectionViewLayout.invalidateLayout()
self.collectionView?.setCollectionViewLayout(PinterestLayout(),
animated: false, completion: { [weak self] (complite) in
guard let strongSelf = self else {
return
}
strongSelf.searchCollectionView?.reloadData()
})
}
@IBAction func profilClick(sender:UIButton) {
isGrid = true
self.collectionView?.collectionViewLayout.invalidateLayout()
self.collectionView?.setCollectionViewLayout(flowLayout,
animated: false, completion: { [weak self] (complite) in
guard let strongSelf = self else {
return
}
strongSelf.searchCollectionView?.reloadData()
})
}
答案 1 :(得分:1)
即使使用pintrestLayout可以获得相同的结果,为什么还要使用两种不同的布局。 https://www.raywenderlich.com/392-uicollectionview-custom-layout-tutorial-pinterest。
仔细检查pintrestLayout,它具有动态高度的代表。
let photoHeight = delegate.collectionView(collectionView, heightForPhotoAtIndexPath: indexPath)
如果您在此处返回静态高度,则您的pintrest布局将成为GridLayout(您的第一个布局)。
如果希望将pintrest布局用作这两种布局,则需要在pintrest布局中声明相同的布尔值(isGrid)。并使用此布尔值返回UICollectionViewLayoutAttributes
更重要的raywenderlich pintrest布局使用缓存来存储布局属性。您必须在应用其他布局之前删除缓存对象。
在本教程中,检查栅格,列表和线性布局的布局。 https://benoitpasquier.com/optimise-uicollectionview-swift/
布局所需的内容。
var isGrid : Bool = true {
didSet {
if isGrid != oldValue {
cache.removeAll()
self.invalidateLayout()
}
}
}