LoginSignup
3
3

More than 3 years have passed since last update.

処理中にNavigationBarのボタン操作を無効にする。

Posted at

まくら

Navigation Controller を使ったアプリを作っている時に、稀によくある問題に対するアプローチです。

例えばこんな場合

  • とある画面で時間のかかる処理中に読み込み中のインジケータを出したい
  • インジケータが出ている間はナビゲーションバーの操作(戻るボタンとか)を無効にしたい

インジケータを出すのはいいとして、操作を無効にする方法はいくつか思いつきますが、今回は前面に目隠しを出して操作できないようにしてみましょう。

ほんだい

まずはソースをどうぞ。
インジケータを表示する部分です。


    // インジケータを表示する
    private func showIndicator() {

        // 背景になるView
        let backView = UIView()
        backView.backgroundColor = UIColor.init(white: 0.0, alpha: 0.5)
        backView.tag = 12345 // 消す時用にタグを付けておく

        // インジケータ
        let indicator = UIActivityIndicatorView()
        indicator.activityIndicatorViewStyle = .whiteLarge
        indicator.frame = CGRect(x: 0, y: 0, width: 100, height: 100)

        // NavigationControllerのViewを使う
        guard let naviView = self.navigationController?.view else {
            return
        }

        // 背景にインジケータを貼り付け
        backView.addSubview(indicator)

        // 背景をNavigationControllerのViewに貼り付け
        naviView.addSubview(backView)

        // サイズ合わせはAutoLayoutで
        backView.translatesAutoresizingMaskIntoConstraints = false
        backView.topAnchor.constraint(equalTo: naviView.topAnchor).isActive = true
        backView.bottomAnchor.constraint(equalTo: naviView.bottomAnchor).isActive = true
        backView.leftAnchor.constraint(equalTo: naviView.leftAnchor).isActive = true
        backView.rightAnchor.constraint(equalTo: naviView.rightAnchor).isActive = true

        // インジケータもAutoLayout
        indicator.translatesAutoresizingMaskIntoConstraints = false
        indicator.centerXAnchor.constraint(equalTo: backView.centerXAnchor).isActive = true
        indicator.centerYAnchor.constraint(equalTo: backView.centerYAnchor).isActive = true
        indicator.widthAnchor.constraint(equalToConstant: 100).isActive = true
        indicator.heightAnchor.constraint(equalToConstant: 100).isActive = true

        // インジケータ起動
        indicator.startAnimating()
    }

これを適当に実装するとこんな感じになります。

SS 2.png

ポイントはNavigationBarがグレーのViewに覆われていてBarButtonItemが押せない状態になっているところです。

ここですね。

    // NavigationControllerのViewを使う
    guard let naviView = self.navigationController?.view else {
        return
    }
    // 背景をNavigationControllerのViewに貼り付け
    naviView.addSubview(backView)

要は、NavigationController.ViewにもaddSubViewできますよって事ですね。

NavigationControllerの上にViewを貼り付けるので、当然その下のボタン等は押せなくなるわけです。


ちなみに注意点としては、当然ですが、NavigationController.Viewが存在しないと使えません。

prepare for segueの遷移時などNavigationControllerが追いづらい時には正直使いづらいです。



現場からは以上です。

3
3
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
3
3