题: 如何使UITableViewCell高度动态变化UICollectionViewCell?
查看层次结构:
UIViewController UITableView UITableViewCell UICollectionView UICollectionViewCell1 Label 1 UICollectionViewCell2 Label 2 UICollectionViewCell3 Label 3 [So on]
UIViewController
UITableView UITableViewCell UICollectionView UICollectionViewCell1 Label 1 UICollectionViewCell2 Label 2 UICollectionViewCell3 Label 3 [So on]
UITableView
UITableViewCell UICollectionView UICollectionViewCell1 Label 1 UICollectionViewCell2 Label 2 UICollectionViewCell3 Label 3 [So on]
UITableViewCell
UICollectionView UICollectionViewCell1 Label 1 UICollectionViewCell2 Label 2 UICollectionViewCell3 Label 3 [So on]
UICollectionView
UICollectionViewCell1 Label 1 UICollectionViewCell2 Label 2 UICollectionViewCell3 Label 3 [So on]
UICollectionViewCell1
Label 1
UICollectionViewCell2
Label 2
UICollectionViewCell3
Label 3
[So on]
Here Label1, Label2, label 3 are have dynamic height and numberOfRows in UICollectionView is also dynamic. I need Height of UITableViewCell according to the UICollectionViewCell.
Label1
Label2
label 3
numberOfRows
UICollectionViewCell
脚步: 绑定委托和数据源
将UItableView委托和数据源与绑定UIViewController。
将UICollectionView委托和数据源与UItableViewCell这里绑定TblCell。
在 UIViewController
class CollectionVC: UIViewController, UITableViewDataSource, UITableViewDelegate { : : func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return UITableViewAutomaticDimension // For tableCell Dynamic Height } func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat { return 200 // For tableCell Estimated Height } // Above two delegates must be necessary or you can use property for same. func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 1 // returning 1, as per current single cell } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "TblCell") as! TblCell return cell } }
TblCell
class TblCell: UITableViewCell , UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout{ @IBOutlet var colViewObj: UICollectionView! // Array for Label var arrData = ["Hello", "How re you?", "rock the world", "Nice to meet you.", "Hey! It is awsome."] override func awakeFromNib() { super.awakeFromNib() // Initialization code self.colViewObj.isScrollEnabled = false } override func setSelected(_ selected: Bool, animated: Bool) { super.setSelected(selected, animated: animated) // Configure the view for the selected state } func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { // Get width of Label As per String characters. let aWidth : CGFloat = arrData[indexPath.row].width(withConstraintedHeight: 40, font: UIFont.systemFont(ofSize: 17.0)) return CGSize(width: aWidth + 40 , height: 40) } // THIS IS THE MOST IMPORTANT METHOD // // This method tells the auto layout // You cannot calculate the collectionView content size in any other place, // because you run into race condition issues. override func systemLayoutSizeFitting(_ targetSize: CGSize, withHorizontalFittingPriority horizontalFittingPriority: UILayoutPriority, verticalFittingPriority: UILayoutPriority) -> CGSize { // If the cell's size has to be exactly the content // Size of the collection View, just return the // collectionViewLayout's collectionViewContentSize. self.colViewObj.frame = CGRect(x: 0, y: 0, width: targetSize.width, height: 600) self.colViewObj.layoutIfNeeded() // It Tells what size is required for the CollectionView return self.colViewObj.collectionViewLayout.collectionViewContentSize } func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return arrData.count } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ColViewCell", for: indexPath) as! ColViewCell cell.lblTitle.text = arrData[indexPath.item] cell.lblTitle.layer.borderColor = UIColor.black.cgColor cell.lblTitle.layer.borderWidth = 1.0 return cell } } extension String { func width(withConstraintedHeight height: CGFloat, font: UIFont) -> CGFloat { let constraintRect = CGSize(width: .greatestFiniteMagnitude, height: height) let boundingBox = self.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [NSFontAttributeName: font], context: nil) return ceil(boundingBox.width) } }
with UICollectionViewDelegateFlowLayout
without UICollectionViewDelegateFlowLayout
UICollectionView inside a UITableViewCell – dynamic height?
TableViewCell height is based on collectionview content size i.e. if same tableCell have any other UI component other than collectionview or there is top bottom margin for collectionView then it won’t be calculated. For this, you can create multiple cells in which one cell only contain collectionview (Best Approach for now) or you can return your actual tableview cell height in systemLayoutSizeFitting by calculation.
systemLayoutSizeFitting