【问题标题】:Dynamic CollectionViewCell In TableViewCell SwiftUITableViewCell Swift中的动态UICollectionViewCell
【发布时间】:2018-03-25 06:31:51
【问题描述】:

问题:

如何根据UICollectionViewCell使UITableViewCell高度动态化?

查看层次结构:

UIViewController

UITableView

UITableViewCell

UICollectionView

UICollectionViewCell1

标签 1

UICollectionViewCell2

标签 2

UICollectionViewCell3

标签 3

[等等]

解释:

这里Label1Label2label 3 具有动态高度,UICollectionView 中的numberOfRows 也是动态的。根据UICollectionViewCell,我需要UITableViewCell 的高度。

【问题讨论】:

    标签: ios swift uitableview uicollectionview row-height


    【解决方案1】:

    UIViewController 中查看层次结构

    步骤:

    1. 绑定委托和数据源
    • UItableView委托和数据源与UIViewController绑定。

    • 在此处将TblCellUItableViewCell 绑定UICollectionView 委托和数据源。

    1. 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. 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 inside a UITableViewCell -- dynamic height?

    注意:

    TableViewCell 高度基于collectionview 内容大小,即如果相同的tableCell 具有除collectionview 之外的任何其他UI 组件,或者collectionView 有上下边距,则不会计算它。为此,您可以创建多个单元格,其中一个单元格仅包含collectionview(目前最好的方法),或者您可以通过计算在systemLayoutSizeFitting 中返回您的实际tableViewCell 高度。

    【讨论】:

    • 谢谢你,伙计!!!我一直在寻找这个,似乎没有任何效果,但这与我的用例完美匹配。
    【解决方案2】:

    如何在 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
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-28
      相关资源
      最近更新 更多