2

I have this uicollectionviewcell

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = commentSection.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! CommentCell
    return cell
}

CommentCell:

let CommenterprofileImage: UIImageView = {
        let v = UIImageView()
        v.translatesAutoresizingMaskIntoConstraints = false
        return v
    }()
    let commentText: UILabel = {
        let l = UILabel()
        l.numberOfLines = 0
        l.text = "some text"
        l.translatesAutoresizingMaskIntoConstraints = false
        return l
    }()
    override init(frame: CGRect) {
        super.init(frame: frame)
        backgroundColor = .blue
        designCell()
    }
    func designCell(){

        addSubview(CommenterprofileImage)
        addSubview(commentText)

        addCellConstraints()
    }

    func addCellConstraints(){  
        CommenterprofileImage.topAnchor.constraint(equalTo: self.topAnchor,constant:10).isActive = true
        CommenterprofileImage.leftAnchor.constraint(equalTo: self.leftAnchor,constant:20).isActive = true
        CommenterprofileImage.widthAnchor.constraint(equalToConstant: 70).isActive = true
        CommenterprofileImage.heightAnchor.constraint(equalToConstant: 70).isActive = true

        commentText.topAnchor.constraint(equalTo: CommenterprofileImage.bottomAnchor,constant:20).isActive = true
        commentText.leftAnchor.constraint(equalTo: self.leftAnchor).isActive = true
        commentText.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
    }

And i want this cell's width to be equal to the view's width,but i want it's height to depend on it's content. I tried doing this

layout.estimatedItemSize = CGSize(width: view.frame.width, height: 100)

But then my cell's height is 100 and width is less than 100.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
for rent
  • 105
  • 2
  • 8
  • You can calculate label height with bounded rect method of string , that will give you estimated height of label because as a content it is the one that changes , and to get exact height of cell just add your image height with estimated height + y position constraints.And other good option is to use UICollectionViewLayout. – Tushar Sharma Aug 13 '17 at 19:15
  • @TusharSharma bounded rect method returns 0 – for rent Aug 13 '17 at 19:30
  • show code how you doing? – Tushar Sharma Aug 13 '17 at 19:32
  • @TusharSharma `print(commentText.bounds.size.height)` – for rent Aug 13 '17 at 19:32
  • Not like that check this answer-: https://stackoverflow.com/questions/30450434/figure-out-size-of-uilabel-based-on-string-in-swift – Tushar Sharma Aug 13 '17 at 19:35
  • @TusharSharma please can you show your answer in code just like it's supposed to be.I got the text height and image height,now how do i add it to cell's and colletionview's height? – for rent Aug 13 '17 at 19:41

1 Answers1

0

You Can do it this way-:

Calculate label height with boundingRect method first-:

func estimatedFrameHeight(text:String) -> CGRect{
        let size = CGSize(width: (view.frame.width/2 - 8), height: 1000)
        let options = NSStringDrawingOptions.usesFontLeading.union(.usesLineFragmentOrigin)
        let attribute = [NSFontAttributeName:UIFont.systemFont(ofSize: 11)]
        return NSString(string: text).boundingRect(with: size, options: options, attributes: attribute, context: nil)
    }

Keep the exact same font you providing to your label,And keep .usesLineFragmentOrigin for multi line label.

Now in CollectionView sizeForItemAt indexPath do this-:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        let width = (collectionView.frame.width)
        let subDict = subCategoryListArray[indexPath.row]
        if let product_name = subDict["product_name"] as? String {
        let height = estimatedFrameHeight(text:product_name)
        return CGSize(width: width, height: height.height + 70 + 10 + 20)
    }
        return CGSize(width: 0, height: 0)

    }

let height = estimatedFrameHeight(text:product_name) . This will provide you with estimated height as well as width if you need. Now you have your label height calculated you need to add imageView height , y position constraints to make it work.You can get it from here-:

CommenterprofileImage.heightAnchor.constraint(equalToConstant: 70).isActive = true

Height = 70 you have.

And,

CommenterprofileImage.topAnchor.constraint(equalTo: self.topAnchor,constant:10).isActive = true

commentText.topAnchor.constraint(equalTo: CommenterprofileImage.bottomAnchor,constant:20).isActive

Top Constraint is = 10

Top Constraint is = 20

So you need to add this now as you can see I did in answer.

Remark-:

only add ImageView Height if it is above label else not require, just add height and y padding for what ever you have above label.

Same to calculate exact width for label subtarct leading or trailing space.

If label covers complete width (No insets subtraction required)-:

func estimatedFrameHeight(text:String) -> CGRect{
        let size = CGSize(width: (view.frame.width), height: 1000)
        let options = NSStringDrawingOptions.usesFontLeading.union(.usesLineFragmentOrigin)
        let attribute = [NSFontAttributeName:UIFont.systemFont(ofSize: 11)]
        return NSString(string: text).boundingRect(with: size, options: options, attributes: attribute, context: nil)
    }

If label is 20 points from leading then subtract that-:

func estimatedFrameHeight(text:String) -> CGRect{
            let size = CGSize(width: (view.frame.width - 20), height: 1000)
            let options = NSStringDrawingOptions.usesFontLeading.union(.usesLineFragmentOrigin)
            let attribute = [NSFontAttributeName:UIFont.systemFont(ofSize: 11)]
            return NSString(string: text).boundingRect(with: size, options: options, attributes: attribute, context: nil)
        }
Tushar Sharma
  • 2,839
  • 1
  • 16
  • 38