Подтвердить что ты не робот

IOS8: Можно использовать "tableview.rowHeight = UITableViewAutomaticDimension" для статических ячеек?

У меня есть UITableView, в котором есть пять статических ячеек. Мне нужна высота ячейки одной ячейки, чтобы автоматически настроить ее содержимое, которое является одним UILabel.

Есть ли способ, которым я могу использовать.

tableView.estimatedRowHeight = 42.0
tableView.rowHeight = UITableViewAutomaticDimension

.. для представления таблицы со статическими ячейками или это работает только для табличных представлений с динамическими ячейками прототипа?

(Или есть ли другой способ сделать это, что вы бы порекомендовали?)

Дополнительная информация

UITableView находится в TableViewController, который встроен в представление контейнера.

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

Я обновляю табличное представление следующим образом

-(void) viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    [_myTableView reloadData];
}

Я добавляю ограничения для UILabel, как описано здесь: http://www.appcoda.com/self-sizing-cells/

4b9b3361

Ответ 1

В iOS 8 я обнаружил, что вы не можете выполнить ту же стратегию, что и для динамической таблицы просмотра таблицы.

Чтобы автоматически настроить высоту статических ячеек, я реализую эти два метода UITableViewDelegate:

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return UITableViewAutomaticDimension;
}

-(CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 44;
}

Надеюсь, что это поможет.

Ответ 2

Расширяя ответ от победителей, представления таблиц на статических ячейках кажутся автоматизированными ячейками на основе содержимого и ограничений после реализации следующих делегатов:

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return UITableViewAutomaticDimension;
}

-(CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 44;
}

ЗА ИСКЛЮЧЕНИЕМ, когда есть метки. По какой-то причине высота собственных значений метки не влияет на расчет высоты ячейки, когда она есть. Моя текущая работа для этого - вставить ярлыки в UIView.

Выполните следующие действия:

  • Вставить ярлык (или метки) в представление. (Выберите ярлыки на IB и нажмите "Меню" > "Редактор" > "Вставить" > "Вид" ).
  • Установить горизонтальные и вертикальные ограничения по границам между этим вид и ячейка
  • Установите горизонтальные и вертикальные ограничения полей между метки (метки) и это представление.

Конечно, это похоже на хак, но работает для меня во всех случаях, которые я пробовал.

Ответ 3

Закончилось это. Не то, что я хотел, но это работает для моих простых требований и длины текста.

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.row == 2)
    {
        CGFloat padding = 30.0f;

        CGFloat labelWidth = self.tableView.bounds.size.width - padding*2;
        NSAttributedString *text = [[NSAttributedString alloc] initWithString:_freeTextLabel.text];
        NSStringDrawingOptions options = NSStringDrawingUsesLineFragmentOrigin;
        CGRect boundingRect = [text boundingRectWithSize:CGSizeMake(labelWidth, CGFLOAT_MAX)
                                             options:options
                                             context:nil];

        return (CGFloat) (ceil(boundingRect.size.height) + padding*2);
    }
    return [super tableView:tableView heightForRowAtIndexPath:indexPath];
}

Ответ 4

ПРИМЕЧАНИЕ. Это основано на ответе @CamelBase, который написан для Objective-C, поэтому в основном просто преобразование в Swift для тех, кто сделал переключатель, и по-прежнему пытается преобразовать материал самостоятельно.


Для тех, кто хочет это сделать, используя Swift, который хочет иметь таблицу со статическими ячейками, вот рабочее решение.

Мне не нужно было использовать этот код (попробовал поместить его в viewDidLoad() и попробовал без него, не имеет значения):

tableView.estimatedRowHeight = 42.0
tableView.rowHeight = UITableViewAutomaticDimension

Сначала вы хотите добавить UILabel в каждую ячейку, в которой вы хотите автоматически развить контент.

Вам нужно будет добавить 4 ограничения для UILabel относительно родителя (вид содержимого ячейки).

  • Ведущая маржа 0
  • Превышение маржи 0
  • Верхняя граница 0
  • Нижняя граница 0

Это приведет к увеличению метки при увеличении ячейки (что наш код ниже).

Теперь просто добавьте этот код:

override func tableView(tableView: UITableView, 
heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat 
{
    let sectionICareAbout = 2
    let rowICareAbout = 1

    // repeat for as many section/row combos you need dynamic sizing on
    if indexPath.section == sectionICareAbout 
      && indexPath == rowICareAbout {
        // replace with how you get the content for the cell
        // in section 2 row 1
        let text = "line1\nline2\nline3"
        return rowHeightForText(text)
    }

    // use auto-dimension if we didn't set something else
    return UITableViewAutomaticDimension
}

func rowHeightForText(text: String) -> CGFloat {
    let labelWidth = tableView.bounds.size.width
    let attributedText = NSAttributedString(string: text)
    let options = NSStringDrawingOptions.UsesLineFragmentOrigin
    let size = CGSize(width: labelWidth, height: CGFloat.max)
    let boundingRect = attributedText.boundingRectWithSize(size, 
        options: options, context: nil)
    return boundingRect.size.height
}

Ответ 5

В IOS8 я обнаружил, что явная установка высоты/ширины строки или высоты/ширины метки в коде вызывает больше проблем, чем исправляет. Я создал динамические и статические таблицы с различной высотой ячеек и многострочными надписями с использованием автозапуска, но вам действительно нужно следовать стандарту Apple на букву, или происходят странные вещи (например, разделители исчезают или ряды случайным образом сбрасываются по высоте).

  • [отредактировано] Задайте оценочные значенияHeightForRowAtIndexPath и heightForRowAtIndexPath для автоматических измерений в вашем UITableViewDelegate

    override func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        return UITableViewAutomaticDimension
    }
    override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        return UITableViewAutomaticDimension
    }
    
  • Убедитесь, что у каждого элемента в ячейке есть ограничение top/bottom/left/right = (not > =, <= или alignX или alignY - оно должно быть =). Вы можете сделать это ограничение с низким приоритетом и обеспечить лучшее ограничение более высокого приоритета, но вы должны дать ему точное начальное значение для размера ячейки.

Ответ 6

Вот простой пример с Swift 3. У нас есть UITableViewController в наборе раскадровки с типом сгруппированы и содержимое статических ячеек типа. Его tableView содержит один UITableViewCell. Ячейка содержит один UILabel, который имеет несколько строк, установленных в 0, и некоторый очень длинный текст для отображения. На этикетке также есть четыре ограничения автоматической компоновки с помощью superView (верхний, нижний, верхний и конечный).

введите описание изображения здесь

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


# 1. Используя tableView(_:estimatedHeightForRowAt:) и tableView(_:heightForRowAt:)

Примечание: для метода tableView(_:estimatedHeightForRowAt:) требуется iOS7

import UIKit

class TableViewController: UITableViewController {

    override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableViewAutomaticDimension
    }

    override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
        return 100 // Return `UITableViewAutomaticDimension` if you have no estimate
    }

}

# 2. Используя свойство estimatedRowHeight и tableView(_:heightForRowAt:)

Примечание: для свойства estimatedRowHeight требуется iOS7

import UIKit

class TableViewController: UITableViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.estimatedRowHeight = 100
    }

    override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableViewAutomaticDimension
    }

}

# 3. Используя tableView(_:heightForRowAt:)

import UIKit

class TableViewController: UITableViewController {

    // Bind this IBOutlet to the cell in Storyboard
    @IBOutlet weak var cell: UITableViewCell!

    override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        let fittingSize = CGSize(width: tableView.bounds.size.width, height: 0)
        let systemLayoutSize = cell.systemLayoutSizeFitting(fittingSize, withHorizontalFittingPriority: UILayoutPriorityRequired, verticalFittingPriority: UILayoutPriorityFittingSizeLevel)
        return systemLayoutSize.height
    }

}

# 4. Используя подкласс UITableViewCell и tableView(_:heightForRowAt:)

import UIKit

class TableViewController: UITableViewController {

    // 1. Set custom class to `CustomCell` for cell in Storyboard
    // 2. Bind this IBOutlet to the cell in Storyboard
    @IBOutlet weak var cell: CustomCell!

    override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        cell.layoutIfNeeded()
        let contentViewSize = cell.contentView.systemLayoutSizeFitting(UILayoutFittingCompressedSize)
        return contentViewSize.height + 1 // + 1 for the separator
    }

}

class CustomCell: UITableViewCell {

    // 1. Set custom class to `CustomCell` for cell in Storyboard
    // 2. Bind this IBOutlet to the cell label in Storyboard
    @IBOutlet weak var label: UILabel!

    override func layoutSubviews() {
        super.layoutSubviews()
        label.preferredMaxLayoutWidth = frame.width
    }

}

Все четыре предыдущих фрагмента кода приведут к следующему отображению:

KuFRB.png

Ответ 7

Я предполагаю, что мне нужно будет сказать ячейке перерисовать, используя что-то вроде

[self.tableView beginUpdates];
[self.tableView reloadRowsAtIndexPaths:@[indexPathOfYourCell] withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates];

Когда дело доходит до динамического изменения высоты tableviewcells.

-(CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return Yourvalue; //return whatever u want ur cell to have size.
  }

Ответ 8

Я тоже искал ответ на этот вопрос и нашел это решение, которое я тестировал и отлично работаю в iOS8.

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.row == 2)  //Dynamic Height
    {
        return UITableViewAutomaticDimension;
    }
    else 
    {
        return 50;  // Static Height
    }
}