当视图打开两次时,@state 属性 没有初始化

The @state property doesn't initialization when the view open two times

Xcode 11 beta 6 , iOS Develop beta 8

我觉得应该初始化@Satae 属性,不知道是SwiftUI的bug还是我理解错了@State

操作流程为

  1. 点击按钮(显示另一个视图)打开另一个视图。
  2. 单击文本字段并输入一些数据。
  3. 点击按钮或下拉视图以关闭此视图。
  4. 点击按钮(显示另一个视图)打开另一个视图。
  5. 你会发现文本字段有数据,它没有初始化。

代码是这样的

import SwiftUI

struct ContentView: View {
    @State var isShow = false
    var body: some View {
        Button(action: {self.isShow.toggle()}) {
            Text("show another view")
        }.sheet(isPresented: $isShow) {
            AnotherView()
        }
    }
}

struct AnotherView: View {
    @Environment(\.presentationMode) var presentationMode
    @State var text = ""
    var body: some View {
        VStack {
            TextField("Input changing the @State property", text: $text)
            Button(action: {self.presentationMode.wrappedValue.dismiss()}) {
                Text("Dismiss")
            }
        }.padding()
    }
}

演示 gif:https://imgur.com/4FWyTOf

@State 尽可能长地存在,因此很可能在解构视图之间重复使用。但是可以通过多种方式解决它。

重绘 body 仅在第一次初始化时由于部分-ObservableObject

import SwiftUI

struct InitializeStateView: View {
    @State var isShow = false
    var body: some View {
        Button(action: {self.isShow.toggle()}) {
            Text("show another view")
        }.sheet(isPresented: $isShow) {
            InitAnotherView()
        }
    }
}

class InitAnotherViewState: ObservableObject {
    @Published var wasInitialized = false
}

struct InitAnotherView: View {
    init() {
        print("Init InitAnotherView")
    }

    @Environment(\.presentationMode) var presentationMode
    @ObservedObject var state = InitAnotherViewState()
    @State var text = ""

    var body: some View {
        print("Redrawing InitAnotherView")

        if !state.wasInitialized {
            DispatchQueue.main.asyncAfter(deadline: .now()) {
                self.text = "hey"
            }
            state.wasInitialized = true
        }

        return VStack {
            TextField("Input changing the @State property", text: $text)
            Button(action: {self.presentationMode.wrappedValue.dismiss()}) {
                Text("Dismiss")
            }
        }.padding()
    }
}

由于 ObservableObject

,每个新角色都会重新绘制 body
import SwiftUI

struct InitializeStateView: View {
    @State var isShow = false
    var body: some View {
        Button(action: {self.isShow.toggle()}) {
            Text("show another view")
        }.sheet(isPresented: $isShow) {
            InitAnotherView()
        }
    }
}

class InitAnotherViewState: ObservableObject {
    @Published var text: String = ""
    @Published var wasInitialized = false
}

struct InitAnotherView: View {
    init() {
        print("Init InitAnotherView")

    }

    @Environment(\.presentationMode) var presentationMode
    @ObservedObject var state = InitAnotherViewState()

    var body: some View {
        print("Redrawing InitAnotherView")

        return VStack {
            TextField("Input changing the @State property", text: $state.text)
            Button(action: {self.presentationMode.wrappedValue.dismiss()}) {
                Text("Dismiss")
            }
        }.padding()
    }
}