Expandable UICollectionViewCell

问题描述 投票:3回答:3

我正在尝试编写一个可扩展的UICollectionViewCell。如果用户按下topbutton,则单元格应扩展到不同的高度并显示底层内容。

我的第一个实现具有自定义UICollectionViewCell,可以通过单击顶部按钮将其展开,但是collectionview也不会展开。 Atm。该单元格是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

基本上,所有内容都应设置动画。

屏幕快照显示了展开的而不是展开的单元格。希望能有所帮助!

opened and closed cell

谢谢!

ios swift uicollectionview uicollectionviewcell
3个回答
18
投票

如果您有多个单元格需要在集合视图单元格中触摸按钮时扩展到不同的高度,那么这里是代码。

我已经使用委托模式让控制器知道使用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
投票

不要直接更改单元格框架。实施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)])
}

0
投票

您可以使用标题显示非展开单元格。并且当您在其中有两个按钮或其他东西时,您可以在标头所属的那部分中将另一部分(扩展部分)作为一行插入。

优点-展开时,您可以使用许多提供的动画。

© www.soinside.com 2019 - 2024. All rights reserved.