чому UITableViewAutomaticDimension не працює?


76

Привіт є багато питання , відповідаючи на динамічну висоту для UITableViewCellз UITableView. Однак мені здається дивним, коли я це робив.

ось кілька відповідей:

тут і тут

зазвичай це відповідає динамічній висоті для комірки

tableView.estimatedRowHeight = 44.0
tableView.rowHeight = UITableViewAutomaticDimension

але в моєму випадку мені цікаво, що цей рядок нічого не робить.

my UITableViewпереглядається після натискання панелі вкладок у розділі splitview. Це корисно?

Можливо, мені чогось не вистачає. Хто-небудь міг мені допомогти, я витратив 2 години на дурість.

Це моє обмеження для заголовка, заголовок може бути довгим, але ярлик - ні.

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

і це моя камера

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


2
Вам слід ще раз перевірити з вами UITableViewCellналаштування авторозкладки в xib / storyboard. У вас там якась проблема на 100%
Віталій Гоженко

2
так, я переписую це. Надія з’ясувати, що це спричиняє
CaffeineShots

Якщо ви розмістите там свій xib / раскадровку, я можу вам з цим допомогти
Віталій Гоженко

Ви встановили обмеження для перегляду щодо верхньої та нижньої частин перегляду вмісту комірки?
Zell B.

чи слід просто робити скріншот?
CaffeineShots

Відповіді:


163

Для того, щоб UITableViewAutomaticDimension працював, вам потрібно встановити всі ліві, праві, нижні та верхні обмеження щодо подання контейнера комірки. У вашому випадку вам потрібно буде додати відсутні пробіли внизу для обмеження суперперегляду для мітки під заголовком


14
Зауважте, вам, мабуть, доведеться встановити обмеження внизу для деяких подань, щоб вони були> =, а не просто =, щоб дозволити їм рости з динамічною висотою комірки. Це була хитрість для мене.
Ryan R

@khunshan Ви впевнені, що не використовуєте класи розміру?
Zell B.

@ZellB. так, ти маєш рацію. через обмеження відсутній клас iPhone. (Y)
Хуншань

28

Я додав обмеження програмно і випадково додав їх до комірки безпосередньо, тобто не щодо contentViewвластивості. Додавання обмежень для contentViewвирішення цього для мене!


так, нам потрібно чітко знати, яке обмеження ми використовуємо для того, що одне обмеження, яке відсутнє або додане, може призвести до двозначності або невиконання обмеження.
CaffeineShots

Я знаю, що це старе, але я не думаю, що це правильний спосіб зробити це. Якщо ви не додаєте обмежень до подання вмісту. Вигляд спотворюється, коли ви відкриваєте будь-який стиль редагування для комірки, наприклад Видалення або самостійно переміщуєте рядок.
Esko918,

@ Esko918 Я думаю, ти неправильно читаєш його відповідь. Він заявляє, що вам потрібно додати обмеження до contentView. Я також випадково додали обмеження на UITableViewCellколи воно повинно бути до UITableViewCellcontentView
Alan

Це те, що я сказав. Якщо ви не додасте обмеження до подання вмісту, тоді вигляд спотвориться, коли ви виберете стиль редагування, наприклад, видалення або переміщення рядка. Ви не повинні змінювати перегляд комірок безпосередньо, оскільки UIKit змінює макет комірок, коли ви натискаєте режим редагування, і комірка зміщується вправо. Вам слід додати всі підпрогляди та обмеження макета до подання вмісту. Не сам погляд
Esko918,

25

Щоб встановити автоматичний розмір для висоти рядка та передбачуваної висоти рядка, переконайтесь, що для автоматичного вимірювання ефективності для розмітки комірки / висоти рядка використовується автоматичний розмір.

  • Призначення та реалізація табличного перегляду dataSource та делегування
  • Призначити UITableViewAutomaticDimensionрядуHeight і оціненомуRowHeight
  • Впровадити методи делегат / dataSource (тобто heightForRowAtповернути йому значення UITableViewAutomaticDimension)

-

Завдання C:

// in ViewController.h
#import <UIKit/UIKit.h>

@interface ViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>

  @property IBOutlet UITableView * table;

@end

// in ViewController.m

- (void)viewDidLoad {
    [super viewDidLoad];
    self.table.dataSource = self;
    self.table.delegate = self;

    self.table.rowHeight = UITableViewAutomaticDimension;
    self.table.estimatedRowHeight = UITableViewAutomaticDimension;
}

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {

    return UITableViewAutomaticDimension;
}

Стрімкий:

@IBOutlet weak var table: UITableView!

override func viewDidLoad() {
    super.viewDidLoad()

    // Don't forget to set dataSource and delegate for table
    table.dataSource = self
    table.delegate = self

    // Set automatic dimensions for row height
    // Swift 4.2 onwards
    table.rowHeight = UITableView.automaticDimension
    table.estimatedRowHeight = UITableView.automaticDimension


    // Swift 4.1 and below
    table.rowHeight = UITableViewAutomaticDimension
    table.estimatedRowHeight = UITableViewAutomaticDimension

}



// UITableViewAutomaticDimension calculates height of label contents/text
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    // Swift 4.2 onwards
    return UITableView.automaticDimension

    // Swift 4.1 and below
    return UITableViewAutomaticDimension
}

Для екземпляра мітки в UITableviewCell

  • Встановити кількість рядків = 0 (& режим розриву рядка = усіка хвоста)
  • Встановіть усі обмеження (зверху, знизу, праворуч ліворуч) щодо контейнера супервигляду / комірки.
  • Необов’язково : Встановіть мінімальну висоту для етикетки, якщо ви хочете, щоб мінімальна вертикальна площа, покрита етикеткою, навіть якщо немає даних.

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

Примітка : Якщо у вас більше одного ярлика (UIElements) з динамічною довжиною, який слід відрегулювати відповідно до розміру вмісту: відрегулюйте "Пріоритет обійму вмісту та стійкості до стиснення" для міток, які потрібно розгорнути / стиснути з вищим пріоритетом.


реалізація heightForRowAt із поверненням роботи
UITableView.automaticDimension

19

Також переконайтесь, що Рядки для вашого UILabel у клітинці встановлені на 0. Якщо встановлено на 1, він не буде рости вертикально.


7

У мене конкретний випадок, і 99% рішень, які я прочитав, не спрацювали. Я думав поділитися своїм досвідом. Сподіваюся, це може допомогти, оскільки я боровся пару годин, перш ніж вирішити цю проблему.

Мій сценарій :

  • Я використовую два TableViews в одному ViewController
  • Я завантажую користувацькі комірки (xib) у ці перегляди таблиць
  • Динамічний вміст у клітинках складається з двох міток
  • Сторінка використовує ScrollView

Що мені потрібно було досягти :

  • Динамічна висота TableView
  • Висота динамічного TableViewCells

Що вам потрібно буде перевірити, щоб це працювало безперебійно :

  • Як і кожен навчальний посібник та відповідь, які ви підкажете, встановіть усі обмеження для вашої мітки / вмісту (зверху, знизу, ведучі та кінцеві) і встановіть для ContentView (Superview). Цей відеоурок буде корисним .

  • У viewWillAppearметоді мого ViewController я даю одному зі своїх tableViews ( tableView2) передбачувану висоту рядка, а потім використовую UITableViewAutomaticDimensionяк таку (і як видно з усіх посібників / відповідей):

        override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
    
        tableView2.estimatedRowHeight = 80
        tableView2.rowHeight = UITableViewAutomaticDimension
    
    }
    

Для мене цих попередніх кроків було недостатньо. Мій TableView просто взяв оцінкуRowHeight і помножив її на кількість комірок. Меее.

  • Оскільки я використовую два різних tableViews, я створив розетку для кожного з них, tableView1і tableView2. Дозволяючи мені змінювати розмір їх у viewDidLayoutSubviewsметоді. Не соромтеся запитувати у коментарі, як я це зробив.

  • Один додатковий крок це виправив для мене, додавши це до viewDidAppearметоду:

    override func viewDidAppear(_ animated: Bool) {
    tableView1.reloadData() // reloading data for the first tableView serves another purpose, not exactly related to this question.
    tableView2.setNeedsLayout()
    tableView2.layoutIfNeeded()
    tableView2.reloadData()
    }
    

Сподіваюся, це комусь допомагає!


остання порада (але без подвійного IBOutlet) все ще корисна в 2019 році.
zhukov.ever

6

Станом на iOS 11 та Xcode 9.3 більшість наведеної інформації є помилковими. Посібник Apple пропонує налаштування

    tableView.estimatedRowHeight = 85.0
    tableView.rowHeight = UITableViewAutomaticDimension

Сесія 245 WWDC 2017 (Створення програм з динамічним типом, приблизно 16:33 у відео) пропонує щось подібне. Ніщо з цього не змінило мене.

Для комірки стилю Субтитри все, що потрібно для отримання саморозмірних комірок подання таблиці, - це встановити кількість рядків (у розділі Етикетки інспектора атрибутів) на 0 для заголовка та субтитрів. Якщо одна з цих міток занадто довга, і ви не встановите кількість рядків на 0, комірка подання таблиці не змінить свій розмір.


Якщо встановити numberOfLinesзначення 0для обох етикеток, можна отримати самостійний розмір за допомогою нестандартних UITableViewCells. Дуже дякую!
mxcl

5

Забули видалити tableView(heightForRowAt:indexPath:)

Може бути так, що, як і я, ви випадково забули видалити шаблонний код heightForRowAtметоду.

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

... І звичайно ж, не дайте йому обмеження висоти ;-)
Маркос

1
Ви можете повернутися UITableViewAutomaticDimensionцим методом. Для підкласифікації
Янні

5

Для тих, хто, можливо, зіткнувся зі мною з тією ж проблемою: я цілу годину намагався змусити це працювати. Простий UIlabel з обмеженнями верхнього, лівого та правого нижнього краю. Я використовував willDisplayCell для передачі даних у клітинку, і це спричиняло проблеми з висотою комірок. Поки я помістив цей код в cellForRow, все працювало чудово. Не зрозумів, чому це сталося, можливо висота комірки була розрахована до того, як буде викликано willDisplayCell, тому не було вмісту для правильного розрахунку. Мене просто хотіли згадати і, мабуть, допомогти комусь із тією ж проблемою.


Дякую! Я теж боровся саме з цим питанням. Мені здається помилкою UIKit, але це вирішило!
Gary Hooper

4

це добре працювало для мене в iOS 11 і новіших версіях, в той час як в iOS 10 рішення було додати

table.rowHeight = UITableView.automaticDimension
table.estimatedRowHeight = 200 // a number and not UITableView.automaticDimension

також переконайтеся, що ви додали "heightForRowAt", навіть якщо він працює в iOS 11 і вище, це потрібно, якщо ви підтримуєте iOS 10

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

3

У моєму випадку у мене було два UITableView, мені довелося змінити цей метод як

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    CGFloat height = 0.0;
    if (tableView == self.tableviewComments) {
        return UITableViewAutomaticDimension;
    }else if (tableView == self.tableViewFriends) {
        height = 44.0;
    }
    return height;
}

3

Спробуйте це, просте рішення, це працює для мене,

In viewDidLoad напишіть цей код,

-(void)viewDidLoad 
{
[super viewDidLoad];
 self.tableView.estimatedRowHeight = 100.0; // for example. Set your average height
 self.tableView.rowHeight = UITableViewAutomaticDimension;
}

У коміркуForRowAtIndexPath напишіть цей код,

 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
 {
  static NSString *CellIdentifier = @"Cell";
  UITableViewCell *cell = [tableView 
  dequeueReusableCellWithIdentifier:CellIdentifier];
 if (cell == nil) {
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] ;
  }
    cell.textLabel.numberOfLines = 0; // Set label number of line to 0
    cell.textLabel.text=[[self.arForTable objectAtIndex:indexPath.row] valueForKey:@"menu"];
    [cell.textLabel sizeToFit]; //set size to fit 
    return cell;
 }

1

Для мого налаштування я спочатку двічі перевірив обмеження в Розкадровці на предмет UITableViewCellоднозначності зверху вниз, а потім довелося змінити код у 2 місцях.

  1. UITableViewDelegate's tableView(_:heightForRowAt:)

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableView.automaticDimension
        // return UITableViewAutomaticDimension for older than Swift 4.2
    }
    
  2. UITableViewDelegate's tableView(_:estimatedHeightForRowAt:)

    func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableView.automaticDimension
        // return UITableViewAutomaticDimension for older than Swift 4.2
    }
    

Крок 1 і 2 дозволяє застосувати автоматичний розмір лише для певних рядків. Для застосування до цілого UITableViewвикористовуйте:

tableView.rowHeight = UITableView.automaticDimension
tableView.estimatedRowHeight = UITableView.automaticDimension
// return UITableViewAutomaticDimension for older than Swift 4.2

0

Для того, щоб UITableViewAutomaticDimension працював, потрібно переконатися, що всі 4 кутові обмеження додані до суперперегляду. У більшості випадків це добре працює з UILabel, але іноді я виявляю, що UITextView робить трюк, коли UILabel не працює належним чином у той час. Тож спробуйте перейти на UITextView і переконайтеся, що в раскадровці не Scrolling Enabledвстановлено прапорець, або ви також можете встановити його програмно.


0

У мене було три горизонтальних предмети, і більшість лівих мали обмеження ліворуч, середній - зверху, знизу, ліворуч та праворуч. Правий мав правий, а лівий - до середнього предмета. Рішенням було додати додаткові ліві та праві обмеження до середнього елемента (моя мітка), які складали> = деяке число до комірки.


0

Переконайтесь, що всі подання в комірці обмежені переглядом вмісту, а не коміркою.

Як каже яблуко:

викласти вміст комірки табличного подання у вікні вмісту комірки. Щоб визначити висоту комірки, вам потрібен неперервний ланцюжок обмежень та подань (із визначеними висотами), щоб заповнити область між верхнім краєм подання вмісту та його нижнім краєм.


0

У мене є нове рішення .. це спрацювало для мене.

в основному UITableViewAutomaticDimensionперейменований на UITableView.automaticDimension... сподіваюсь..це


0

введіть тут опис зображенняУ моєму випадку я зробив усе, але це не вирішило проблему для мене, нарешті, я перевірив рядки мітки, яка була зафіксована на 3. Зміна значення рядка на 0 вирішує проблему для мене. так що, щоб сказати вам все, це має бути 0, а обмеження Верх, Знизу, Зліва, Право повинні бути прикріплені, щоб працювати нормально.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.