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

nor*_*ins 40 state init swiftui

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

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

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

Gui*_*oMP 66

属性包装器正在为您生成一些代码。您需要知道的是实际生成的存储属性是包装器的类型,因此您需要使用其构造函数,并且它以_. 在你的情况下,这意味着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!")
    }
}
Run Code Online (Sandbox Code Playgroud)

  • _mapState = 状态(初始值:inputMapState) (5认同)

小智 8

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

使用可以访问您想要的数据的模型。创建一个地图视图并在您的父视图中使用它的实例。这也将有助于对模型进行单元测试。

使用属性包装器@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")
    }
}
Run Code Online (Sandbox Code Playgroud)