サブビューのフレームをviewDidLoad
およびviewWillAppear
に設定したときに、変更が画面に反映されない理由を誰かが知っているのではないかと思っていましたが、viewDidAppear
に設定すると?
私の場合、私は2つのTableViewを備えたカスタムxibをロードし、viewDidLoad
でそれらをシフトダウンして、viewDidLoad
に追加される別のビューのためのスペースを許可しようとしています。
問題は、フレームを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;
}
クラスがロードされるときにviewDidLoadが呼び出されますが、UI要素は初期化されていないため、それらを参照しようとすると、viewDidLoad呼び出しとviewDidAppear呼び出しの間に発生する初期化プロセス中に上書きされます。すべてのui要素が初期化され、描画されると、viewDidAppearが呼び出されます。
viewDidLoad-コントローラーのビューがメモリにロードされた後に呼び出されます
この時点では、ビューはビュー階層内にありません。
viewWillAppear-ビューがビュー階層に追加されようとしていることをView Controllerに通知します。
繰り返しますが、ビューはまだビュー階層に追加されていません。
viewDidAppear-ビューがビュー階層に追加されたことをView Controllerに通知します。
その場合にのみ、ビューがビュー階層に追加されます。
更新
viewDidLayoutSubviews
は、実際に画面に表示される前にUIを変更する最も適切な場所です。
viewDidLayoutSubviews-ビューがサブビューをレイアウトしたことをView Controllerに通知します。
このスレッドを参照してください layoutSubviewsはいつ呼び出されますか?
autolayoutを使用する場合、フレームワークはlayoutSubviewsを自動的に呼び出しません。それは非常に重要です。 refから:
viewDidLoadにサブビューを追加すると、viewDidAppearの前にlayoutSubviewsが呼び出され、サブビューの正しいサイズを取得できます。ただし、何もしないと、viewDidAppearの後にlayoutSubviewsが呼び出されます。あなたのコード次第です。
viewWillAppear()で
フレームを取得するビューに対して一度だけlayoutIfNeeded()を呼び出します。
if tableView then tableView.layoutIfNeeded()for exmple