ハーフモーダルを実装する
メインのビューから別のビューを表示するときに、上部にすこしだけメインビューが見えて、それに重なるように別のビューが表示されている場合がありますが、それがハーフモーダルと称される動作です。
完全に別のビューがメインビューを覆ってしまうと操作が混乱するときなどに使い勝手があります。画像処理アプリケーションのパラメータ設定を別のビューで実施するときに便利かもしれません。
メインビューのコード
通常のモーダルビュー表示に、.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()
}
}