😇
【iOS】フォアグラウンド状態を検知する際のScenePhaseとonChange(of:)のハマりポイント
アプリの状態がフォアグラウンド、バックグラウンドになっているを検知する時にScenePhase
とonChange(of:)
を使用して状態の変化をみることがあると思うのですが、少しハマってしまったのでハマったポイントを共有しておきたいと思います。
環境
- Xcode 14.2
- iOS 16.2
@StateとonChangeの場合
下記のコードで試してみます。
struct ContentView: View {
@State private var text = ""
var body: some View {
VStack {
TextField("Input Text here..", text: $text)
Divider()
}
.padding()
.onChange(of: text) { newValue in
print("text", text)
print("newValue", newValue)
}
}
}
TexFieldに1
を入力してみます。
結果
text
とnewValue
の値ともに1
という新しい値になっているのを確認出来ました。
.onChange(of: text) { newValue in
print("text", text) // text 1
print("newValue", newValue) // newValue 1
}
新旧の値を確認する方法
下記のような記述にすることで、変わる前の値と変わった後の値を検知できます。
出力結果は、上記と同じようにTextFieldに1
を入力した際の出力例です。
.onChange(of: text) { [text] newValue in
print("text", text) // text
print("newValue", newValue) // newValue 1
}
text
のprint
ログは空文字になっており、1
が入力される前の値を取得できています。
SceneStateとonChangeの場合
下記のコードで試してみます。
struct ContentView: View {
@Environment(\.scenePhase) var scenePhase
var body: some View {
Text("ScenePhace")
.onChange(of: scenePhase) { newValue in
print("scenePhase", scenePhase)
print("newValue", newValue)
}
}
}
結果
アプリを起動した際の出力結果です。
.onChange(of: scenePhase) { newValue in
print("scenePhase", scenePhase) // scenePhase inactive
print("newValue", newValue) // newValue active
}
scenePhase
の出力が状態が変わる前の値inactive
になっています。
ScenePhase
の場合、デフォルトで新旧の値を確認する方法で試したような状態になっているようです。
下記のようなコードに変更して、出力結果を確認しても結果は同じでした。
.onChange(of: scenePhase) { [scenePhase] newValue in
print("scenePhase", scenePhase) // scenePhase inactive
print("newValue", newValue) // newValue active
}
おわりに
アプリのフォアグラウンド、バックグラウンド状態を検知する為にScenePhase
とonChange(of:)
を組みあわえて使用する際は、newValue
の値を使用して分岐させる必要がありますので注意しましょう。
というか、基本的にはnewValue
側の値を使用するように心がけたいと思います。
参考
Discussion