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

Dmy*_*kov 15 ios swift swiftui

我注意到添加sheet修饰符时 SwiftUI 完全刷新视图。

假设我有显示随机数的视图。我希望这个值是独立的,并且不连接到工作表逻辑(每次打开/关闭工作表时不会改变),但每次工作表呈现/关闭时文本都会发生变化

它应该这样工作吗?@Sate我的主要观点是只更新连接的视图而不是所有堆栈,我错了吗?呈现模式时如何防止视图自行刷新?

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")
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

PS ContentView 调用onAppear()/onDisappear()并且init()仅调用 / 。

Asp*_*eri 20

它需要制作独立的条件无关视图来实现您希望的行为,如下所示

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")
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下RandomView不会重建,因为不依赖于active状态。

  • 和往常一样,阿斯佩里是正确的。本文提供了一些其他清晰的视图相互依赖的示例,以及如何分解它们:https://medium.com/flawless-app-stories/swiftui-why-to-write-custom-views-for-better -性能-561962f1c268 (2认同)
  • 只是补充一下,对于更复杂的用例,请在 SwiftUI 视图上使用带有“.equatable()”修饰符的“Equatable”协议。 (2认同)
  • ...浪费了几天的时间试图弄清楚为什么每次修改 TextField 值时我的 UI 都会完全更新,然后尝试修复它。谢谢你! (2认同)

use*_*734 5

阿斯佩里伤心:

视图是结构体,值类型,如果它的任何部分发生变化,则整个值发生变化

他是绝对正确的!但为此我们拥有国家财产。重新创建视图时,状态值不会更改。

这应该有效,正如您所期望的那样

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")
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

优点是什么?对于简单的事情,状态/绑定是最好的解决方案,毫无疑问。

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()
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,您可以在生成或不生成新随机数的情况下关闭该工作表。不需要外部模型...