🐕

iOS18未満のSwiftUI .alert のButton.disable()のバグ

2025/01/17に公開

alert内にTextFieldを持たせる場合にTextFieldの文字列によってalertのボタンを.disabled(_:)するパターンがあると思うがiOS18未満では正しく動作しないようだった

コード例
import SwiftUI

struct ContentView: View {
    @State var alertPresented = false
    @State var alertEnabled = false
    @State var alertText = ""

    var body: some View {
        VStack {
            Button("alert表示") {
                alertPresented = true
            }
        }.frame(width: 300, height: 300)
        .alert(
            "入力してください",
            isPresented: $alertPresented,
            actions: {
                TextField("", text: $alertText)
                    .onChange(of: alertText) {
                        alertEnabled = (1...10).contains(alertText.count)
                    }
                Button("完了") { alertPresented = false }
                    .disabled(!alertEnabled)
                Button("キャンセル", role: .cancel) {}
            }
        )
    }
}

動作確認結果

ビルド環境はXode16.1/Swift5.10

  • ❌iOS16
    • .disabled() 自体が正しく動かない
    • 初期状態で .disable(true) だとボタン自体が表示されなくなる
    • .disabled(false) から.disabled(true) にしても、ボタンはdisableにならない(enableなまま)
  • ❌iOS17
    • 初期状態 .disable(true) の場合のみ不具合が発生
    • 初期状態 .disable(true) から .disabled(false)(enable)になってもボタンタップの処理(action)が呼ばれない😭
  • ⭕️iOS18
    • .disable() が正常に動いてそう
    • iOS18.0, 18.1, 18.2で動作確認済み

参考

https://forums.developer.apple.com/forums/thread/737964

MIXI DEVELOPERS Tech Blog

Discussion