如何在SwiftUI的init函数中初始化@State变量?

时间:2019-11-07 23:32:33

标签: state swiftui init

让我们看一下简单的源代码:

import SwiftUI

struct MyView: View {
    @State var mapState: Int

    init(inputMapState: Int)
    {
        mapState = inputMapState //Error: 'self' used before all stored properties are initialized
    } //Error: Return from initializer without initializing all stored properties

    var body: some View {
        Text("Hello World!")
    }
}

我在这里需要init函数,因为我想在这里加载一些数据,但是有一个问题,在这里无法初始化@State变量!我该怎么办? 也许这是一个非常简单的问题,但我不知道该怎么做。 非常感谢!

4 个答案:

答案 0 :(得分:38)

属性包装器正在为您生成一些代码。您需要知道的是实际生成的存储属性是包装程序的类型,因此您需要使用其构造函数,并且其前缀为_。在您的情况下,这意味着var _mapState: State<Int>,因此请按照您的示例进行操作:

import SwiftUI

struct MyView: View {
    @State var mapState: Int

    init(inputMapState: Int)
    {
        _mapState = /*State<Int>*/.init(initialValue: inputMapState)
    }

    var body: some View {
        Text("Hello World!")
    }
}

答案 1 :(得分:1)

我认为编写代码时最好进行初始化。

就像

  

@State var mapState = 0

或者,如果要将值绑定到另一个视图,请使用@Binding。

我希望你也检查一下。

https://www.hackingwithswift.com/quick-start/swiftui/what-is-the-binding-property-wrapper

答案 2 :(得分:0)

您可以为mapState设置一个初始值,如下所示:

@State var mapState: Int = 0

然后您将能够设置传递给init方法的值。

答案 3 :(得分:0)

我们可以注入视图所需的数据。

使用可以访问所需数据的模型。制作一个地图视图,并在其父视图中使用该实例。这也将有助于对模型进行单元测试。

使用属性包装器@Binding将数据从父视图传递到MapView,并使用_mapState来保存mapState的值。

struct Model {
 //some data
}

struct MapView {
    private let model: Model
    @Binding var mapState: Int

    init(model: Model, mapState: Binding<Int>) {
        self.model = model
        self._mapState = mapState
    }
}

extension MapView: View {

    var body: some View {
        Text("Map Data")
    }
}