2014-12-03 3 views
7

Я работаю над приложением, где я сталкиваюсь с какой-то странной проблемой. Я создал UITableViewController в раскадровке и добавил ячейку прототипа. В этой ячейке я добавил элемент UILabel, и этот UILabel занимает всю ячейку. Я настроил его с помощью Auto Layout и добавил ограничения слева, справа, сверху и снизу. UILabel содержит текст.iOS 8 UITableView первая строка имеет неправильную высоту

Сейчас в моем коде, я инициализацию в RowHeight и estimatedRowHeight в виде таблицы:

override func viewDidLoad() { 
    super.viewDidLoad() 

    self.tableView.rowHeight = UITableViewAutomaticDimension 
    self.tableView.estimatedRowHeight = 50 
} 

И я создаю ячейку следующим образом:

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
    var cell : UITableViewCell? = tableView.dequeueReusableCellWithIdentifier("HelpCell") as? UITableViewCell 
    if(cell == nil) { 
     cell = UITableViewCell(style: .Default, reuseIdentifier: "HelpCell") 
    } 
    return cell! 
} 

Я возвращаю две строки в моей таблице Посмотреть. Здесь возникает моя проблема: высота первой строки является большой. Похоже, что вторая, третья строка и т. Д. Имеют правильную высоту. Я действительно не понимаю, почему это так. Может кто-то помочь мне с этим?

ответ

15

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

Я пробовал все различные «исправления» для этой проблемы, а затем нашел, что вызов этих функций после изначального вызова self.tableView.reloadData.

  self.tableView.reloadData() 
      // Bug in 8.0+ where need to call the following three methods in order to get the tableView to correctly size the tableViewCells on the initial load. 
      self.tableView.setNeedsLayout() 
      self.tableView.layoutIfNeeded() 
      self.tableView.reloadData() 

Выполняйте эти дополнительные макеты только после начальной загрузки.

Я нашел очень полезную информацию здесь: https://github.com/smileyborg/TableViewCellWithAutoLayoutiOS8/issues/10

Update: Иногда вы, возможно, придется также полностью настроить ячейку в heightForRowAtIndexPath, а затем вернуть расчетную высоту ячейки. Посмотрите эту ссылку для хорошего примера, http://www.raywenderlich.com/73602/dynamic-table-view-cell-height-auto-layout, в частности, часть на heightForRowAtIndexPath.

Update 2: Я также нашел, что это очень полезно для переопределения estimatedHeightForRowAtIndexPath и поставить несколько точной оценки высоты строки. Это очень полезно, если у вас есть UITableView с ячейками, которые могут быть разных высот.

Вот надуманный пример реализации estimatedHeightForRowAtIndexPath:

public override func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { 

    let cell = tableView.cellForRowAtIndexPath(indexPath) as! MyCell 

    switch cell.type { 
    case .Small: 
     return kSmallHeight 
    case .Medium: 
     return kMediumHeight 
    case .Large: 
     return kLargeHeight 
    default: 
     break 
    } 
    return UITableViewAutomaticDimension 
} 

Update 3: (! Woo-ух)UITableViewAutomaticDimension было зафиксировано для IOS 9. Таким образом, вы являетесь ячейками , должны автоматически сами по себе, не вычисляя высоту ячеек вручную.

0

В iOS 8, присваивая значение estimatedRowHeight, значение включает новую функцию расчета высоты строки iOS 8. Это означает, что высота ячейки получается с помощью внутренних ограничений изнутри. Если с этими ограничениями что-то не так, вы получите нечетные результаты. Итак, что-то не так с вашими ограничениями в ячейке. Они, вероятно, неоднозначны; это обычная причина несогласованности. Однако это все, что я могу вам сказать, поскольку вы на самом деле не показывали/не описывали ограничения.

+0

Я уверен, что мои ограничения не неоднозначным, так как у меня есть только 4 ограничения на UILabel. Есть ли у вас какое-либо другое предположение, что может быть неправильным? – Devos50

+1

Не будьте «уверены». Есть способы узнать, есть ли у вас двусмысленный макет. Используй их. Не используйте ваше чувство кишки; это проблема, а не решение. Если бы вы _knew_, что составляло однозначный макет, мы бы не были здесь с вами проблемы, не так ли? Послушай, что я тебе говорю. Простой факт состоит в том, что 4 ограничения, закрепляющие левый, правый, верхний и нижний, не достаточны. Вероятно, ваши ограничения _are_ неоднозначны. – matt

0

Предлагаю удалить нижнее ограничение на UILabel. Он изменит размер в соответствии с текстом, и ячейка также должна изменить размер.

Если это не помогло устранить проблему, попробуйте добавить следующее в viewDidLoad():

self.tableView.reloadData()

+0

Благодарим вас за предложение, но если я удалю ограничение, UILabel не изменит размер. Кроме того, перезагрузка данных не решает проблему. – Devos50

+0

Не могли бы вы поделиться скриншотом своих ограничений с ячейкой? – Armin

2

Как говорит Apple, в описании setNeedsLayout:

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

Из-за этого вы должны добавить необходимые строки коды (которые должны быть выполнены с правым макетом) в dispatch_after block (который поставит ваш метод в очереди RunLoop). И ваш код будет выполнен после применения макета потребности.

Пример:

- (void)someMethod { 

[self.tableView reloadData]; 

[self.tableView setNeedsLayout]; 

[self.tableView layoutIfNeeded]; 

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 

      //code which should be executed with the right size of table 

     }); 
Смежные вопросы