简体   繁体   中英

What is the best way to switch views in SwiftUI?

I have tried several options to switch views in SwiftUI. However, each one had issues like lagging over time when switching many times. The linked question have been deleted, I don't know why it was, but if it weren't it really could have helped me. I am asking this because that question intrigued me, and I want to know more, because I was able to replicate the described behavior in that question. I am trying to find the best and most clean way to switch views using SwiftUI. I am just trying to make a multiview user interface.

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

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

I hope you guys can understand the question. To replicate the behavior, please compile the code in a swiftUI app, then switch be repeatedly switching between the two buttons quickly for 30 seconds, then you should notice a delay between each switch, and resizing the window should look chunky. I am using the latest version of macOS and the latest version of Xcode.

So I tried to show that each of the calls to the Views would add an instance to the view stack... I might be wrong here but the following should show this:

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

The I tried to show that the other method wouldn't do that:

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


    }
}

I don't know if the lag is really coming from this or if there is a better method of proof, but for now this is what I came up with.

Original answer

I would recommend doing the following:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM