SwiftUI 超时警报警告然后超时
SwiftUI Timeout Alert Warning Then Timed Out
我设置了一个计时器来显示两个警报。第一个警报向用户显示一个警告,上面写着“嘿,你已经有一段时间没有活动了,你还在这里吗”,如果他们点击是,它就会重置计时器。如果他们不点击警报按钮,则在 x 时间后显示第二个警报,通知他们他们的会话已过期。他们点击“确定”,然后离开导航视图并返回主页。
一切正常,但是 XCode 抛出以下错误:
[Presentation] Attempt to present <SwiftUI.PlatformAlertController: 0x7fc2fa031800> on <_TtGC7SwiftUI19UIHostingControllerGVS_15ModifiedContentVS_7AnyViewVS_12RootModifier__: 0x7fc2e9f05530> (from <_TtGC7SwiftUI19UIHostingControllerGVS_15ModifiedContentVS_7AnyViewVS_24NavigationColumnModifier__: 0x7fc309f28e80>) which is already presenting <SwiftUI.PlatformAlertController: 0x7fc2ea842000>.
据我了解,这就是说,已经显示了一条警报,即使我要关闭它并显示您的其他警报,我也会对此进行投诉,这告诉我我'我做错了什么。我想确保我做的是正确的,这样我就不会在 XCode 的控制台中收到这个错误。
创建计时器后,我正在使用 onReceive 观看它:
.onReceive(timer) { time in
if userTimeout == true {
timer.upstream.connect().cancel()
} else {
caWarning()
caTimeout()
}
}
两个函数真的很简单:
func caWarning() {
if Date.now >= userActivity.addingTimeInterval(5*1) {
userActivityAlert = true
}
}
func caTimeout() {
if Date.now >= userActivity.addingTimeInterval(10*1) {
userActivityAlert = false
userTimeout = true
}
}
最后,我的警报 if 语句是:
if userActivityAlert == true {
VStack {
EmptyView()
}
.alert("Foo", isPresented: $userActivityAlert, actions: {
Button("I'm Here") {
userActivity = Date.now
}
}, message: { Text("Are you still there?") }
) // End show alert
} else if UserTimeout == true {
VStack {
EmptyView()
}
.alert("Foo", isPresented: $userTimeout, actions: {
Button("OK") {
self.caRegExpired.navToHome = true
}
}, message: {
Text("Your session has expired.\nTap OK, to start over.")
}) // End Alert
} // End If
能想到的我都试过了。从 @Environment (\.dismiss) var dismiss
然后调用 dismiss()
(关闭底层视图而不是警报),到浏览 Apple 的文档和旧的 UIKit 东西(没有帮助)。
我可以这样做(即两个单独的警报)或者能够在一段时间后将第一个警报修改为第二个警报(甚至可能显示倒计时,直到用户会话结束)已过期)。
老实说,我想知道这是否只是记录噪音,因为第一个警报消失了,而第二个警报完全正常显示。从字面上看,这一切都很好,但重要的是要解决错误,我想知道我是否做错了什么。
这是针对最新的 SwiftUI 5+,XCode 是针对 iOS 15+
@loremipsum 的 link 给出了答案:在停用第一个警报和显示第二个警报之间稍等片刻:
struct ContentView: View {
let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
@State private var userActivityAlert = false
@State private var userTimeout = false
@State private var userActivity = Date.now
var body: some View {
VStack {
Text("Hello, World!")
.alert("Foo", isPresented: $userActivityAlert, actions: {
Button("I'm Here") {
userActivity = Date.now
}
}, message: { Text("Are you still there?") }
) // End show alert
Text("Hello, World!")
.alert("Foo", isPresented: $userTimeout, actions: {
Button("OK") {
// self.caRegExpired.navToHome = true
}
}, message: {
Text("Your session has expired.\nTap OK, to start over.")
}) // End Alert
}
.onReceive(timer) { time in
if userTimeout == true {
timer.upstream.connect().cancel()
} else {
caWarning()
caTimeout()
}
}
}
func caWarning() {
if Date.now >= userActivity.addingTimeInterval(5*1) {
userActivityAlert = true
}
}
func caTimeout() {
if Date.now >= userActivity.addingTimeInterval(10*1) {
userActivityAlert = false
//This delay leaves a little gap between alerts
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
userTimeout = true
}
}
}
}
我设置了一个计时器来显示两个警报。第一个警报向用户显示一个警告,上面写着“嘿,你已经有一段时间没有活动了,你还在这里吗”,如果他们点击是,它就会重置计时器。如果他们不点击警报按钮,则在 x 时间后显示第二个警报,通知他们他们的会话已过期。他们点击“确定”,然后离开导航视图并返回主页。
一切正常,但是 XCode 抛出以下错误:
[Presentation] Attempt to present <SwiftUI.PlatformAlertController: 0x7fc2fa031800> on <_TtGC7SwiftUI19UIHostingControllerGVS_15ModifiedContentVS_7AnyViewVS_12RootModifier__: 0x7fc2e9f05530> (from <_TtGC7SwiftUI19UIHostingControllerGVS_15ModifiedContentVS_7AnyViewVS_24NavigationColumnModifier__: 0x7fc309f28e80>) which is already presenting <SwiftUI.PlatformAlertController: 0x7fc2ea842000>.
据我了解,这就是说,已经显示了一条警报,即使我要关闭它并显示您的其他警报,我也会对此进行投诉,这告诉我我'我做错了什么。我想确保我做的是正确的,这样我就不会在 XCode 的控制台中收到这个错误。
创建计时器后,我正在使用 onReceive 观看它:
.onReceive(timer) { time in
if userTimeout == true {
timer.upstream.connect().cancel()
} else {
caWarning()
caTimeout()
}
}
两个函数真的很简单:
func caWarning() {
if Date.now >= userActivity.addingTimeInterval(5*1) {
userActivityAlert = true
}
}
func caTimeout() {
if Date.now >= userActivity.addingTimeInterval(10*1) {
userActivityAlert = false
userTimeout = true
}
}
最后,我的警报 if 语句是:
if userActivityAlert == true {
VStack {
EmptyView()
}
.alert("Foo", isPresented: $userActivityAlert, actions: {
Button("I'm Here") {
userActivity = Date.now
}
}, message: { Text("Are you still there?") }
) // End show alert
} else if UserTimeout == true {
VStack {
EmptyView()
}
.alert("Foo", isPresented: $userTimeout, actions: {
Button("OK") {
self.caRegExpired.navToHome = true
}
}, message: {
Text("Your session has expired.\nTap OK, to start over.")
}) // End Alert
} // End If
能想到的我都试过了。从 @Environment (\.dismiss) var dismiss
然后调用 dismiss()
(关闭底层视图而不是警报),到浏览 Apple 的文档和旧的 UIKit 东西(没有帮助)。
我可以这样做(即两个单独的警报)或者能够在一段时间后将第一个警报修改为第二个警报(甚至可能显示倒计时,直到用户会话结束)已过期)。
老实说,我想知道这是否只是记录噪音,因为第一个警报消失了,而第二个警报完全正常显示。从字面上看,这一切都很好,但重要的是要解决错误,我想知道我是否做错了什么。
这是针对最新的 SwiftUI 5+,XCode 是针对 iOS 15+
@loremipsum 的 link 给出了答案:在停用第一个警报和显示第二个警报之间稍等片刻:
struct ContentView: View {
let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
@State private var userActivityAlert = false
@State private var userTimeout = false
@State private var userActivity = Date.now
var body: some View {
VStack {
Text("Hello, World!")
.alert("Foo", isPresented: $userActivityAlert, actions: {
Button("I'm Here") {
userActivity = Date.now
}
}, message: { Text("Are you still there?") }
) // End show alert
Text("Hello, World!")
.alert("Foo", isPresented: $userTimeout, actions: {
Button("OK") {
// self.caRegExpired.navToHome = true
}
}, message: {
Text("Your session has expired.\nTap OK, to start over.")
}) // End Alert
}
.onReceive(timer) { time in
if userTimeout == true {
timer.upstream.connect().cancel()
} else {
caWarning()
caTimeout()
}
}
}
func caWarning() {
if Date.now >= userActivity.addingTimeInterval(5*1) {
userActivityAlert = true
}
}
func caTimeout() {
if Date.now >= userActivity.addingTimeInterval(10*1) {
userActivityAlert = false
//This delay leaves a little gap between alerts
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
userTimeout = true
}
}
}
}