Keyboard 当键盘出现在SwiftUI中时,OnAppear意外调用

Keyboard 当键盘出现在SwiftUI中时,OnAppear意外调用,keyboard,swiftui,textfield,tabview,swiftui-tabview,Keyboard,Swiftui,Textfield,Tabview,Swiftui Tabview,我在Swiftui2.0和iOS14中遇到了非常奇怪的行为 当键盘出现在屏幕上时,会自动调用其他选项卡视图的OnAppear方法 但是,这在Xcode 11.7中运行良好 这就是正在发生的问题。 下面是产生上述错误的代码 struct ContentView: View { var body: some View { TabView { DemoView(screenName: "Home")

我在Swiftui2.0和iOS14中遇到了非常奇怪的行为

当键盘出现在屏幕上时,会自动调用其他选项卡视图的OnAppear方法

但是,这在Xcode 11.7中运行良好

这就是正在发生的问题。

下面是产生上述错误的代码

struct ContentView: View {
    var body: some View {
        TabView {
            DemoView(screenName: "Home")
                .tabItem {
                    Image.init(systemName: "star.fill")
                    Text("Home")
                }
            DemoView(screenName: "Result")
                .tabItem {
                    Image.init(systemName: "star.fill")
                    Text("Result")
                }
            DemoView(screenName: "More")
                .tabItem {
                    Image.init(systemName: "star.fill")
                    Text("More")
                }
        }
    }
}

struct DemoView:View {
    
    @State var text:String = ""
    var screenName:String
    var body: some View {
        VStack{
            Text(screenName)
                .font(.title)
            
            TextField("Buggy Keyboard Issue", text: $text)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                
            Text("Issue : When keyboard appears, onAppear of other 2 tabs call automatically.")
                .font(.footnote)
        }
        .padding()
        .onAppear(perform: {
            debugPrint("OnAppear of : \(screenName)")
        })
    }
}
这似乎是Swiftui2.0的一个bug,但不确定。 任何帮助都将不胜感激


感谢为避免重新加载视图,请在选项卡视图上尝试

.ignoresSafeArea(.keyboard, edges: .bottom)

它只在iOS 14上工作,我自己也有同样的问题,我认为这是一个bug或类似的东西,但是我想出了一个解决方案,也许是一个变通办法,直到苹果公司解决它

我所做的事情基本上是使用了一个
懒散的vstack
,这似乎工作得很好

LazyVStack {
    VStack{
        Text(screenName)
            .font(.title)
        
        TextField("Buggy Keyboard Issue", text: $text)
            .textFieldStyle(RoundedBorderTextFieldStyle())
            
        Text("Issue : When keyboard appears, onAppear of other 2 tabs call automatically.")
            .font(.footnote)
    }
    .padding()
    .onAppear(perform: {
        debugPrint("OnAppear of : \(screenName)")
})
}
现在,当键盘出现时,其他选项卡视图的
OnAppear
方法不会自动调用


刚刚实施了以下解决方法:

struct ContentView: View {
    var body: some View {
        TabView(selection: $selectedTab) {
            TabContentView(tag: 0, selectedTag: selectedTab) {
                Text("Some tab content")
            }
            .tabItem {
                Text("First tab")
            }
            TabContentView(tag: 0, selectedTag: selectedTab) {
                Text("Another tab content")
            }
            .tabItem {
                Text("Second tab")
            }
        }
    }
    
    @State private var selectedTab: Int = 0
}

private struct TabContentView<Content: View, Tag: Hashable>: View {
    init(tag: Tag, selectedTag: Tag, @ViewBuilder content: @escaping () -> Content) {
        self.tag = tag
        self.selectedTag = selectedTag
        self.content = content
    }

    var body: some View {
        Group {
            if tag == selectedTag {
                content()
                    .frame(maxWidth: .infinity, maxHeight: .infinity)
            } else {
                Color.clear
            }
        }
        .tag(tag)
    }

    private let tag: Tag
    private let selectedTag: Tag
    private let content: () -> Content
}
struct ContentView:View{
var body:一些观点{
选项卡视图(选择:$selectedTab){
选项卡ContentView(标记:0,selectedTag:selectedTab){
文本(“某些选项卡内容”)
}
.tabItem{
文本(“第一个选项卡”)
}
选项卡ContentView(标记:0,selectedTag:selectedTab){
文本(“另一个选项卡内容”)
}
.tabItem{
文本(“第二个选项卡”)
}
}
}
@选择的状态私有变量选项卡:Int=0
}
私有结构选项卡ContentView:View{
init(tag:tag,selectedTag:tag,@ViewBuilder内容:@escaping()->content){
self.tag=tag
self.selectedTag=selectedTag
self.content=内容
}
var body:一些观点{
团体{
如果标记==selectedTag{
内容()
.frame(maxWidth:无穷大,maxHeight:无穷大)
}否则{
颜色。清晰
}
}
.标签(tag)
}
私人出租标签:标签
私有let selectedTag:Tag
私有出租内容:()->内容
}

不确定它是否足够稳定,但键盘外观不会再触发标签内容的外观。

我已经向苹果报告了这一行为。SwiftUI onAppear不等于UIKit viewDidAppear。一旦视图在视图层次结构中呈现(而不是在用户可见时),它们就会调用onAppear。什么时候,为什么,调用多少次是完全不同的问题,实际上并没有在任何地方指定/记录,所以我不会依赖于这种行为,因为它是从一个版本更改到另一个版本的。你也经历过同样的经历吗?是的,我经历过:/。我也经历过同样的问题!。如果我们不能依赖于外观上的
,当视图可见时,我们应该在哪里进行网络调用。这对我不起作用,实现在悬赏注册表中显示,对我不起作用,这是SwiftUI中的一个bug。我向苹果提交了反馈,但还没有得到回复:
FB8646389
,实际上,这个bug在我的代码中产生了很多意想不到的行为。懒虫在这里做什么呢?这对我很有用。我认为当键盘出现时,其他选项卡视图会被重新加载。lazyvstack导致当键盘出现在另一个选项卡中时不会重新加载视图。