可扩展的 UICollectionViewCell
Posted
技术标签:
【中文标题】可扩展的 UICollectionViewCell【英文标题】:Expandable UICollectionViewCell 【发布时间】:2016-11-26 22:50:01 【问题描述】:我正在尝试编写一个。 如果用户按下顶部按钮,单元格应展开到不同的高度并显示底层内容。
我的第一个实现有一个自定义 UICollectionViewCell,可以通过点击顶部按钮展开,但 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
基本上所有东西都应该是动画的。
屏幕截图显示了一个展开而不是展开的单元格。希望对您有所帮助!
谢谢!
【问题讨论】:
不知何故,APLExpandableCollectionView 可能有用... 【参考方案1】:如果在集合视图单元格内触摸按钮时需要将多个单元格扩展到不同的高度,那么,这里是代码。
我已经使用委托模式让控制器知道,使用 indexPath 触摸了哪个单元格的按钮。 创建cell时需要将cell的indexpath传递给cell。
当按钮被触摸时,单元格调用委托(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")
)
【讨论】:
你回答得最好!这就是我需要的! 嗨,我知道这已经很晚了,但这个答案真的很有帮助。但我有个问题。我一直让索引超出范围,因为我正在使用来自 api 的数据,并且在代码运行之前它没有加载,这与你已经在数据源数组中定义的不同。我该怎么做才能等待我的api加载所以我的数组不为空并且我没有超出范围?谢谢【参考方案2】:不要直接更改单元格框架。实现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)])
【讨论】:
【参考方案3】:您可以使用标题来显示非展开单元格。当你在其中两个按钮或其他东西时,你可以将其他部分(扩展部分)作为一行插入到标题所属的部分中。
好处 - 展开时您可以使用许多提供的动画。
【讨论】:
以上是关于可扩展的 UICollectionViewCell的主要内容,如果未能解决你的问题,请参考以下文章
我如何在 UITableViewCell 或 UICollectionViewCell 中为 UIButton 编写一个扩展,它只影响它所在的单元格?
Expandable UICollectionViewCell 重新定位问题