🚨
iOS15でSwiftUIのAlertを連続で定義できない問題が解決していた
概要
iOS16が出ましたね。経験上、多くの企業は大体最新のOSバージョンから2バージョンまでをサポートする傾向にあると思うのでそろそろiOS15以降をターゲットにしたアプリも増えてくる頃だと思います。
SwiftUIでは下のように同じViewに連続して .alert
Modifierをつけると片方のアラートが表示されないというバグが存在していました。しかし、この記事の結論でもありますが、iOS15以降から使える .alert
系のModifierを使うとこのバグを回避できます。iOS15以降のサポートになったらそれらを使っていきましょう。
struct ContentView: View {
@State private var isPresented1 = false
@State private var isPresented2 = false
var body: some View {
VStack(spacing: 20) {
Button {
isPresented1 = true
} label: {
Image(systemName: "globe")
.imageScale(.large)
.foregroundColor(.accentColor)
Text("Button 1")
}
Button {
isPresented2 = true
} label: {
Image(systemName: "globe")
.imageScale(.large)
.foregroundColor(.accentColor)
Text("Button 2")
}
}
.padding()
.alert(isPresented: $isPresented1) {
Alert(title: Text("Alert 1"))
}
.alert(isPresented: $isPresented2) {
Alert(title: Text("Alert 2"))
}
}
}
私の環境では後半の Alert 2
は表示されますが Alert 1
は表示されない動きになります。この記事には書きませんがこれには色々なワークアラウンドがありました。ただ、先ほど使っていた .alert
Modifierはdeprecatedになっており、iOS15以降では違うAPIが用意されています。例えばこれ。この他にもerrorに特化したものなどalertのModifierなどModifierの種類自体も増えalert周辺の機能が充実しました
そして、iOS15以降からサポートされている .alert
Modifierではどうやら前述した連続して
.alert Modifierをつけると片方のアラートが表示されないというバグ
は修正済みのようです。先ほどのコードを新しいAPIで書き直した一例が下記のようになります。 Alert 1
も Alert 2
も表示できることが確認できます。
struct ContentView: View {
@State private var isPresented1 = false
@State private var isPresented2 = false
var body: some View {
VStack(spacing: 20) {
Button {
isPresented1 = true
} label: {
Image(systemName: "globe")
.imageScale(.large)
.foregroundColor(.accentColor)
Text("Button 1")
}
Button {
isPresented2 = true
} label: {
Image(systemName: "globe")
.imageScale(.large)
.foregroundColor(.accentColor)
Text("Button 2")
}
}
.padding()
.alert("Alert 1", isPresented: $isPresented1, actions: {
Button("OK", action: { })
})
.alert("Alert 2", isPresented: $isPresented2, actions: {
Button("OK", action: { })
})
}
}
まとめ
iOS15以降がターゲットになったら新しい .alert
に置き換えましょう
おしまい \(^o^)/
Discussion
助かりました。
deprecatedなAPIのほうでは相変わらず同じバグがあるんですね。
ですね。iOS14から残っているalertの方ではバグがOSに関わらず残っています