Невозможно правильно установить кадр перед viewDidAppear
мне было интересно, знает ли кто-нибудь, почему, когда вы устанавливаете фрейм подвида в viewDidLoad
и viewWillAppear
изменения не влияют на экран, но если вы установите его в viewDidAppear
они делают?
в моем случае я загружаю пользовательский xib с двумя таблицами, а затем пытаюсь переместить их вниз в viewDidLoad
чтобы освободить место для другого представления, которое добавляется в viewDidLoad
как это не всегда нужно, чтобы отобразить его.
проблема в том, когда я устанавливаю frame в viewDidLoad
или viewWillAppear
он установлен на объекте, я могу видеть, распечатав его, но он не отражается на экране. Перемещение моего набора вызовов фрейма в viewDidAppear
заставит все работать, как ожидалось.
неправильно ли думать, что я смогу установить кадр в viewDidLoad
?
- (id)init {
if ( self = [super initWithNibName:@"MyView" bundle:nil] ) {}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.descriptionWebView = [[[UIWebView alloc] initWithFrame:CGRectMake( 0, 0, self.view.frame.size.width, 200 )] autorelease];
[self.view addSubview:self.descriptionWebView];
self.tableView1.autoresizingMask = UIViewAutoresizingNone;
self.tableView2.autoresizingMask = UIViewAutoresizingNone;
[self.descriptionWebView loadRequest:[NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"...." withExtension:@"html"]]];
table1LocationWithHeader = CGRectMake( self.tableView1.frame.origin.x, 200, self.tableView1.frame.size.width, self.tableView1.frame.size.height - 200 );
table2LocationWithHeader = CGRectMake( self.tableView2.frame.origin.x, 200, self.tableView2.frame.size.width, self.tableView2.frame.size.height - 200 );
//this will NOT work
self.tableView1.frame = table1LocationWithHeader;
self.tableView2.frame = table2LocationWithHeader;
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
//this will NOT work
self.tableView1.frame = table1LocationWithHeader;
self.tableView2.frame = table2LocationWithHeader;
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
//this WILL work
self.tableView1.frame = table1LocationWithHeader;
self.tableView2.frame = table2LocationWithHeader;
}
//I added these after comments for stack overflow users, it seems like viewDidLayoutSubviews is the best place to set the frame
- (void)viewWillLayoutSubviews {
[super viewWillLayoutSubviews];
//this will NOT work
self.tableView1.frame = table1LocationWithHeader;
self.tableView2.frame = table2LocationWithHeader;
}
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
//this WILL work
self.tableView1.frame = table1LocationWithHeader;
self.tableView2.frame = table2LocationWithHeader;
}
3 ответов
viewDidLoad вызывается при загрузке класса, однако никакие элементы пользовательского интерфейса не были инициализированы, и поэтому любая попытка ссылаться на них будет перезаписана или недоступна во время процесса инициализации, который происходит между вызовами viewDidLoad и viewDidAppear. После того как все элементы интерфейса были initalised и тянет viewDidAppear называется.
метод viewDidLoad - Вызывается после загрузки представления контроллера в память
в этот момент представление не входит в иерархию представлений.
viewWillAppear-уведомляет контроллер представления о том, что его представление будет добавлено в иерархию представлений.
опять же, представление еще не добавлено в иерархию представлений.
viewDidAppear-уведомляет контроллер представления о том, что его представление было добавлено в иерархию представлений.
только тогда представление добавляется в представление иерархия.
обновление
на viewDidLayoutSubviews
является наиболее подходящим местом для изменения пользовательского интерфейса, прежде чем он фактически появится на экране.
viewDidLayoutSubviews-уведомляет контроллер вида, что его представление только что выложило свои подвиды.
смотрите здесь когда вызывается layoutSubviews?
при использовании autolayout framework не вызывает layoutSubviews автоматически. Это очень важно. От Реф:
- init не вызывает layoutSubviews для вызова (duh)
- addSubview: вызывает layoutSubviews для добавляемого представления, представления, в которое оно добавляется (целевое представление), и всех подвидов цели. ...
Если вы добавляете subview в viewDidLoad, layoutSubviews вызывается перед viewDidAppear, и вы можете получить правильный размер подвидов. Но если вы ничего не делаете, layoutSubviews будет вызываться после viewDidAppear. Это зависит от вашего кода.
в viewWillAppear()
просто вызовите layoutIfNeeded () один раз для представления, кадр которого вы хотите получить.
Если tableView, то tableView.layoutIfNeeded() для exmple