2016-11-26 33 views
1

我想編程一個可展開的UICollectionViewCell。 如果用戶按下頂部按鈕,單元格應展開到不同的高度並顯示底層內容。展開式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 

Basicly一切都應該是動畫。

該屏幕截圖顯示了一個展開和未展開的單元格。希望有所幫助!

opened and closed cell

謝謝!

+0

不知何故,[APLExpandableCollectionView](https://github.com/apploft/APLExpandableCollectionView)可能是有用的... –

回答

9

如果您有需要擴大到按鈕時集合視圖內觸及不同高度單元更細胞,那麼,這裏是代碼。

我已經使用委託模式讓控制器知道使用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") 
     }) 
    } 
} 
+0

你回答最好!這是我需要的! – Zhanserik

+0

這幫了我 - 謝謝你分享這個 –

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)]) 
}