SwiftUI @State var初始化问题

时间:2019-06-20 18:07:24

标签: swiftui

我想通过@State的{​​{1}}方法在SwiftUI中初始化init() var的值,因此它可以从准备的字典中获取适当的文本以进行操作在TextField中。 源代码如下:

Struct

不幸的是,执行失败并显示错误struct StateFromOutside: View { let list = [ "a": "Letter A", "b": "Letter B", // ... ] @State var fullText: String = "" init(letter: String) { self.fullText = list[letter]! } var body: some View { TextField($fullText) } }

我该如何解决这种情况?提前非常感谢您!

4 个答案:

答案 0 :(得分:42)

SwiftUI不允许您在初始化程序中更改 @State,但是您可以初始化

删除默认值,并使用_fullText直接设置@State,而不用通过属性包装器访问器。

@State var fullText: String // No default value of ""

init(letter: String) {
    _fullText = State(initialValue: list[letter]!)
}

答案 1 :(得分:3)

我会尝试在onAppear中对其进行初始化。

struct StateFromOutside: View {
    let list = [
        "a": "Letter A",
        "b": "Letter B",
        // ...
    ]
    @State var fullText: String = ""

    var body: some View {
        TextField($fullText)
             .onAppear {
                 self.fullText = list[letter]!
             }
    }
}

或者甚至更好的是,使用模型对象(链接到视图的BindableObject)并在那里进行所有初始化和业务逻辑。您的视图将更新以自动反映更改。

答案 2 :(得分:0)

请参见下面的示例中的.id(count)

import SwiftUI
import MapKit

struct ContentView: View {
@State private var count = 0

var body: some View {
    Button("Tap me") {
        self.count += 1
        print(count)
    }
    Spacer()
    testView(count: count).id(count) // <------ THIS IS IMPORTANT. Without this "id" the initializer setting affects the testView only once and calling testView again won't change it (not desirable, of course)
}
}



struct testView: View {
var count2: Int
@State private var region: MKCoordinateRegion

init(count: Int) {
    count2 = 2*count
    print("in testView: \(count)")
    
    let lon =  -0.1246402 + Double(count) / 100.0
    let lat =  51.50007773 + Double(count) / 100.0
    let myRegion = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: lat, longitude: lon) , span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01))
    _region = State(initialValue: myRegion)
}

var body: some View {
    Map(coordinateRegion: $region, interactionModes: MapInteractionModes.all)
    Text("\(count2)")
}
}

答案 3 :(得分:-1)

在这种情况下,Bogdan Farca的答案是正确的,但是我们不能说这是所提出问题的解决方案,因为我发现所提出问题中的Textfield存在问题。仍然可以将init用于相同的代码,因此请看下面的代码,它显示了所问问题的确切解决方案。

struct StateFromOutside: View {
    let list = [
        "a": "Letter A",
        "b": "Letter B",
        // ...
    ]
    @State var fullText: String = ""

    init(letter: String) {
        self.fullText = list[letter]!
    }

    var body: some View {
        VStack {
            Text("\(self.fullText)")
            TextField("Enter some text", text: $fullText)
        }
    }
}

只需在视图内部调用即可使用

struct ContentView: View {
    var body: some View {
        StateFromOutside(letter: "a")
    }
}