SwiftUI:在 launch/enter 前景上显示 "lock screen"?
SwiftUI: Show "lock screen" on launch/enter foreground?
我正在 SwiftUI 中开发一个 iOS 应用程序,它需要 lock/unlock 来自钥匙串的加密密钥才能执行任何操作。我希望在使用应用程序时将这些键保存在内存中,然后在用户切换到另一个应用程序或进入后台时从内存中删除。当应用程序启动或回到前台时,我想提示他们输入密码以解锁密钥。
我过去在使用 UIKit 时做过类似的事情,但这个应用程序是用 SwiftUI 编写的。我的应用程序的根是一个 TabView
,每个选项卡中显示许多其他 View
。我希望这个“锁定屏幕”弹出,而不管当时哪个 View
恰好处于活动状态。我知道我可以在 UIApplicationDelegate 中订阅许多 Notification
。这可以处理从内存中删除密钥的任务。我不知道如何在当时可能处于活动状态的任何其他 View
之上显示锁定屏幕 View
。
是否有“标准”SwiftUI 方法来完成此操作?我想尽可能地遵守 SwiftUI 最佳实践,但还没有看到任何关于如何做这样的事情的好例子。
最简单的版本是使用 if/else
块根据 @State
变量有条件地显示锁定屏幕:
struct ContentView: View {
@State var showLock = false
var body: some View {
Group {
if showLock {
Text("Locked")
} else {
Text("Tab view here")
}
}.onReceive(NotificationCenter.default.publisher(for: UIApplication.willResignActiveNotification)) { _ in
showLock = true
}
}
}
上述方法的缺点是,当显示锁定屏幕时,您可能会丢失选项卡视图中的某些状态。
要保持选项卡视图加载并保持您的状态,您可以使用显示在其他内容之上的 fullScreenCover
:
struct ContentView: View {
@State var showLock = false
var body: some View {
Text("Tab view here")
.fullScreenCover(isPresented: $showLock) {
VStack {
Text("Locked")
Button("Hide") {
showLock = false
}
}
}
.onReceive(NotificationCenter.default.publisher(for: UIApplication.willResignActiveNotification)) { _ in
showLock = true
}
}
}
显然,存储状态 (locked/unlocked) 的位置无关紧要——您可以将其存储在 ObservableObject
、环境键等中——SwiftUI 可以看到它更新的任何地方。获取 background/foreground 通知的策略相同——任何设置状态的策略都是可行的。
我正在 SwiftUI 中开发一个 iOS 应用程序,它需要 lock/unlock 来自钥匙串的加密密钥才能执行任何操作。我希望在使用应用程序时将这些键保存在内存中,然后在用户切换到另一个应用程序或进入后台时从内存中删除。当应用程序启动或回到前台时,我想提示他们输入密码以解锁密钥。
我过去在使用 UIKit 时做过类似的事情,但这个应用程序是用 SwiftUI 编写的。我的应用程序的根是一个 TabView
,每个选项卡中显示许多其他 View
。我希望这个“锁定屏幕”弹出,而不管当时哪个 View
恰好处于活动状态。我知道我可以在 UIApplicationDelegate 中订阅许多 Notification
。这可以处理从内存中删除密钥的任务。我不知道如何在当时可能处于活动状态的任何其他 View
之上显示锁定屏幕 View
。
是否有“标准”SwiftUI 方法来完成此操作?我想尽可能地遵守 SwiftUI 最佳实践,但还没有看到任何关于如何做这样的事情的好例子。
最简单的版本是使用 if/else
块根据 @State
变量有条件地显示锁定屏幕:
struct ContentView: View {
@State var showLock = false
var body: some View {
Group {
if showLock {
Text("Locked")
} else {
Text("Tab view here")
}
}.onReceive(NotificationCenter.default.publisher(for: UIApplication.willResignActiveNotification)) { _ in
showLock = true
}
}
}
上述方法的缺点是,当显示锁定屏幕时,您可能会丢失选项卡视图中的某些状态。
要保持选项卡视图加载并保持您的状态,您可以使用显示在其他内容之上的 fullScreenCover
:
struct ContentView: View {
@State var showLock = false
var body: some View {
Text("Tab view here")
.fullScreenCover(isPresented: $showLock) {
VStack {
Text("Locked")
Button("Hide") {
showLock = false
}
}
}
.onReceive(NotificationCenter.default.publisher(for: UIApplication.willResignActiveNotification)) { _ in
showLock = true
}
}
}
显然,存储状态 (locked/unlocked) 的位置无关紧要——您可以将其存储在 ObservableObject
、环境键等中——SwiftUI 可以看到它更新的任何地方。获取 background/foreground 通知的策略相同——任何设置状态的策略都是可行的。