ios - getting the height of a label in custom cell to use for heightForRowAt in my main view controller -
i have view controller uses custom cell called searchcell bring content in , wondering how can height of label lblleft , use in tableview(_ tableview: uitableview, heightforrowat indexpath: indexpath) -> cgfloat function return height of label. code i'm using in main view controller:
func tableview(_ tableview: uitableview, cellforrowat indexpath: indexpath) -> uitableviewcell { if searchmode == searching { let cell: mhsearchcell = tableview.dequeuereusablecell(withidentifier: mhsearchcell.reusableidentifier()) as! mhsearchcell cell.helper = helpers[indexpath.row] cell.delegate = self return cell } }
part of code creates label in mhsearchcell, label connected here iboutlet:
lblleft.text = "" if let expertisecount = helper.expertise { let paragraphstyle = nsmutableparagraphstyle() paragraphstyle.linespacing = 5 paragraphstyle.linebreakmode = .bywordwrapping paragraphstyle.alignment = nstextalignment.center lblleft.numberoflines = 0 let finalstring = expertisecount.map({$0.name!}).joined(separator: " \u{00b7} ") let finalattributedstring = nsmutableattributedstring(string: finalstring, attributes: [nsparagraphstyleattributename:paragraphstyle]) lblleft.attributedtext = finalattributedstring }
i use custom extension calculate height of nsattributedstring. "containerwidth" max width of label, contentview.bounds.size.width of cell.
extension nsattributedstring { func height(containerwidth: cgfloat) -> cgfloat { let rect = self.boundingrect(with: cgsize.init(width: containerwidth, height: cgfloat.greatestfinitemagnitude), options: [.useslinefragmentorigin, .usesfontleading], context: nil) return ceil(rect.size.height) } func width(containerheight: cgfloat) -> cgfloat { let rect = self.boundingrect(with: cgsize.init(width: cgfloat.greatestfinitemagnitude, height: containerheight), options: [.useslinefragmentorigin, .usesfontleading], context: nil) return ceil(rect.size.width) }
}
one "trick" heightforrowatindexpath called before cellforrowatindexpath. need create placeholder cell , keep reference it. this:
// init once , var searchcellplaceholder = searchcell() // use whatever default initializer func tableview(_ tableview: uitableview, heightforrowat indexpath: indexpath) -> cgfloat { let object = data[indexpath.row] // keep reusing cell , populate new object text, use configure method in cellforrowatindex too. configurecell(cell: searchcellplaceholder object: object) // height of label after text applied let height = searchcell.label.height(containerwidth: serachcell.contentview.bounds.size.width) return height }
you don't want init placeholder cell in heightforrowatindexpath because kill performance initialize object every time that's called. that's why initialize beginning , keep reusing it.
//
if you're using auto layout, can how have uitableview automatically set height of cell you. better option.
Comments
Post a Comment