1. ホーム
  2. iphone

[解決済み] viewWillAppear: と viewDidAppear の間でビューフレームが変化する。

2023-05-13 20:58:10

質問

私のアプリケーションで奇妙な挙動を発見しました。 IBOutlet への呼び出しの間にその接続されたビューのフレームがある、という奇妙な挙動を発見しました。 viewWillAppear:viewDidAppear: . 以下は、私の UIViewController サブクラスでの関連するコードです。

-(void)viewWillAppear:(BOOL)animated {
    NSLog(@"%@", self.scrollView);
}

-(void)viewDidAppear:(BOOL)animated {
    NSLog(@"%@", self.scrollView);
}

と、その結果のログ出力です。

MyApp[61880:c07] <UIScrollView: 0x1057eff0; frame = (0 0; 0 0); clipsToBounds = YES; autoresize = TM+BM; gestureRecognizers = <NSArray: 0x10580100>; layer = <CALayer: 0x1057f210>; contentOffset: {0, 0}>
MyApp[61880:c07] <UIScrollView: 0x1057eff0; frame = (0 44; 320 416); clipsToBounds = YES; autoresize = TM+BM; gestureRecognizers = <NSArray: 0x10580100>; layer = <CALayer: 0x1057f210>; contentOffset: {0, 0}>

これは、2つの呼び出しの間でフレームが変化していることを明確に示しています。のビューでセットアップを行いたいと思いました。 viewDidLoad メソッドでビューのセットアップを行いたかったのですが、コンテンツが画面上に表示されるまで私が変更できないのであれば、それはかなり無駄のように思われます。何が起こっているのでしょうか?

どのように解決するのですか?

Autolayout は、ビューの GUI を設計および開発する方法に大きな変化をもたらしました。主な違いの 1 つは autolayout はビューのサイズをすぐに変更するのではなく、トリガーされたとき、つまり特定の時間にのみ変更しますが、制約をすぐに再計算するように強制したり、レイアウトが必要なものとしてマークしたりすることができることです。これは次のように動作します。 -setNeedDisplay .

私にとっての大きな挑戦は、オートサイズ・マスクをもう使う必要がないこと、そしてフレームがビューの配置に無用なプロパティになっていることを理解し、受け入れることでした。ビューの位置について考える必要はもうありませんが、互いに関連する空間でそれらをどのように見たいかを考える必要があります。

旧来のオートレジマスクとオートレイアウトを混在させる場合は、問題が発生するときです。オートレイアウトの実装を早急に検討し、オートレイアウトに基づくビュー階層において、古いアプローチを混在させないようにしなければなりません。

ビューコントローラのメインビューのように、オートサイジングマスクのみを使用するコンテナビューがあっても構いませんが、混在させないようにしたほうがよいでしょう。

ストーリーボードは使ったことがないのですが、おそらく正しいのでしょう。Autolayoutを使用すると、オートレイアウトエンジンが計算を開始するときに、ビューのフレームが設定されます。同じことを - (void)viewDidLayoutSubviews メソッドの super の直後に同じことを聞いてみてください。

このメソッドは、オートレイアウトエンジンがビューのフレームを計算し終えたときに呼び出されます。