LoginSignup
2
2

More than 5 years have passed since last update.

viewDidLoadで画面遷移をしてないのに、「Unbalanced calls to begin/end appearance transitions」エラーが出る時

Last updated at Posted at 2018-06-26

エラー状況

Unbalanced calls to begin/end appearance transitionsエラーでぐぐると、「viewDidLoadviewWillAppear内で画面遷移をしているのが原因」なパターンが多くヒットする。
が、それをしていないのに起きる時のはなし。

エラーが発生したコード

簡略版。こんな感じのコードで起きた。

class ViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        getTimeline() // サーバーから取得したデータをもとに、非同期でViewをreloadする
    }

    // 子のViewControllerを返す処理。
    // XLPagerTabStripというライブラリを使用してます。
    override func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] {
        return [hogeVC(),fugaVC()]
    }
}

ポイントは2つ。
- ViewController内に、ContainerViewでViewControllerの子供を持つ
- viewDidLoad内で通信処理を呼び出し、その中でViewを更新している

そもそもこのエラーの原因は?

Unbalanced calls to begin/end appearance transitionsは、親のViewControllerの表示が確定していない状態で、子のViewControllerを扱うことで生じる ことがほとんど。

よって、先の例で言えばgetTimeline()が元凶である。
なぜなら、viewDidLoadを抜けた後にViewのreloadが走り、それが終わることで初めて表示が確定する仕様になっており、その確定の前にviewControllersが呼ばれてしまうから。

解決策

非同期でViewを更新する処理を、viewDidAppearに移す。
先の例で言えば、こうすれば解決する。

class ViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        getTimeline() // サーバーから取得したデータをもとに、非同期でViewをreloadする
    }

    override func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] {
        return [hogeVC(),fugaVC()]
    }
}

ただし、Appear後に非同期処理を開始するのが不満な場合は、異なる策をとる必要がある。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2