从“更多”溢出中的选项卡显示警报让我回到上一个视图

问题描述

我有一个简单的操作,在使用 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

复制步骤(使用下面的代码):

  • 启动应用
  • 转到更多 -> 按钮标签
  • 点击“显示提醒”
  • 显示警报,但其背后的视图立即返回到选项卡一
  • 重复相同的步骤,它不会再次发生(必须重新启动应用程序)

Animation of the issue

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")))
        }
    }
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...