Возможное решение не добавлять noArticlesView
непосредственно в таблице, но это поместить UITableView
внутри контейнера UIView
(в конце концов, устанавливая таблицы ограничений, в соответствии с рамой контейнера), а затем тяготы вашего noArticlesView
в контейнер, используя те же ограничения, которые вы задали, и в том же месте в вашем коде, который находится внутри метода -tableView:numberOfRowsInSection:
UITableViewDataSource
. Я протестировал его на простом примере, и он сработал.
Изменения, которые необходимо применить к вашему коду, - это заменить UITableViewController
на UIViewController, добавить представление контейнера (если вы не хотите, чтобы ваша таблица точно соответствовала представлению контроллера вида, в этом случае это представление является контейнером), а затем ограничьте свой noArticleView контейнером вместо таблицы. Мой примерный код находится в нижней части этого ответа.
Я попытаюсь сделать возможное объяснение причины проблемы и почему это решение работает, но подумайте, что часть моего объяснения основана на догадках, поэтому она не может быть полностью точной.
Прежде всего краткое описание того, как процесс рендеринга иерархии представлений работает в iOS. Первым шагом для механизма компоновки является определение размера и положения всех представлений и подпунктов в иерархии представлений. Обычно это выполняется с помощью итеративного подхода, в котором оцениваются ограничения автоматического макета, чтобы определить размер и положение просмотров и подсмотров, а затем метод -layoutSubviews
каждого вида предназначен для точной настройки: это означает, что вы можете изменить макет после ограничений оцениваются. То, что требует механизм компоновки, состоит в том, что если метод -layoutSubviews
снова изменяет ограничения, то необходимо снова вызвать -[super layoutSubviews]
, чтобы разрешить итеративный процесс: если этого не происходит, механизм компоновки вызывает исключение. В случае UITableView моя догадка заключается в том, что метод tableView: numberOfRowsInSection: вызывается где-то внутри внутреннего метода UITableView layoutSubviews, и этот метод не вызывает [super layoutSubviews]. Поэтому, если ваш метод источника данных таблицы обновляет внутренние ограничения таблицы, в конце метода инициируется исключение. Решение, которое я предлагаю, работает, потому что единственным ограничением, применяемым к таблице, является внешнее ограничение для контейнера, поэтому оно оценивается на первом этапе процесса компоновки, тогда как ограничения, добавленные в методе источника данных таблицы, не имеют отношения к таблице, поскольку они применяются к представлениям, внешним по отношению к таблице (container и 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;
}
Не эксперт, но у меня тоже была эта проблема, и я думаю, что это потому, что UITableView реализует собственную версию layoutSubviews (или других методов, которые необходимы для автоматического макета). Я поднимаю ваш вопрос, потому что я тоже хотел бы получить ответ :) – AncAinu
Да, мне просто нужно вернуться к использованию фреймов для этого (что я сделал ранее), но Auto Layout было бы неплохо использовать. :/ –
Я вернулся к кадру для этого, но это действительно не удобно, когда все с автозапуском ... – AncAinu