Pruthvi Hariharan
Pruthvi Hariharan

Reputation: 551

Adding header to the tableview with dynamic heigh in swift

I have a UIView(TableHeaderView) which has few labels and collection view. One of the label text is set on run time. So its height is unknown. I'm setting this view as the header for table view.

 let tableHeaderView = CommentsTableHeaderView.instanceFromNib() as! CommentsTableHeaderView
    commentsTable.tableHeaderView = tableHeaderView

In CommentsTableHeaderview class I have the following code. I have set postDesc label's number of lines to 0. If the text comes in few lines, its cutting off. I want this to be dynamic and display all text.

class CommentsTableHeaderView: UIView,UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout {

@IBOutlet weak var postDesc: UILabel!

@IBOutlet weak var profileName: UILabel!

@IBOutlet weak var profileImage: UIImageView!

@IBOutlet weak var imageCollectionView: UICollectionView!

@IBOutlet weak var numberOfComments: UILabel!




class func instanceFromNib() -> UIView {

    return UINib(nibName: "CommentsTableHeaderView", bundle: nil).instantiate(withOwner: nil, options: nil)[0] as! UIView

}

override func awakeFromNib() {
    imageCollectionView.delegate = self
    imageCollectionView.dataSource = self   
    imageCollectionView.register(UINib(nibName: "InnerCollectionCell", bundle: nil), forCellWithReuseIdentifier: "InnerCollectionCell")
    postDesc.lineBreakMode = .byWordWrapping
    postDesc.numberOfLines = 0
    postDesc.text = "hi"



}

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    print("inside collection view")

    return 4
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    print("inside cell")
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "InnerCollectionCell", for: indexPath) as! InnerCollectionCell

    cell.cellImageView.image = UIImage(named: "Recipe.jpeg")

    return cell
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize{
    print("inside size\(collectionView.frame.width)")

    return CGSize(width: imageCollectionView.frame.width, height: 200)
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets{
    return UIEdgeInsets(top: 0, left: 10, bottom: 0, right: 10)
}

} Please see the constraints Image

Upvotes: 1

Views: 1114

Answers (2)

NiTrOs
NiTrOs

Reputation: 359

you need 2 collectionViewDelegate methods:

func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
    return CGSize(width: x, height: x)
}

if you wish to have a dynamic height in referenceSizeForHeaderInSection height field, set your height according to screen size for ex, UIScreen.main.bounds.height * 0.09

Upvotes: 0

Nirav Bhatt
Nirav Bhatt

Reputation: 6969

You need a way to resize your UILabel according to the text size. Do not put height constraints on UILabel. Rather pin its bottom to the bottom view's top.

Do that programmatic resizing after viewDidLoad() - maybe in viewWillAppear() or viewDidAppear(), before you do your first reloadData() call.

Here is a nice tutorial how this should be done - it suggests doing the resizing inside viewDidLayoutSubviews(), which should also be fine.

Upvotes: 1

Related Questions