在 "More" overflow 中显示来自选项卡的警报让我回到之前的视图
Showing alert from a tab in "More" overflow sends me back to the previous view
我有一个简单的操作,在使用 TabView 的 SwiftUI 应用程序中显示警报。但是,每当我第一次显示来自被推送到“更多”溢出屏幕的选项卡的警报时,它会立即将我带回到我之前所在的任何“主选项卡”(非更多)。
这只会在我第一次显示警报时发生,之后它会按预期工作。但是,在所有后续警报中(当它正常运行时)我在控制台中得到这个输出
2021-01-07 12:19:49.289546-0700 Test App[48718:25806605] setViewControllers:animated: called on <UIMoreNavigationController 0x7fcecf826c00> while an existing transition or presentation is occurring; the navigation stack will not be updated.
如果“按钮”选项卡是主要选项卡之一(不在“更多”屏幕上),则不会发生这种情况。
StoreKit 的应用内购买弹出窗口也会发生同样的行为,而不仅仅是我启动的警报。
我该如何解决这个问题?这是 TabView 错误吗?
运行 Xcode 12.3
在模拟器中复制于:iPhone 11,iPhone 12,iPad Pro
复制步骤(使用下面的代码):
- 启动应用程序
- 转到更多 -> 按钮选项卡
- 点击“显示警报”
- 已显示警报,但它后面的视图立即返回到选项卡 One
- 重复相同的步骤,不再发生(必须重新启动应用)
import SwiftUI
struct ContentView: View {
let textTabs = ["One","Two","Three","Four","Five","Six","Seven","Eight"]
var body: some View {
TabView {
ForEach(textTabs, id: \.self) { name in
Text(name).tabItem {
Image(systemName: "circle")
Text(name)
}
}
ButtonTab().tabItem {
Image(systemName: "face.smiling")
Text("Button")
}
}
}
}
struct ButtonTab: View {
@State var showAlert = false
var body : some View {
VStack {
Button("show alert") {
showAlert = true
}
}
.alert(isPresented: $showAlert) {
Alert(title: Text("hello"),
dismissButton: .default(Text("ok")))
}
}
}
一种可能的解决方法是在单击按钮时保持选择:
struct ContentView: View {
let textTabs = ["One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight"]
@State private var selection = "Two" // store selection as a `@State`
var body: some View {
TabView(selection: $selection) {
ForEach(textTabs, id: \.self) { name in
Text(name)
.tabItem {
Image(systemName: "circle")
Text(name)
}
}
ButtonTab(selection: $selection)
.tabItem {
Image(systemName: "face.smiling")
Text("Button")
}
.tag("Button") // add tag for `selection`
}
}
}
struct ButtonTab: View {
@State private var showAlert = false
@Binding var selection: String // pass selection as a `@Binding`
var body: some View {
VStack {
Button("show alert") {
showAlert = true
selection = "Button" // (force) set `selection` here
}
}
.alert(isPresented: $showAlert) {
Alert(title: Text("hello"),
dismissButton: .default(Text("ok")))
}
}
}
我有一个简单的操作,在使用 TabView 的 SwiftUI 应用程序中显示警报。但是,每当我第一次显示来自被推送到“更多”溢出屏幕的选项卡的警报时,它会立即将我带回到我之前所在的任何“主选项卡”(非更多)。
这只会在我第一次显示警报时发生,之后它会按预期工作。但是,在所有后续警报中(当它正常运行时)我在控制台中得到这个输出
2021-01-07 12:19:49.289546-0700 Test App[48718:25806605] setViewControllers:animated: called on <UIMoreNavigationController 0x7fcecf826c00> while an existing transition or presentation is occurring; the navigation stack will not be updated.
如果“按钮”选项卡是主要选项卡之一(不在“更多”屏幕上),则不会发生这种情况。
StoreKit 的应用内购买弹出窗口也会发生同样的行为,而不仅仅是我启动的警报。
我该如何解决这个问题?这是 TabView 错误吗?
运行 Xcode 12.3
在模拟器中复制于:iPhone 11,iPhone 12,iPad Pro
复制步骤(使用下面的代码):
- 启动应用程序
- 转到更多 -> 按钮选项卡
- 点击“显示警报”
- 已显示警报,但它后面的视图立即返回到选项卡 One
- 重复相同的步骤,不再发生(必须重新启动应用)
import SwiftUI
struct ContentView: View {
let textTabs = ["One","Two","Three","Four","Five","Six","Seven","Eight"]
var body: some View {
TabView {
ForEach(textTabs, id: \.self) { name in
Text(name).tabItem {
Image(systemName: "circle")
Text(name)
}
}
ButtonTab().tabItem {
Image(systemName: "face.smiling")
Text("Button")
}
}
}
}
struct ButtonTab: View {
@State var showAlert = false
var body : some View {
VStack {
Button("show alert") {
showAlert = true
}
}
.alert(isPresented: $showAlert) {
Alert(title: Text("hello"),
dismissButton: .default(Text("ok")))
}
}
}
一种可能的解决方法是在单击按钮时保持选择:
struct ContentView: View {
let textTabs = ["One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight"]
@State private var selection = "Two" // store selection as a `@State`
var body: some View {
TabView(selection: $selection) {
ForEach(textTabs, id: \.self) { name in
Text(name)
.tabItem {
Image(systemName: "circle")
Text(name)
}
}
ButtonTab(selection: $selection)
.tabItem {
Image(systemName: "face.smiling")
Text("Button")
}
.tag("Button") // add tag for `selection`
}
}
}
struct ButtonTab: View {
@State private var showAlert = false
@Binding var selection: String // pass selection as a `@Binding`
var body: some View {
VStack {
Button("show alert") {
showAlert = true
selection = "Button" // (force) set `selection` here
}
}
.alert(isPresented: $showAlert) {
Alert(title: Text("hello"),
dismissButton: .default(Text("ok")))
}
}
}