gpt4 book ai didi

ios - UICollectionView 的弹性 header

转载 作者:搜寻专家 更新时间:2023-10-31 22:42:10 24 4
gpt4 key购买 nike

我正在尝试使用 collectionview 部分标题创建一个可伸缩标题。有很多不同的方法可以做到这一点,但我只是在寻找最简单、最直接的方法,并明确说明要做什么。有没有人看过关于在 Swift 3 中执行此操作的简单指南,或者您能解释一下如何在此处完成此操作吗?

我觉得应该没有那么难。我想使用 UICollectionViewDelegateFlowLayoutScrollviewDelegate 因为我认为这是完成它的最简单方法。

当用户滚动时,我可以使用 scrollViewDidScroll 方法来控制页眉的高度吗?我将如何手动更改标题的高度?我知道在 Storyboard 上我可以在 UICollectionView header 大小设置中更改它,但我将如何在代码中调整它?

最佳答案

使用 Swift 5/iOS 12.3,您可以覆盖 shouldInvalidateLayout(forBoundsChange:)layoutAttributesForElements(in:) UICollectionViewFlowLayout 子类中的方法,以便在 UICollectionView 中创建可伸缩 header 。以下示例代码展示了如何实现这些方法:

CollectionViewController.swift

import UIKit

class CollectionViewController: UICollectionViewController {

let flowLayout = CustomFlowLayout()

override func viewDidLoad() {
super.viewDidLoad()

guard let collectionView = collectionView else { fatalError() }

collectionView.alwaysBounceVertical = true
collectionView.contentInsetAdjustmentBehavior = .always
collectionView.collectionViewLayout = flowLayout
collectionView.register(CollectionViewCell.self, forCellWithReuseIdentifier: "Cell")
collectionView.register(HeaderReusableView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "HeaderView")
}

override func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "HeaderView", for: indexPath) as! HeaderReusableView
return headerView
}

override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 20
}

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
return collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! CollectionViewCell
}

}

CustomFlowLayout.swift

import UIKit

class CustomFlowLayout: UICollectionViewFlowLayout {

let idealCellWidth: CGFloat = 100
let margin: CGFloat = 10

override init() {
super.init()

sectionInsetReference = .fromSafeArea
sectionInset = UIEdgeInsets(top: margin, left: margin, bottom: margin, right: margin)
headerReferenceSize = CGSize(width: 0, height: 80)
sectionHeadersPinToVisibleBounds = false
}

required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

override func prepare() {
super.prepare()

guard let collectionView = collectionView else { return }
let availableWidth = collectionView.frame.width - collectionView.safeAreaInsets.left - collectionView.safeAreaInsets.right - sectionInset.left - sectionInset.right
let idealNumberOfCells = (availableWidth + minimumInteritemSpacing) / (idealCellWidth + minimumInteritemSpacing)
let numberOfCells = idealNumberOfCells.rounded(.down)
let cellWidth = (availableWidth + minimumInteritemSpacing) / numberOfCells - minimumInteritemSpacing
itemSize = CGSize(width: cellWidth, height: cellWidth)
}

override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
return true
}

override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
guard let collectionView = collectionView else { return nil }
guard let rectAttributes = super.layoutAttributesForElements(in: rect) else { return nil }

let offsetY = collectionView.contentOffset.y + collectionView.safeAreaInsets.top
if let firstHeader = rectAttributes.first(where: { $0.representedElementKind == UICollectionView.elementKindSectionHeader && offsetY < 0}) {
let origin = CGPoint(x: firstHeader.frame.origin.x, y: firstHeader.frame.minY - offsetY.magnitude)
let size = CGSize(width: firstHeader.frame.width, height: max(0, headerReferenceSize.height + offsetY.magnitude))
firstHeader.frame = CGRect(origin: origin, size: size)
}

return rectAttributes
}

}

CollectionViewCell.swift

import UIKit

class CollectionViewCell: UICollectionViewCell {

override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = .cyan
}

required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

}

HeaderReusableView.swift

import UIKit

class HeaderReusableView: UICollectionReusableView {

override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = .magenta
}

required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

}

预期结果:

enter image description here

关于ios - UICollectionView 的弹性 header ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44446059/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com