动态缩小 UICollectionViewCell 的高度
Scaling down the height of a UICollectionViewCell dynamically
我正在使用 UICollectionViewDelegateFlowLayout
在 Collection 视图中显示动态高度的单元格。单元格的大小在 sizeForItemAt
.
中设置
目标:每个 Collection 视图单元格都有一个切换功能,可以将 dynamically-calculated 高度更改为 50%。这就是我 运行 遇到问题的地方。
在 sizeForItemAt
中,我正在获取动态高度。
var dynamicHeight = (header + content + footer)
return CGSize(width: self.view.frame.width, height: dynamicHeight)
当单元格上的按钮被按下时,我想将 sizeForItemAt
更新为如下内容:
return CGSize(width: self.view.frame.width, height: (dynamicHeight / 2))
如何在更新 sizeForItemAt
时更改 Collection 视图单元格的高度?
为了实现你想要的,你需要:
- 将单元格的状态存储在您的数据源中,以便
collectionView(_:layout:sizeForItemAt:)
函数可以使用索引路径和 轻松访问它
- 更改单元格的存储状态后,您需要调用集合视图的
reloadItems(at:)
函数,传递单元格的索引路径,以更新单元格的大小。
您可以在以下代码中查看示例:
class TestCollectionViewCell: UICollectionViewCell {
@IBOutlet weak var `switch`: UISwitch!
var action: ((Bool) -> Void)?
@IBAction func switchValueChanged(_ sender: UISwitch) {
action?(sender.isOn)
}
}
private let reuseIdentifier = "Cell"
class TestCollectionViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout {
struct Item {
let color: UIColor
var scaledDown: Bool
}
var items: [Item] = [
.init(color: .red, scaledDown: false),
.init(color: .green, scaledDown: false),
.init(color: .black, scaledDown: false),
.init(color: .orange, scaledDown: false),
.init(color: .yellow, scaledDown: false),
.init(color: .gray, scaledDown: false),
.init(color: .darkGray, scaledDown: false),
.init(color: .lightGray, scaledDown: false),
]
// MARK: UICollectionViewDataSource
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return items.count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! TestCollectionViewCell
let item = items[indexPath.item]
cell.switch.isOn = item.scaledDown
cell.backgroundColor = item.color
cell.action = { [weak self] (isOn: Bool) in
guard let self = self else { return }
self.items[indexPath.item].scaledDown = isOn
collectionView.reloadItems(at: [indexPath])
}
return cell
}
// MARK: - UICollectionViewDelegateFlowLayout
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let dynamicHeight: CGFloat = 200
if items[indexPath.item].scaledDown {
return CGSize(width: view.frame.width, height: (dynamicHeight / 2))
}
return CGSize(width: view.frame.width, height: dynamicHeight)
}
}
我正在使用 UICollectionViewDelegateFlowLayout
在 Collection 视图中显示动态高度的单元格。单元格的大小在 sizeForItemAt
.
目标:每个 Collection 视图单元格都有一个切换功能,可以将 dynamically-calculated 高度更改为 50%。这就是我 运行 遇到问题的地方。
在 sizeForItemAt
中,我正在获取动态高度。
var dynamicHeight = (header + content + footer)
return CGSize(width: self.view.frame.width, height: dynamicHeight)
当单元格上的按钮被按下时,我想将 sizeForItemAt
更新为如下内容:
return CGSize(width: self.view.frame.width, height: (dynamicHeight / 2))
如何在更新 sizeForItemAt
时更改 Collection 视图单元格的高度?
为了实现你想要的,你需要:
- 将单元格的状态存储在您的数据源中,以便
collectionView(_:layout:sizeForItemAt:)
函数可以使用索引路径和 轻松访问它
- 更改单元格的存储状态后,您需要调用集合视图的
reloadItems(at:)
函数,传递单元格的索引路径,以更新单元格的大小。
您可以在以下代码中查看示例:
class TestCollectionViewCell: UICollectionViewCell {
@IBOutlet weak var `switch`: UISwitch!
var action: ((Bool) -> Void)?
@IBAction func switchValueChanged(_ sender: UISwitch) {
action?(sender.isOn)
}
}
private let reuseIdentifier = "Cell"
class TestCollectionViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout {
struct Item {
let color: UIColor
var scaledDown: Bool
}
var items: [Item] = [
.init(color: .red, scaledDown: false),
.init(color: .green, scaledDown: false),
.init(color: .black, scaledDown: false),
.init(color: .orange, scaledDown: false),
.init(color: .yellow, scaledDown: false),
.init(color: .gray, scaledDown: false),
.init(color: .darkGray, scaledDown: false),
.init(color: .lightGray, scaledDown: false),
]
// MARK: UICollectionViewDataSource
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return items.count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! TestCollectionViewCell
let item = items[indexPath.item]
cell.switch.isOn = item.scaledDown
cell.backgroundColor = item.color
cell.action = { [weak self] (isOn: Bool) in
guard let self = self else { return }
self.items[indexPath.item].scaledDown = isOn
collectionView.reloadItems(at: [indexPath])
}
return cell
}
// MARK: - UICollectionViewDelegateFlowLayout
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let dynamicHeight: CGFloat = 200
if items[indexPath.item].scaledDown {
return CGSize(width: view.frame.width, height: (dynamicHeight / 2))
}
return CGSize(width: view.frame.width, height: dynamicHeight)
}
}