LoginSignup
1
2

More than 5 years have passed since last update.

Swift, iOS:ナビゲーションバーにビューを重ねる方法

Last updated at Posted at 2018-03-01

背景

iOSでUINavigationBar(ナビゲーションバー)を使ったユーティリティアプリを作っている時、モーダルを表示する時に画面全体に半透明グレーのビューを重ねたくなるときがありました.
ナビゲーションバーにビューを重ねる方法で調べると、何やら結構厄介なことをしてそうだったので、簡単にできる方法はないかと模索した結果を備忘録的に書き記しておきます.
(ついでに、ビューをフェードで重ねる方法も書いておきます.)

ソースコード(説明入り)

ExampleViewController
class ExampleViewController: UIViewController {
    let naviFadeView = UIView() //ナビゲーションバーの上にだけ重ねるビュー
    let mainFadeView = UIView() //メインコンテンツの上に重ねるビュー

    override func viewDidLoad() {
        super.viewDidLoad()

        //★★★ナビゲーションバーの上に重ねるビューの初期設定★★★
        //ナビゲーションバーの高さを取得
        let naviH: CGFloat = UIApplication.shared.statusBarFrame.height + self.navigationController!.navigationBar.frame.height
        //ビューのframeを設定
        naviFadeView.frame = CGRect(origin: CGPoint.zero, size: CGSize(width: self.view.frame.width, height: naviH))
        //ナビゲーションバーにビューを追加
        self.navigationController!.view.addSubview(naviFadeView)
        //ビューを隠しておく
        naviFadeView.isHidden = true
        //ビューの色設定(ここでは半透明の黒)
        naviFadeView.backgroundColor = UIColor(hex: "000000", alpha: 0.5)
        //フェードアニメーションのためにalphaも設定
        naviFadeView.alpha = 0.0

        //★★★メインコンテンツの上に重ねるビューの初期設定★★★
        //ビューのframeを設定
        mainFadeView.frame = CGRect(origin: CGPoint.zero, size: self.view.frame.size)
        //メインビューにビューを追加
        self.view.addSubview(mainFadeView)
        //ビューを最前面にする
        self.view.bringSubview(toFront: mainFadeView)
        //ビューを隠しておく
        mainFadeView.isHidden = true
        //ビューの色設定(ここでは半透明の黒)
        mainFadeView.backgroundColor = UIColor(hex: "000000", alpha: 0.5)
        //フェードアニメーションのためにalphaも設定
        mainFadeView.alpha = 0.0
    }

    //ビューをフェードイン
    func fadeIn() {
        mainFadeView.isHidden = false
        naviFadeView.isHidden = false
        //タイマーでアニメーション(UIView.animateでも可)
        Timer.scheduledTimer(withTimeInterval: 0.02, repeats: true, block: { (t) in
            if self.mainFadeView.alpha < 1.0 {
                self.mainFadeView.alpha += 0.05
                self.naviFadeView.alpha += 0.05
            } else {
                t.invalidate()
            }
        })
    }

    //ビューをフェードアウト
    func fadeOut() {
        //タイマーでアニメーション(UIView.animateではうまくいかなかった)
        Timer.scheduledTimer(withTimeInterval: 0.02, repeats: true, block: { (t) in
            if self.mainFadeView.alpha > 0.0 {
                self.mainFadeView.alpha -= 0.05
                self.naviFadeView.alpha -= 0.05
            } else {
                t.invalidate()
                self.mainFadeView.isHidden = true
                self.naviFadeView.isHidden = true
            }
        })
    }
}

解説

ナビゲーションバーはメインビューよりも上層(手前)のレイヤーに存在するようで、単純にビューを最前面に持ってくるだけでは覆いかぶせることができません。
AppDelegate経由でUIWindowにビューを追加する方法とか、ナビゲーションバーのlayer.zPosition-1にしちゃうとか色々やりようがあるみたいですが、ViewControllerに処理が収まらないのは嫌だし、zPositionをマイナスにするとナビゲーションバーそのものが消えてしまいます。
そこで、一枚のビューに見せかければ良いのでは?というひらめきで実装してみました。
やっていることは簡単でナビゲーションバーに被せる用のビューとメインビューに被せる用のビューを用意してそれぞれの上に被せるだけです.色や透明度を同じにしたら、2つのビューの境目は全くわかりませんし、ユーザに気づかれることはないでしょう。

1
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
1
2