如何在SwiftUI中以编程方式设置@State变量

17

我有一个控件,它设置了一个@State变量来跟踪自定义选项卡视图中所选选项卡。 我可以通过设置以下内容的代码来设置@State变量:

@State var selectedTab: Int = 1

如何通过编程设置初始值,以便在创建视图时更改所选选项卡?

我尝试了以下方法:

1:

@State var selectedTab: Int = (parameter == true ? 1 : 2)

2:

init(default: Int) {
    self.$selectedTab = default
}

有同样的问题。 - Bagusflyer
1
不应该从通过初始化程序传递的数据初始化@State变量;由于模型在视图之外维护,因此不能保证该值实际上会被使用。请查看我的答案。 - Kugutsumen
你应该使用绑定来提供对不属于视图本地状态的访问。 - Kugutsumen
相关回答:https://dev59.com/QFMI5IYBdhLWcg3wPpAa#58137096 - ConfusionTowers
3个回答

34

我在我的一个视图中设置初始状态值的示例:

struct TodoListEdit: View {
    var todoList: TodoList
    @State var title = ""
    @State var color = "None"

    init(todoList: TodoList) {
        self.todoList = todoList
        self._title = State(initialValue: todoList.title ?? "")
        self._color = State(initialValue: todoList.color ?? "None")
    }

8

Joe Groff: 在SwiftUI中,@State变量不应该从通过初始化器传递的数据进行初始化。正确的做法是在内联中设置初始状态值:

@State var selectedTab: Int = 1

您应该使用Binding来提供访问不属于视图本身的状态。

@Binding var selectedTab: Int

然后,您可以从init初始化它,并仍然可以将其传递给子视图。

来源:https://forums.swift.org/t/state-messing-with-initializer-flow/25276/3


1
但是如果您有两种情况,一种是您想从前一个视图传递数据,另一种是您想使用默认数据值进行初始化(即创建/编辑页面)呢? - Ever Uribe
这个讨论提供了更好的背景,解释了为什么@State变量不应该在初始化时进行初始化,详情请见:https://forums.swift.org/t/assignment-to-state-var-in-init-doesnt-do-anything-but-the-compiler-gened-one-works/35235 - Ever Uribe
你在哪里进行数据结构的适配?我需要将一个枚举数组转换为字符串集,以便我可以将其传递给列表,让用户选择一个或多个项目。最好的方法是使用传入的数组进行操作。因此,我无法真正同意这是正确的策略。 - Todd Hoff

-7

一旦我发现答案,这个问题就变得非常简单了!

你只需要通过修改声明来删除初始化的初始值:

@State var selectedTab: Int = 1

to:

@State var selectedTab: Int

然后,selectedTab变量会自动成为实例化语句中的参数。因此,初始化将是:

TabBarContentView(selectedTab: 2)

就是这么简单!!!!


2
如果你必须编写自己的init,那么这是无法工作的。 - Bagusflyer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接