【问题标题】:What is the best way to switch views in SwiftUI?在 SwiftUI 中切换视图的最佳方式是什么?
【发布时间】:2019-12-18 01:31:48
【问题描述】:

我尝试了几种在 SwiftUI 中切换视图的选项。但是,每个人在多次切换时都会遇到lagging over time之类的问题。链接的问题已被删除,我不知道为什么会这样,但如果不是这样,它真的可以帮助我。我问这个是因为这个问题引起了我的兴趣,我想知道更多,因为我能够复制该问题中描述的行为。我试图找到使用 SwiftUI 切换视图的最佳和最干净的方法。我只是想制作一个多视图用户界面。

在 View1.swift 中

import SwiftUI
struct View1: View {
    @State var GoToView2:Bool = false
    var body: some View {
        ZStack {
            if (GoToView2) {
                View2()
                //What should I do if I created another swiftui view under the name View2? 
                //Just calling View2() like that causes lag as described in the linked question before it was deleted, if from view2 I switch back to view1 and so on. 
                //If I directly put the code of View2 here, then adding other views would get too messy.
            } else {
                VStack {
                    Button(action: {self.GoToView2.toggle()}) {
                        Text("Go to view 2")
                    }
                }
            }
        }
    }
}

在 View2.swift 中:

import SwiftUI
struct View2: View {
    @State var GoToView1:Bool = false
    var body: some View {
        ZStack {
            if (GoToView1) {
                 View1()
            } else {
                VStack {
                    Button(action: {self.GoToView1.toggle()}) {
                        Text("Go to view 1")
                    }
                }
            }
        }
    }
}

我希望你们能理解这个问题。要复制该行为,请在 swiftUI 应用程序中编译代码,然后快速在两个按钮之间反复切换 30 秒,然后您应该注意到每个切换之间的延迟,并且调整窗口大小应该看起来很粗。我正在使用最新版本的 macOS 和最新版本的 Xcode。

【问题讨论】:

  • 没有观察到滞后。你能展示你在 View2 中做什么吗?你使用哪个版本的 Xcode?​​span>
  • @Asperi IF view2 有一个按钮可以转到 view1,然后从 1 到 2 到 1 到 2 多次切换会产生延迟。尝试调整窗口大小,如果滞后,它会调整大小
  • @Asperi 我编辑了我的问题以包含指定的信息
  • 我认为这是因为它基本上是递归的......在View1 你调用View2 反之亦然......它就像一个无限的视图树,对吧?您应该将GoToView2 作为Binding 传递给View2...如果我错了请纠正我
  • 我没有执行这些操作。我不是版主。如果您想讨论行为和/或响应,请在meta.stackoverflow.com 上发帖

标签: swift performance swiftui


【解决方案1】:

所以我试图表明对Views 的每个调用都会将一个实例添加到视图堆栈中......我可能在这里错了,但以下应该显示:

struct View1: View {
    @State var GoToView2:Bool = false
    var counter: Int

    init(counter: Int) {
        self.counter = counter + 1
    }

    var body: some View {
        VStack {
            if (GoToView2) {
                Text("\(self.counter)")
                View2(counter: self.counter)
            } else {
                VStack {
                    Button(action: {
                        withAnimation {
                            self.GoToView2.toggle()
                        }
                    }) {
                        Text("Go to view 2")
                    }
                }
            }
        }
    }
}

struct View2: View {
    @State var GoToView1:Bool = false
    var counter: Int

    init(counter: Int) {
        self.counter = counter + 1
    }

    var body: some View {
        VStack {
            if (GoToView1) {
                Text("\(self.counter)")
                View1(counter: self.counter)
            } else {
                VStack {
                    Button(action: {
                        withAnimation {
                            self.GoToView1.toggle()
                        }
                    }) {
                        Text("Go to view 1")
                    }
                }.transition(.move(edge: .leading))
            }
        }
    }
}

我试图证明另一种方法不会这样做:

struct View1: View {
    @State var GoToView2: Bool = false
    var counter: Int

    init(counter: Int) {
        self.counter = counter + 1
    }

    var body: some View {
        VStack {
            if (GoToView2) {
                Text("\(self.counter)")
                View2(counter: self.counter, GoToView1: self.$GoToView2)
            } else {
                VStack {
                    Button(action: {
                        withAnimation {
                            self.GoToView2.toggle()
                        }
                    }) {
                        Text("Go to view 2")
                    }
                }
            }
        }
    }
}

struct View2: View {
    @Binding var GoToView1: Bool
    var counter: Int

    init(counter: Int, GoToView1: Binding<Bool>) {
        self._GoToView1 = GoToView1
        self.counter = counter + 1
    }

    var body: some View {

            VStack {
                Text("\(self.counter)")
                Button(action: {
                    withAnimation {
                        self.GoToView1.toggle()
                    }
                }) {
                    Text("Go to view 1")
                }
            }.transition(.move(edge: .leading))


    }
}

我不知道延迟是否真的来自此,或者是否有更好的证明方法,但现在这是我想出的。

原答案

我建议您执行以下操作:

struct View1: View {
    @State var GoToView2:Bool = false
    var body: some View {
        ZStack {
            if (GoToView2) {
                View2(GoToView1: self.$GoToView2)
            } else {
                VStack {
                    Button(action: {
                        withAnimation {
                            self.GoToView2.toggle()
                        }
                    }) {
                        Text("Go to view 2")
                    }
                }
            }
        }
    }
}

struct View2: View {
    @Binding var GoToView1: Bool
    var body: some View {
        VStack {
            Button(action: {
                withAnimation {
                    self.GoToView1.toggle()
                }
            }) {
                Text("Go to view 1")
            }
        }.transition(.move(edge: .leading))
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-07
    • 2021-06-20
    • 2011-09-01
    • 1970-01-01
    • 2020-12-04
    • 1970-01-01
    相关资源
    最近更新 更多