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

Почему я получаю "Автоматический макет, который все еще требуется после выполнения -layoutSubviews" при каждом запуске приложения?

Поскольку я добавил следующий код, каждый раз, когда мое приложение открывает этот UITableViewController, он сбой:

 self.noArticlesView = [[UIView alloc] init];
 self.noArticlesView.translatesAutoresizingMaskIntoConstraints = NO;
 self.noArticlesView.backgroundColor = [UIColor colorWithRed:0.961 green:0.961 blue:0.961 alpha:1];

 [self.view addSubview:self.noArticlesView];

 [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.noArticlesView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.0 constant:0.0]];
 [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.noArticlesView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0.0]];
 [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.noArticlesView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1.0 constant:0.0]];
 [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.noArticlesView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeRight multiplier:1.0 constant:0.0]];    

И это дает мне эту ошибку:

* Завершение приложения из-за неперехваченного исключения "NSInternalInconsistencyException", причина: "Автоматическая компоновка по-прежнему требуется после выполнения -layoutSubviews. Реализация UITableView -layoutSubviews требует вызова super. '

Чего я делаю неправильно? Я вызываю этот код в tableView:numberOfRowsInSection:, когда 0 строк.

4b9b3361

Ответ 1

Я был подклассифицирован UIScrollView и получил то же сообщение об ошибке на iOS 7 (но не 8).

Я переопределял layoutSubviews так, как показано ниже:

- (void)layoutSubviews {
    [super layoutSubviews];
    // code to scroll the view
}

Я решил проблему, переведя вызов super layoutSubviews в последнюю вещь в методе:

- (void)layoutSubviews {
    // code to scroll the view
    [super layoutSubviews];
}

Ответ 2

Была та же проблема. Добавлено представление для self.tableView и используемых ограничений. Не добавляйте представления в представление таблицы через addSubview: но добавляйте их в виде заголовков, нижних колонтитулов или ячеек.

Ответ 3

[self.view layoutIfNeeded]

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

Ответ 4

Вам также необходимо отключить трансляцию маски для представления таблицы.

Ответ 5

для меня это было

self.tableView.backgroundView = self.emptyView;

Я изменил это на

    NSComparisonResult order = [[UIDevice currentDevice].systemVersion compare: @"8.0" options: NSNumericSearch];
if (order == NSOrderedSame || order == NSOrderedDescending) {
    // OS version >= 8.0
    self.tableView.backgroundView = self.emptyView;
}else{
    [self.tableView.backgroundView addSubview:self.emptyView];
}

Ответ 6

Оформить заказ "Автоматический макет, который требуется после выполнения -loutoutSubviews" с подклассом UITableViewCell, поскольку вопрос выглядит одинаковым.

Я смог реализовать упомянутую в категорию, указанную в одном из ответов, которая решила проблему для меня. Однако мне пришлось создать категорию в классе UITableView вместо класса UITableViewCell, как это обсуждается в этом конкретном ответе.

Ответ 7

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

Ответ 8

Возможное решение заключается не в том, чтобы добавить noArticlesView непосредственно в таблицу, а в том, чтобы поместить UITableView внутри контейнера UIView (в конечном итоге установив ограничения таблицы в соответствии с рамкой контейнера), а затем ограничьте свой noArticlesView в контейнер, используя те же ограничения, которые вы задали, и в том же месте в вашем коде, что находится внутри метода -tableView:numberOfRowsInSection: UITableViewDataSource. Я протестировал его на простом примере, и он сработал.
Изменения, которые необходимо применить к вашему коду, - это заменить UITableViewController на UIViewController, добавить представление контейнера (если вы не хотите, чтобы ваша таблица точно соответствовала представлению контроллера вида, в этом случае это представление является контейнером), а затем ограничьте свой noArticleView контейнером вместо таблицы. Мой примерный код находится в нижней части этого ответа.
Я попытаюсь сделать возможное объяснение причины проблемы и почему это решение работает, но подумайте, что часть моего объяснения основана на догадках, поэтому она не может быть абсолютно точной.
Прежде всего краткое объяснение того, как процесс рендеринга иерархии представлений работает в iOS. Первым шагом для механизма компоновки является определение размера и положения всех представлений и подпунктов в иерархии представлений. Обычно это делается с помощью итеративного подхода, в котором оцениваются ограничения автоматического макета, чтобы определить размер и положение представлений и подпунктов, а затем каждый метод представления -layoutSubviews вызывается для точной настройки: это означает, что вы можете изменить макет после определения ограничений. То, что требует механизм компоновки, состоит в том, что если метод -layoutSubviews снова изменяет ограничения, тогда -[super layoutSubviews] должен быть вызван снова, чтобы разрешить итеративный процесс: если этого не происходит, механизм компоновки вызывает исключение. В случае UITableView моя догадка заключается в том, что метод tableView: numberOfRowsInSection: вызывается где-то внутри внутреннего метода UITableView layoutSubviews, и этот метод не вызывает [super layoutSubviews]. Поэтому, если ваш метод источника данных таблицы обновляет внутренние ограничения таблицы, в конце метода инициируется исключение. Решение, которое я предлагаю, работает, потому что единственным ограничением, применяемым к таблице, является внешнее ограничение для контейнера, поэтому оно оценивается на первом этапе процесса компоновки, тогда как ограничения, добавленные в методе источника данных таблицы, не имеют отношения к таблице, поскольку они применяются к представлениям, внешним по отношению к таблице (контейнер и noArticlesView), поэтому они не влияют на процесс компоновки внутреннего табличного представления.



//
//  RootController.h

#import 

@interface RootController : UIViewController

@property (nonatomic,strong) IBOutlet UITableView *table;
@property (nonatomic,strong) IBOutlet UIView *container;

@end

//
//  RootController.m


#import "RootController.h"

@implementation RootController

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    // Return the number of sections.
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in the section.

    UIView *_v = [[UIView alloc] init];
    _v.backgroundColor=[UIColor redColor];
    _v.translatesAutoresizingMaskIntoConstraints=NO;

    [self.container addSubview:_v];
    NSLayoutConstraint *_c1 = [NSLayoutConstraint constraintWithItem:_v
                                                            attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.container attribute:NSLayoutAttributeTop multiplier:1.0 constant:20.0];
    NSLayoutConstraint *_c2 = [NSLayoutConstraint constraintWithItem:_v
                                                           attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.container attribute:NSLayoutAttributeBottom multiplier:1.0 constant:-20.0];
    NSLayoutConstraint *_c3 = [NSLayoutConstraint constraintWithItem:_v
                                                           attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.container attribute:NSLayoutAttributeLeft multiplier:1.0 constant:20.0];
    NSLayoutConstraint *_c4 = [NSLayoutConstraint constraintWithItem:_v
                                                           attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.container attribute:NSLayoutAttributeRight multiplier:1.0 constant:-20.0];
    [self.container addConstraints:@[_c1,_c2,_c3,_c4]];

    return 0;
}

Ответ 9

Я отключил автоматическую компоновку на контроллере представления, авария не происходит сейчас