2015-07-13 4 views
0

Я работаю на экране часто задаваемых вопросов с табличным представлением и разделами. Мои данные представляют собой массив разделов, каждый из которых содержит заголовок и массив faqs.Расширяемый FAQ table view iOS

Нажатие на ячейку (с вопросом) следует расширить ее, чтобы отобразить ответ. Поскольку ответы имеют разные длины, и они могут содержать адреса электронной почты, мне сказали использовать UIWebView для их представления.

В настоящее время клетки расширяются и разрушаются, но у них нет правых высот. Высоты вычисляются правильно, но есть проблема в heightForRowAtIndexPath, я думаю.

Вот код:

Мой мобильный:

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 the view for the 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) 
    } 
} 

В видовом контроллере:

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 
     } 
    } 
} 

Высоты правильно рассчитал, и я могу распечатать словарь. Однако некоторые ячейки не имеют допустимой высоты (у них 100).

Если есть лучшее решение, я открыт для любых предложений. Единственное, что не может быть изменено, это использование uiwebview и вычисление высоты строк.

Я также заметил, что использование beginUpdates() и endUpdates() не вызывает cellForRowAtIndexPath. Я не уверен, возможно ли теперь отрегулировать вид ячейки при ее расширении. Я хотел бы изменить цвет фона, цвет текста и поворот изображения стрелки (или заменить его).

Спасибо за любую помощь.

Редактировать Мне нужно обновить свой вопрос.

Мне как-то удалось заставить его работать, но выяснилось, что это делается немного по-другому.

Проблема в том, что текст вопроса может быть длинным и разрезан. Теперь мне нужно вычислить две высоты для каждой ячейки: одну для сложенного состояния и одну для расширенного состояния. Вскоре говоря у меня есть таблица с разрушенными клетками разной высоты, и каждый из них имеют разную высоту при расширении :)

Я изменил мою webViewDidFinishLoad (который вычисляет высоту) функция для:

func webViewDidFinishLoad(webView: UIWebView) { 
     delegate?.cellHeight(collapsed: self.questionLabel.height(), expanded: Utils.calculateWebViewHeight(webView) + self.questionLabel.height(), forCellAtIndex: index) 
    } 

Это может быть необходимо добавить дополнительный интервал, но это не проблема. Проблема заключается в том, как установить ограничения автоопределения, чтобы сделать знак вопроса расти вертикально.

Это как мой вид иерархии выглядит следующим образом: Views hierarchy

я поставил метку и стрелка в виду, потому что у меня были проблемы с центрирования их verticaly в клетке. Но насколько я знаю, UIViews не знают своего размера, верно? Таким образом, установка только верхних и нижних ограничений между верхним видом и веб-представлением недостаточна. Я попытался установить минимальную высоту для верхнего представления (я хочу, чтобы ячейка была не менее 50 пт), но она не работает.

Это мой прототип клетки: enter image description here

Для того, чтобы понять, теперь я только ведущий, отставая, верхние и нижние ограничения, присвоенные вид сверху (серый цвет), этикетки и WebView (и ширина, высота, trailing и centerY для стрелки).

Как установить эти ограничения, так что вызов questionLabel.frame.size.height вернется, например. 17 для одной строки 34 для 2 строк и т. Д.?

ответ

-1
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 
    } 
} 
+0

Я использую это на своем экране часто задаваемых вопросов. У меня есть расширяемая ячейка, содержащая QuestionLabel и расширяемую часть - AnswerLabel. Поэтому в таблице delagate я вычисляю высоту в «heightForRowAtIndexPath». Удачи. –