43

サブビューのフレームを設定したときに変更が画面に反映されない理由を誰かが知っているのではviewDidLoadないかと思いviewWillAppearましたが、設定した場合は影響しviewDidAppearますか?

私の場合、2つのテーブルビューを含むカスタム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;
}
4

3 に答える 3

100

viewDidLoadは、クラスがロードされたときに呼び出されますが、UI要素が初期化されていないため、それらを参照しようとすると、viewDidLoad呼び出しとviewDidAppear呼び出しの間で発生する初期化プロセス中に上書きまたは使用できなくなります。すべてのUI要素が初期化され、描画されると、viewDidAppearが呼び出されます。

viewDidLoad-コントローラのビューがメモリにロードされた後に呼び出されます

この時点で、ビューはビュー階層内にありません。

viewWillAppear-ビューがビュー階層に追加されようとしていることをViewControllerに通知します。

この場合も、ビューはまだビュー階層に追加されていません。

viewDidAppear-ビューがビュー階層に追加されたことをViewControllerに通知します。

その場合にのみ、ビューがビュー階層に追加されます。

アップデート

viewDidLayoutSubviewsUIが実際に画面に表示される前に、UIを変更するのに最も適切な場所です。

viewDidLayoutSubviews-ビューがサブビューをレイアウトしたことをViewControllerに通知します。

于 2012-10-26T00:44:15.737 に答える
2

このスレッドを参照してくださいlayoutSubviewsはいつ呼び出されますか?
自動レイアウトを使用する場合、フレームワークはlayoutSubviewsを自動的に呼び出しません。それは非常に重要です。参照から:

  • initによってlayoutSubviewsが呼び出されることはありません(duh)
  • addSubview:追加されるビュー、追加されるビュー(ターゲットビュー)、およびターゲットのすべてのサブビューでlayoutSubviewsが呼び出されるようにします。..。


viewDidLoadにサブビューを追加すると、viewDidAppearの前にlayoutSubviewsが呼び出され、正しいサイズのサブビューを取得できます。ただし、何もしないと、viewDidAppearの後にlayoutSubviewsが呼び出されます。それはあなたのコード次第です。

于 2015-08-03T00:40:26.977 に答える
0

viewWillAppear()で

フレームを取得するビューに対してlayoutIfNeeded()を1回呼び出すだけです。

tableViewの場合、exmpleのtableView.layoutIfNeeded()

于 2017-03-02T10:05:26.073 に答える