ハーフモーダルを実装する

メインのビューから別のビューを表示するときに、上部にすこしだけメインビューが見えて、それに重なるように別のビューが表示されている場合がありますが、それがハーフモーダルと称される動作です。

完全に別のビューがメインビューを覆ってしまうと操作が混乱するときなどに使い勝手があります。画像処理アプリケーションのパラメータ設定を別のビューで実施するときに便利かもしれません。

Fig. 1 メインのビュー
Fig. 2 モーダルビュー25%
Fig. 3 モーダルビュー50%
Fig. 4 モーダルビュー75%

メインビューのコード

通常のモーダルビュー表示に、.presentationDetents というモディファイアを追加するだけです。覆う割合を .fraction で 1.0 までの割合で指定します。1.0 にすると完全に覆って裏側のメインのビューは見えません。

ここでひとつハマるところなのですが、FlagShowModal025、FlagShowModal050、FlagShowModal075 は、ひとつのフラグだけでいけそうな気がしますが、これは三つのフラグをそれぞれ立てなければなりません。

理屈はよくわかりませんが、仮にこのフラグを FlagShowModal として一つにしてしまうと、一番最初に(コードの一番上に)記述した .presentationDetents モディファイアの .fraction の設定を優先してしまうようです。( ぜんぶ推測ですいません )

フラグとして true/false の情報だけでいけそうな気もするのですが @State なので、なにか別の管理もしているのでしょう。

モーダルビューの表示割合を変化させたいというシチュエーションはそんなに多くないと思うので、この仕様でハマらないようにお知らせしておきます。

import SwiftUI

struct ContentView: View {

    let BTN_W = 160.0
    let BTN_H =  40.0
    let BTN_R =   8.0

    @State var FlagShowModal025 = false
    @State var FlagShowModal050 = false
    @State var FlagShowModal075 = false

    var body: some View {

        ZStack {

            Color( .green )

            VStack {

                Button( action: {
                    FlagShowModal025 = true
                }, label: {
                    Text( "25%" )
                        .font( .system( size: 40.0 ))
                })
                .sheet( isPresented: $FlagShowModal025 ) {
                    ViewInformation()
                    .presentationDetents([ .fraction( 0.25 ) ])
                }

                Button( action: {
                    FlagShowModal050 = true
                }, label: {
                    Text( "50%" )
                        .font( .system( size: 40.0 ))
                })
                .sheet( isPresented: $FlagShowModal050 ) {
                    ViewInformation()
                    .presentationDetents([ .fraction( 0.50 ) ])
                }

                Button( action: {
                    FlagShowModal075 = true
                }, label: {
                    Text( "75%" )
                        .font( .system( size: 40.0 ))
                })
                .sheet( isPresented: $FlagShowModal075 ) {
                    ViewInformation()
                    .presentationDetents([ .fraction( 0.75 ) ])
                }



            }
        }

    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

モーダルビューのコード

こっちは呼ばれるほうのコードなので特に難しいことはありません。

import SwiftUI

struct ViewInformation: View {
    var body: some View {

        ZStack {

            Color( .cyan )

            Text( "This view is information" )
                .font( .system( size: 36.0 ))
                .foregroundColor( .black )

        }

    }
}

struct ViewInformation_Previews: PreviewProvider {
    static var previews: some View {
        ViewInformation()
    }
}