Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
261 views
in Technique[技术] by (71.8m points)

ios - Dynamic CollectionViewCell In TableViewCell Swift

Question:

How To Make UITableViewCell Height Dynamic according the UICollectionViewCell?

View Hierarchy:

UIViewController

UITableView

UITableViewCell

UICollectionView

UICollectionViewCell1

Label 1

UICollectionViewCell2

Label 2

UICollectionViewCell3

Label 3

[So on]

Explanation:

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

View Hierarchy In UIViewController

enter image description here

Steps:

  1. Bind Delegate And Datasource
  • Bind UItableView Delegate and datasource with the UIViewController.

  • Bind UICollectionView Delegate and datasource with the UItableViewCell here TblCell.

  1. In 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
     }
     }
    
  2. In 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)
     }
     }
    

Output:

  • Red Border : UITableViewCell
  • Yellow Border : UICollectionViewCell
  • Black Outline : Label

with UICollectionViewDelegateFlowLayout

enter image description here

without UICollectionViewDelegateFlowLayout

enter image description here

Reference:

UICollectionView inside a UITableViewCell -- dynamic height?

Note :

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 tableViewCell height in systemLayoutSizeFitting by calculation.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...