swift - Expandable FAQ table view iOS -
i'm working on faq screen table view , sections. data array of sections each containing title , array of faqs.
tapping on cell (with question) should expand show answer. because answers have different lenghts , can contains email adresses told use uiwebview presenting them.
at moment cells expand , collapse don't have right heights. heights calculated correctly there problem in heightforrowatindexpath think.
here code:
my cell:
protocol faqcelldelegate: nsobjectprotocol { func webviewheight(height: cgfloat, forcellatindex: nsindexpath) } class faqcell: uitableviewcell { @iboutlet weak var questionlabel: regularlabel! @iboutlet weak var arrowimageview: uiimageview! @iboutlet weak var webview: uiwebview! var delegate: faqcelldelegate? var index: nsindexpath! override func awakefromnib() { super.awakefromnib() // initialization code } override func setselected(selected: bool, animated: bool) { super.setselected(selected, animated: animated) // configure view selected state } func loaddata(#question: string, answer: string, index: nsindexpath, delegate: faqcelldelegate?){ self.webview.delegate = self self.webview.scrollview.bounces = false self.webview.scrollview.scrollenabled = false questionlabel.text = question webview.loadhtmlstring("<head><style type=\"text/css\">body, p {color: #000000; font-size:\(12); font-family: \(kregularfontname); text-align: left;}a{color:#ed174c;}</style></head><body>\(answer)</body>", baseurl: nil) self.delegate = delegate self.arrowimageview.image = uiimage(named: "arrow_down") self.index = index } } extension faqcell: uiwebviewdelegate { func webviewdidfinishload(webview: uiwebview) { delegate?.webviewheight(utils.calculatewebviewheight(webview), forcellatindex: index) } }
in view controller:
var cellsheights = [nsindexpath : cgfloat]() func tableview(tableview: uitableview, cellforrowatindexpath indexpath: nsindexpath) -> uitableviewcell { let cell = tableview.dequeuereusablecellwithidentifier("faqcell", forindexpath: indexpath) as! faqcell let question = self.faqsections[indexpath.section].faqs[indexpath.row].question let answer = self.faqsections[indexpath.section].faqs[indexpath.row].answer cell.loaddata(question: question, answer: answer, index: indexpath, delegate: self) return cell } func tableview(tableview: uitableview, viewforheaderinsection section: int) -> uiview? { let headerview = nsbundle.mainbundle().loadnibnamed("darkheaderview", owner: self, options: nil)[0] as! darkheaderview headerview.headername.text = self.faqsections[section].sectionname return headerview } func tableview(tableview: uitableview, heightforheaderinsection section: int) -> cgfloat { return 40 } func tableview(tableview: uitableview, didselectrowatindexpath indexpath: nsindexpath) { updatetable() } func tableview(tableview: uitableview, diddeselectrowatindexpath indexpath: nsindexpath) { updatetable() } func tableview(tableview: uitableview, heightforrowatindexpath indexpath: nsindexpath) -> cgfloat { if let selectedrows = tableview.indexpathsforselectedrows() as? [nsindexpath] { if selectedrows.find({$0.section == indexpath.section && $0.row == indexpath.row}) != nil { if let height = cellsheights[indexpath] { return height + kbasiccellheight } return 100 } } return kbasiccellheight } func updatetable() { tableview.beginupdates() tableview.endupdates() } extension faqviewcontroller: faqcelldelegate { func webviewheight(height: cgfloat, forcellatindex: nsindexpath) { nslog("section: \(forcellatindex.section) row: \(forcellatindex.row) height: \(height)") if let actualheight = self.cellsheights[forcellatindex] { if actualheight != height { self.cellsheights[forcellatindex] = height } } else { self.cellsheights[forcellatindex] = height } } }
heights correctly calculated , can print out dictionary. cells don't have valid height (they have 100).
if there better solution open sugestions. 1 thing cannot change use of uiwebview , way rows heights calculated.
i noticed using beginupdates() , endupdates() doesn't call cellforrowatindexpath. not sure if it's possible adjust cell's when expanded. i'd change background color, text color , rotate arrow image (or replace it).
thanks help.
edit need refresh question.
i somehow managed make work turned out neeeds done little bit differently.
the problem question text can long , cut. need calculate 2 heights each cell: 1 collapsed state , 1 expanded state. shortly saying have table collapsed cells of different height , each of them have different height when expanded:)
i changed webviewdidfinishload (which calculates heights) function to:
func webviewdidfinishload(webview: uiwebview) { delegate?.cellheight(collapsed: self.questionlabel.height(), expanded: utils.calculatewebviewheight(webview) + self.questionlabel.height(), forcellatindex: index) }
it may needed add additional spacing not problem. problem how set autolayout constraints make question label grow verticaly.
this how views hierarchy looks like:
i put label , arrow in view because had problems centering them verticaly in cell. far know uiviews don't know size, right? setting top , bottom constraints between upper view , web view not sufficient. tried set minimum height upper view (i want cell @ least 50 pt tall) doesn't work.
to make clear have leading, trailing, top , bottom constraints assigned upper view (gray color), label , webview (and width, height, trailing , centery arrow).
how set constraints calling questionlabel.frame.size.height return e.g. 17 1 line 34 2 lines , on?
extension uilabel{ func requiredheight() -> cgfloat{ let label:uilabel = uilabel(frame: cgrectmake(0, 0, self.frame.width, cgfloat.max)) label.numberoflines = 0 label.linebreakmode = nslinebreakmode.bywordwrapping label.font = self.font label.text = self.text label.sizetofit() return label.frame.height } }
Comments
Post a Comment