我正在尝试编写可扩展的UICollectionViewCell。 如果用户按下顶部按钮,则单元格应扩展到不同的高度并显示基础内容。
我的第一个实现具有自定义UICollectionViewCell,可以通过单击顶部按钮进行扩展,但collectionview也不会扩展。自动取款机。单元格是collectionview中的最后一个单元格,只需向下滑动,就可以看到展开的内容。如果你停止触摸,滚动视图会跳起来,看不到扩展单元格。
这是我的代码:
import Foundation
import UIKit
class ExpandableCell: UICollectionViewCell {
@IBOutlet weak var topButton: IconButton!
public var expanded : Bool = false
private var expandedHeight : CGFloat = 200
private var notExpandedHeight : CGFloat = 50
@IBAction func topButtonTouched(_ sender: AnyObject) {
if (expanded == true) {
self.deExpand()
} else {
self.expand()
}
}
public func expand() {
UIView.animate(withDuration: 0.8, delay: 0.0, usingSpringWithDamping: 0.9, initialSpringVelocity: 0.9, options: UIViewAnimationOptions.curveEaseInOut, animations: {
self.frame = CGRect(x: self.frame.origin.x, y: self.frame.origin.y, width: self.frame.size.width, height: self.expandedHeight)
}, completion: { success in
self.expanded = true
})
}
public func deExpand() {
UIView.animate(withDuration: 0.8, delay: 0.0, usingSpringWithDamping: 0.9, initialSpringVelocity: 0.9, options: UIViewAnimationOptions.curveEaseInOut, animations: {
self.frame = CGRect(x: self.frame.origin.x, y: self.frame.origin.y, width: self.frame.size.width, height: self.notExpandedHeight)
}, completion: { success in
self.expanded = false
})
}
}
我也无法正确实现以下方法,因为我还没有直接引用该单元格:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
基本上一切都应该是动画的。
屏幕截图显示了一个展开但未展开的单元格。希望有所帮助!
谢谢!
答案 0 :(得分:17)
如果在集合视图单元格内触摸按钮时,有多个单元格需要扩展到不同的高度,那么这里是代码。
我已经使用委托模式让控制器知道,使用indexPath触摸了哪个单元格的按钮。 创建单元格时,需要将单元格的索引路径传递给单元格。
当触摸按钮时,单元格调用委托(ViewController),相应地更新isExpandedArray并重新加载特定单元格。
CollectionViewCell
protocol ExpandedCellDelegate:NSObjectProtocol{
func topButtonTouched(indexPath:IndexPath)
}
class ExpandableCell: UICollectionViewCell {
@IBOutlet weak var topButton: UIButton!
weak var delegate:ExpandedCellDelegate?
public var indexPath:IndexPath!
@IBAction func topButtonTouched(_ sender: UIButton) {
if let delegate = self.delegate{
delegate.topButtonTouched(indexPath: indexPath)
}
}
}
查看控制器类
class ViewController: UIViewController {
@IBOutlet weak var collectionView: UICollectionView!
var expandedCellIdentifier = "ExpandableCell"
var cellWidth:CGFloat{
return collectionView.frame.size.width
}
var expandedHeight : CGFloat = 200
var notExpandedHeight : CGFloat = 50
var dataSource = ["data0","data1","data2","data3","data4"]
var isExpanded = [Bool]()
override func viewDidLoad() {
super.viewDidLoad()
isExpanded = Array(repeating: false, count: dataSource.count)
}
}
extension ViewController:UICollectionViewDataSource{
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return dataSource.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: expandedCellIdentifier, for: indexPath) as! ExpandableCell
cell.indexPath = indexPath
cell.delegate = self
//configure Cell
return cell
}
}
extension ViewController:UICollectionViewDelegateFlowLayout{
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
if isExpanded[indexPath.row] == true{
return CGSize(width: cellWidth, height: expandedHeight)
}else{
return CGSize(width: cellWidth, height: notExpandedHeight)
}
}
}
extension ViewController:ExpandedCellDelegate{
func topButtonTouched(indexPath: IndexPath) {
isExpanded[indexPath.row] = !isExpanded[indexPath.row]
UIView.animate(withDuration: 0.8, delay: 0.0, usingSpringWithDamping: 0.9, initialSpringVelocity: 0.9, options: UIViewAnimationOptions.curveEaseInOut, animations: {
self.collectionView.reloadItems(at: [indexPath])
}, completion: { success in
print("success")
})
}
}
答案 1 :(得分:1)
不要直接更改单元格框架。实施func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
并在那里处理高度。
假设您在collectionView中有一个单元格,上面有一个顶部按钮:
let expanded = false
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize{
if expanded{
// what is the size of the expanded cell?
return collectionView.frame.size
}else{
// what is the size of the collapsed cell?
return CGSizeZero
}
}
@IBAction func didTouchUpInsideTopButton(sender: AnyObject){
// top button tap handler
self.expanded = !self.expanded
// this call will reload the cell and make it redraw (animated) Since the expanded flag changed, the sizeForItemAt call above will return a different size and animate the size change
self.collectionView.reloadItemsAtIndexPaths([NSIndexPath(forRow: 0, inSection: 0)])
}
答案 2 :(得分:0)
您可以使用标题显示非展开单元格。当您在其中有两个按钮或其他东西时,您可以在标题所属的那部分中将另一部分(扩展部分)作为一行插入。
优点-展开时,您可以使用许多提供的动画。