「autoLayoutってなんじゃー!つかいもんにならんわー!」
と、そんなふうに思っていた時期が僕にもありました。(笑)
使い慣れてみるとケッコー便利です。\(^o^)/
さて、そんな便利なautoLayoutですが、一つ困ったことが。
画面のサイズが決定して、それをもとに%などでサイズが決まって形状を変えたいときなどどの段階で処理するかが問題なのです。
viewControllerで描画に関連しそうなメソッドのライフサイクルはこんな感じかな?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
//ライフサイクル override func viewDidLoad() { super.viewDidLoad() //初回の表示時に一度だけ呼ばれる。 //初期値の読み込みなどに使ってる。 } override func viewWillAppear(animated: Bool) { super.viewWillAppear(animated) //他のビューから戻ってきたときなどビューが表示される直前に毎回呼ばれる //毎回呼ばれるので他のページで設定した値を反映させたりする。 } override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() //レイアウトが始まる直前に毎回呼ばれる。 //ビューが表示された時だけでなく回転時などにも呼ばれる。 //使いみちわからん。w } override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() //レイアウトが終わった直後に毎回呼ばれる。 //ビューが表示された時だけでなく回転時などにも呼ばれる。 } override func viewDidAppear(animated: Bool) { super.viewDidAppear(animated) //他のビューから戻ってきたときなどのビューが表示された直後に毎回呼ばれる。 //ビューが表示されてすぐにしたい処理などに向いている。 } |
さて、autoLayoutでのレイアウトが決定しているのがviewDidLayoutSubviews以降です。
それ以前は値が決定しておらず、autoLayoutで決まる値を参照にするとおかしなことになる可能性が高いです。
viewDidLayoutSubviewsを知る前はviewDidAppearにその処理を書いていました。
しかし、ビューが描画されたあとなので、一瞬描き変えられるところが見えたりします。/(^o^)\
また、毎回他のビューから戻ってきてビューが表示されるたびに同じ処理を繰り返してしまいます。
レイアウトが決まってビューが表示される直前のviewDidLayoutSubviewsなら描き変えられるところは表示されませんが、
こちらはビューの切り替わりだけでなくビューが回転したりイベントあるたびに呼ばれてしまうようです。
で、本題。
結局やりたいのはviewDidLayoutSubviewsで一回だけ処理をさせるということ。
いろいろと調べてこちらのサイトが参考になりました。
[Swift] viewDidLayoutSubviewsで初回だけ処理をしたい | 黒ごまのおむすび
Lazyというのをつかうらじいです。/(^o^)\
1 2 3 4 5 6 7 8 9 |
override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() _ = self.initViewLayout } private lazy var initViewLayout : Void = { print(self.view.frame) //ここに処理したいメソッドをかいていく。 }() |
この処理だとビューの表示前に一回だけ呼び出すことができました。
他の人はこんな場合どうしているんだろう?
うじゃうじゃ。/(^o^)\