简体   繁体   English

SwiftUI:防止视图在呈现工作表时刷新

[英]SwiftUI: prevent View from refreshing when presenting a sheet

I have noticed that SwiftUI completely refresh view when adding sheet modifier.我注意到 SwiftUI 在添加工作sheet修改器时完全刷新视图。

Let's say I have View that displays random number.假设我有显示随机数的视图。 I expect that this value would be independent and not connected to the sheet logic (not changing every time I open/close sheet), but every time sheet presented/dismissed Text is changing .我希望这个值是独立的并且不连接到工作表逻辑(每次打开/关闭工作表时都不会改变),但每次工作表呈现/关闭时文本都在改变

Is it supposed to work so?它应该这样工作吗? Am I wrong that main point of @Sate is to update only connected Views but not all stack? @Sate主要观点是只更新连接的视图而不是所有堆栈,我错了吗? How can I prevent my View from refreshing itself when presenting a modal?在呈现模式时如何防止我的视图自我刷新?

struct ContentView: View {

    @State var active = false

    var body: some View {
        VStack {
            Text("Random text: \(Int.random(in: 0...100))")

            Button(action: { self.active.toggle() }) {
                Text("Show pop up")
            }
        }
        .sheet(isPresented: $active) {
            Text("POP UP")
        }
    }
}

PS ContentView calls onAppear() / onDisappear() and init() only ones. PS ContentView 只调用onAppear() / onDisappear()init()

It needs to make separated condition-independent view to achieve behavior as you wish, like below它需要制作独立的独立于条件的视图来实现你想要的行为,如下所示

struct RandomView: View {
    var body: some View {
        Text("Random text: \(Int.random(in: 0...100))")
    }
}

struct ContentView: View {

    @State var active = false

    var body: some View {
        VStack {
            RandomView()

            Button(action: { self.active.toggle() }) {
                Text("Show pop up")
            }
        }
        .sheet(isPresented: $active) {
            Text("POP UP")
        }
    }
}

In this case RandomView is not rebuilt because is not dependent on active state.在这种情况下, RandomView不会重建,因为它不依赖于active状态。

Asperi sad :阿斯佩里伤心:

View is struct, value type, if any part of it changed then entire value changed视图是结构体,值类型,如果它的任何部分发生变化,则整个值都发生了变化

He is absolutely right!他是绝对正确的! But for that we have state properties.但是为此我们有状态属性。 When the view is recreated, the value of state doesn't change.重新创建视图时,状态的值不会改变。

This should work, as you expected这应该工作,正如你所期望的

struct ContentView: View {

    @State var active = false
    @State var number = Int.random(in: 0 ... 100)
    var body: some View {
        VStack {
            Text("Random text: \(number)")

            Button(action: { self.active.toggle() }) {
                Text("Show pop up")
            }
        }
        .sheet(isPresented: $active) {
            Text("POP UP")
        }
    }
}

What is the advantage?优势是什么? For simple things, the state / binding is the best solution, without any doubt.对于简单的事情,状态/绑定是最好的解决方案,毫无疑问。

import SwiftUI

struct SheetView: View {
    @Binding var randomnumber: Int
    var body: some View {
        Button(action: {
            self.randomnumber = Int.random(in: 0 ... 100)
        }) {
            Text("Generate new random number")
        }
    }
}
struct ContentView: View {

    @State var active = false
    @State var number = Int.random(in: 0 ... 100)
    var body: some View {
        VStack {
            Text("Random text: \(number)")

            Button(action: { self.active.toggle() }) {
                Text("Show pop up")
            }
        }
        .sheet(isPresented: $active) {
            SheetView(randomnumber: self.$number)
        }
    }
}
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

Now you can dismiss the sheet with or without generating new random number.现在您可以在生成或不生成新随机数的情况下关闭工作表。 No external model is required ...不需要外部模型...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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