UICollectionViewCell 中的动态高度 noScrollable UICollectionView
Posted
技术标签:
【中文标题】UICollectionViewCell 中的动态高度 noScrollable UICollectionView【英文标题】:Dynamic height noScrolable UICollectionView in UICollectionViewCell 【发布时间】:2016-12-07 09:03:02 【问题描述】:我想在UICollectionViewCell
中添加一个dynamic height
nonScrollable
UICollectionView
。 (正如 Ash Furrow 所解释的,在 UICollectionViewCell 中添加静态高度 UICollectionView 很容易)
花了几个小时在网络上搜索后,我仍然不明白。
这就是我想要的
让我们调用: 主集合视图:ParentCollectionView CollectionView内部:ChildCollectionView
我想获取 ChildCollectionView 的高度,以便我可以在 side 中设置 ParentCollectionView 的单元格大小:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
let text = "I'm trying to get a label in a cell.."
let options = NSStringDrawingOptions.usesFontLeading.union(.usesLineFragmentOrigin)
let estimatedFrameForEventText = (text as NSString).boundingRect(with: CGSize.init(width: view.frame.width - 30, height: 1000), options: options, attributes: [NSFontAttributeName: UIFont.systemFont(ofSize: 12)], context: nil)
return CGSize.init(width: view.frame.width - 10, height: 320 + estimatedFrameForEventText.height + 60)
还想用这个改变 ChildCollectionView 的高度常数:
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: eventCellId, for: indexPath) as! EventCell
cell.eventText.text = "I'm trying to get a label in a cell.."
// height constraint of ChildCollectionView in ParentCell
cell.collectionViewHeightConstraint.constant = cell.collectionView.intrinsicContentSize.height
return cell
故意禁用 ChildCollectionView 的滚动以一起显示 ChildCollectionViewCells。
这就是我卡住的地方
我不能预先计算 ChildCollectionView 以将它们传递给 ParentCollectionView 代表
CollectionView 都使用UICollectionViewFlowLayout
我是 ios 开发新手。 任何帮助将不胜感激:)
【问题讨论】:
由于您的集合视图的内容不可滚动,您可能需要重新考虑另一个集合视图中的集合视图。如果你真的必须做类似的事情,你实际上可以在你的委托方法中检查 collectionView == ParentCollectionView 以确定你当前正在与哪个交互。 在计算 ChildCollectionView 的大小方面,您需要详细说明如何计算它,然后我才能帮助您。但通常你应该能够设置约束来设置你的内容是你的 ChildCollectionView 在这种情况下是相对于它所在的单元格 @BenOng ChildCollectionView 在 ParentCollectionViewCell 内部初始化,并且其 dataSource 和 delegate 为 self .....我使用 collectionView.intrinsicContentSize.height 计算它 @BenOng - 并且设置了数据......我必须通过在 ParentCollectionView sizeForItemAt 中计算的这个值,以便单元格具有正确的高度,包括 ChildCollectionView 在这种情况下,您可以为您的 ChildCollectionView 创建一个自定义委托方法来更新其单元格大小的 ParentCollectionView 【参考方案1】:这解决了我的问题
ParentCollectionViewController
var height: CGFloat!
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: eventCellId, for: indexPath) as! EventCell
cell.collectionViewHeightConstraint.constant = height!
return cell
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
let options = NSStringDrawingOptions.usesFontLeading.union(.usesLineFragmentOrigin)
var sizeOfChildCell: CGRect!
var widthOfCells: CGFloat! = 0.0
let cellPadding = 10
let widthOfChildCollectionview = view.frame.width - 120
for tag in tags
sizeOfChildCell = ("#\(tag)" as NSString).boundingRect(with: CGSize.init(width: widthOfChildCollectionview, height: 1000), options: options, attributes: [NSFontAttributeName: UIFont.systemFont(ofSize: 12)], context: nil)
widthOfCells = widthOfCells + sizeOfChildCell.width + cellPadding + 3.8
let numOfRows = ceil(widthOfCells / widthOfChildCollectionview)
height = numOfRows * 25
height = height + numOfRows * 3.8
return CGSize.init(width: view.frame.width - 10, height: 320 + height)
ParentCollectionViewCell
var childCollectionViewHeightConstraint: NSLayoutConstraint!
lazy var childCollectionView: UICollectionView =
let layout = UICollectionViewFlowLayout()
let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
cv.showsVerticalScrollIndicator = false
cv.isScrollEnabled = false
cv.contentInset = UIEdgeInsetsMake(0, 0, 0, 0)
cv.backgroundColor = .white
cv.dataSource = self
cv.delegate = self
return cv
()
override init(frame: CGRect)
super.init(frame: frame)
childCollectionViewHeightConstraint = NSLayoutConstraint(item: childCollectionView, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 96)
addConstraint(childCollectionViewHeightConstraint)
【讨论】:
【参考方案2】:仅用于此主题的未来搜索。我将 IGListKit 与一个单元格一起使用,该单元格包含一个包含我的标签的 UICollectionView。我的问题是 IGListKit 并没有很好地建立在 AutoLayout 原则上,因此为了防止集合视图单元格相互重叠,我必须在显示该部分之前手动计算该部分的高度。
我的想法是只添加每个标签的宽度(+ padding + minimumInterimSpace)并确定下一个标签何时取代集合视图宽度。
func calculateDimensions()
//This is how IGListKit forwards the width, could be replaced with collectionView.containerSize.width
let width = collectionContext!.containerSize.width
var lineWidth:CGFloat = 0.0
var lines = 0
for tag in data.arrTags
//Calculate bounds by using boundingRect
let size = TextSize.size(tag, font: Font.fontRegular(size: 13), height: 30)
//16= 8 padding-left + 8 padding-right
//5 = minimumInterimSpace
let itemWidth = 16 + size.width + 5
let tmpWidth = lineWidth + itemWidth
if tmpWidth > width
lines += 1
lineWidth = itemWidth
lineWidth += itemWidth
sectionHeight = CGFloat( lines * 30 + (lines * 5)) + 15
当 IGListKit 设置当前节的大小时调用此方法。所以我这样做了:
override func sizeForItem(at index: Int) -> CGSize
calculateDimensions()
let size = CGSize(width: collectionContext!.containerSize.width, height: sectionHeight)
return size
这将导致以下结果:
【讨论】:
以上是关于UICollectionViewCell 中的动态高度 noScrollable UICollectionView的主要内容,如果未能解决你的问题,请参考以下文章
为啥向 UICollectionViewCell 中的按钮添加操作效果不佳?