Динамический CollectionViewCell в TableViewCell Swift

Вопрос:

Как сделать UITableViewCell высоту динамичной в соответствии с UICollectionViewCell?

Просмотр иерархии:

UIViewController

UITableView

UITableViewCell

UICollectionView

UICollectionViewCell1

Этикетка 1

UICollectionViewCell2

Этикетка 2

UICollectionViewCell3

Этикетка 3

[So on]

Объяснение:

Здесь Label1, Label2, label 3 имеют динамическую высоту, а numberOfRows в UICollectionView также является динамической. Мне нужна высота UITableViewCell в соответствии с UICollectionViewCell.


person dahiya_boy    schedule 13.10.2017    source источник


Ответы (2)


Просмотр иерархии в UIViewController

введите здесь описание изображения

Шаги:

  1. Связать делегата и источник данных
  • Свяжите UItableView делегата и источник данных с UIViewController.

  • Свяжите UICollectionView делегата и источника данных с UItableViewCell здесь 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)
     }
     }
    

Выход:

  • Красная рамка: UITableViewCell
  • Желтая рамка: UICollectionViewCell
  • Черный контур: ярлык

с UICollectionViewDelegateFlowLayout

введите здесь описание изображения

без UICollectionViewDelegateFlowLayout

введите здесь описание изображения

Справка:

UICollectionView внутри UITableViewCell - динамическая высота?

Примечание :

Высота TableViewCell основана на размере содержимого collectionview, т. е. если тот же tableCell имеет какой-либо другой компонент пользовательского интерфейса, кроме collectionview, или для collectionView есть верхнее нижнее поле, тогда он не будет рассчитываться. Для этого вы можете создать несколько ячеек, в которых одна ячейка содержит только collectionview (на данный момент лучший подход), или вы можете вернуть свой фактический рост tableViewCell в systemLayoutSizeFitting путем расчета.

person dahiya_boy    schedule 13.10.2017
comment
Спасибо, мужик!!! Я искал это целую вечность, казалось, что ничего не работает, но это отлично сработало с моим вариантом использования. - person Parag Pawar; 05.05.2021

как присвоить высоту ячейке в соответствии с текстом в Swift

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
{
    let message = "Swift is a powerful and intuitive programming language for macOS, iOS, watchOS and tvOS. Writing Swift code is interactive and fun, the syntax is concise yet expressive, and Swift includes modern features developers love."


    let font = UIFont.systemFont(ofSize: 12.0)
    let height = heightForLabel(text: message, font: font, width: self.view.bounds.width )

    if height > 40 {
        return height  
    } else {
        return 40.0;
    }
}


func heightForLabel(text:String, font:UIFont, width:CGFloat) -> CGFloat
{
    let label:UILabel = UILabel(frame: CGRect(x:0,y: 0,width:width,height:CGFloat.greatestFiniteMagnitude))
    label.numberOfLines = 0
    label.lineBreakMode = NSLineBreakMode.byWordWrapping
    label.font = font
    label.text = text

    label.sizeToFit()
    return label.frame.height
}
person Dheeraj Kumar    schedule 14.02.2018