2016-05-08 4 views
0

Подкласс UITableViewCell содержит UIButton с многострочным текстом, т. Е. Свойство numberOfLines = 0.Как автоматически настроить высоту UITableViewCell, содержащую многострочный UIButton?

Размеры ячеек таблицы меняются по высоте, поэтому высота ячейки установлена ​​равной UITableViewAutomaticDimension.

Высота ячейки адаптируется при добавлении UILabel с несколькими текстовыми строками. Однако он не адаптируется к UIButton, ведь рамка кнопки не приспосабливается к кадру ее titleLabel.

Что я могу сделать, чтобы ячейка просмотра таблицы и ее содержимое отображались на высоте кнопки?

class MyButtonCell: UITableViewCell { 

    var button: UIButton! 
    var buttonText: String? 

    convenience init(buttonText: String?) { 
     self.init() 

     self.buttonText = buttonText 

     button = UIButton(type: UIButtonType.System) 
     button.titleLabel?.numberOfLines = 0 
     button.titleLabel?.lineBreakMode = .ByWordWrapping 
     button.contentHorizontalAlignment = .Center 
     button.titleLabel?.textAlignment = .Center 

     button.translatesAutoresizingMaskIntoConstraints = false 
     contentView.addSubView(button) 

     NSLayoutConstraint.activateConstraints([ 
      button.topAnchor.constraintEqualToAnchor(self.contentView.topAnchor), 
      button.bottomAnchor.constraintEqualToAnchor(self.contentView.bottomAnchor), 
      button.rightAnchor.constraintEqualToAnchor(self.contentView.rightAnchor), 
      button.leftAnchor.constraintEqualToAnchor(self.contentView.leftAnchor) 
      ]) 

     button.setTitle(buttonText, forState: .Normal) 
     button.setTitleColor(buttonTextColor, forState: UIControlState.Normal) 
     button.titleLabel?.font = buttonFont 
    } 
} 

Высота ячейки рассчитывается автоматически:

tableView.estimatedRowHeight = 100 

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { 
    return UITableViewAutomaticDimension 
} 

UPDATE:

Пример проекта на https://github.com/mtrezza/ButtonCellHeightBug

Поданный компании Apple Bug Report # 26170971.

Результаты ошибок в этом: enter image description here

+0

Вы используете раскадровку и автозапуск? – Siriss

+0

@Siriss Я не использую раскадровку для этого представления таблицы, хотя я использую для этого автоматический макет кода (см. Строку 'NSLayoutConstraint') выше. – Manuel

+0

Получил это. Попробуйте sizeToFit() на вашей кнопке после того, как вы установили текст. – Siriss

ответ

1

Вы должны использовать estimatedHeightForRowAtIndexPath. На вашей кнопке вы можете позвонить sizeToFit(), который изменит ее размер, чтобы он содержал текст.

Кроме того, если вы установили оценочный размер на tableView (как и вы), вам обычно не нужно вызывать heightForRowAtIndexPath или estimatedHeightForRowAtIndexPath, а tableView установит его для вас.

EDIT:

Я создал тестовый проект, и вы, кажется правильным. Использование UIButton setTitle не изменяет размер ячейки.

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

//paragraphs is just a string array. 
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { 
     let label = UILabel(frame: CGRectMake(0,0,tableView.frame.width, <your prototype height>)) 
     label.numberOfLines = 0 
     label.text = paragraphs[indexPath.row] 
     label.sizeToFit() 
     print(label.frame.height) 
     return label.frame.height 
    } 

Ошибка в iOS?

+0

. Для автоматического расчета высоты ячейки должны быть заданы оба свойства вида таблицы 'оцененныйRowHeight' и' rowHeight'. Так как свойство не установлено, вместо этого метод 'heightForRowAtIndexPath' переопределяется. Свойства табличного представления взаимозаменяемы с методами AFAIK. Так что это кажется прекрасным. – Manuel

+0

Нет указанной высоты. ForRow переопределит tableview.estimatedRowHeight. Если вы установили расчетную высоту в tableView, вам не нужно вызывать методы делегатов height или valuHeight, поскольку tableView будет обрабатывать его для вас. Вы должны использовать AutoLayout и иметь достаточно ограничений, чтобы дать достаточную информацию для рисования ячейки. – Siriss

+0

Вы уверены? Apple заявляет: «Чтобы включить ячейки отображения таблицы размеров, вы должны установить свойство rowHeight в представлении таблицы в UITableViewAutomaticDimension. Вы также должны присвоить значение свойству оценочногоRowHeight. Как только оба этих свойства будут установлены, система использует Auto Layout, чтобы вычислить фактическую высоту строки. " https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/WorkingwithSelf-SizingTableViewCells.html – Manuel

0

Полностью динамическая высота для ячейки таблицы зрения достигается 1) с использованием оцененной высоты строки, 2) установки rowHeight на AutoDimension, 3) и , а самое главное с использованием ограничений в вашей xib/раскадровке. Ячейка может содержать кнопки/метки или любые компоненты пользовательского интерфейса, которые вы хотели бы иметь, до тех пор, пока вы их должным образом ограничиваете, в частности, чтобы убедиться, что все ограничено по вертикали, поэтому представление таблицы может определять высоту ячейки. И таким образом вам не нужно вычислять высоту динамического текста, нет необходимости в sizeToFit/sizeThatFit, и он работает для разных размеров экрана.

+0

Спасибо за ваш ответ, @Siriss смог воспроизвести мою проблему, см. Ответ выше. Таблица и ячейка в этом случае не предназначены для раскадровки, а в коде с использованием автоматической компоновки. 4 необходимых ограничения для одной кнопки в ячейке просмотра таблицы довольно просты, см. Выше. Тем не менее высота адаптирована для ярлыков с несколькими линиями, но не для кнопок. Я думаю, это связано с тем, что текст кнопки не задан напрямую, а с помощью 'setTitle: forState', поэтому ограничения/рамки высоты метки установлены слишком поздно, и высота ячейки вычисляется на основе titleLabel без текста. – Manuel

+2

Хорошо, теперь я вижу трудности. UILabel уважает numberOfLines, но UIButton имеет тенденцию находиться в одной строке, если вы не выполняете некоторые вычисления и не устанавливаете фрейм явно, что очень утомительно. Если макет является препятствием, просто используйте UILabel - это намного проще в правильном расположении - и добавьте распознаватель жестов, чтобы сделать его доступным для кликов. – Stephenye

Смежные вопросы