SwiftUI 中 init() 内部的条件
Conditions inside init() in SwiftUI
我需要将 init 与 SwiftUI 一起使用,但我只是在学习初始化程序。找了很多复杂的例子,但是基本都看不懂
如何根据其他一些变量的值在 init() 中初始化不同的值,例如基于来自切换的 true/false?
示例代码
我正在尝试这样的事情:
import SwiftUI
struct ToggleView: View {
@State var toggleValue: Bool = true
var testValue: String
init() {
if toggleValue {
self.testValue = "true"
} else {
self.testValue = "false"
}
}
var body: some View {
VStack {
Toggle(isOn: $toggleValue) {
Text("True or false?")
}.padding()
Text("Selected value:")
Text("\(testValue)")
}
}
}
struct ToggleView_Previews: PreviewProvider {
static var previews: some View {
ToggleView()
}
}
但是与 if toggleValue { 一致,我得到一个错误:
'self' used before all stored properties are initialized
我试过改变:
var testValue: String
init() {
至:
@Binding var testValue: String
init(testValue: Binding<String>) {
但是也没用。如何将此 testValue 与切换绑定,因此在点击切换后我的应用程序将打印:“Selected value: false”?
TLDR;您永远不能用另一个存储的 属性 初始化一个存储的 属性。如果您想用相同的值初始化两个属性,该值必须来自初始化程序中的参数或某个常量。
编译器实际上给出了一个非常有用的错误。在使用 self
之前,需要初始化所有存储的属性。在您的示例中,您有两个存储属性:toggleValue
和 testValue
。 toggleValue
已初始化,但 testValue
未初始化。由于读取存储的 属性 是 using self
的示例,因此您 不能 使用存储的 属性 来初始化另一个存储的 属性。您 可以 使用 init()
.
中的参数初始化属性
例如:
init(initialValue: Bool) {
testValue = initialValue ? "true" : "false"
}
或者您可以使 testValue 成为依赖于另一个 属性:
的计算 属性
var testValue: String {
toggleValue ? "true" : "false"
}
如果你想保持 testValue
和 toggleValue
同步 和 能够修改 testValue 你可以使用绑定:
var testValue: Binding<String> {
Binding<String>(
get: { toggleValue ? "true" : "false" },
set: { toggleValue = [=12=] == "true" }
)
}
如果你只想初始化 testValue in sync with toggleValue 你可以使用静态常量:
static let initialValue = true
@State var toggleValue = ToggleView.initialValue
var testValue = ToggleView.initialValue ? "true" : "false"
或者在初始化器中使用常量:
init() {
let initialValue = true
toggleValue = initialValue
testValue = initialValue ? "true" : "false"
// Note that in this case the compiler will inform you the 'false'
// branch will never be executed (which is correct). To prevent this
// you can either depend on a static constant, create your own
// extension on bool to provide a string, or just use:
// testValue = "\(initialValue)"
}
请注意,结构有一个隐式初始化程序,它存储按出现顺序列出的属性。使用初始化属性作为可选参数。这意味着您可以通过以下方式初始化 ToggleView(无需指定初始化程序):
ToggleView(toggleValue: false, testValue: true)
ToggleView(testValue: true)
我需要将 init 与 SwiftUI 一起使用,但我只是在学习初始化程序。找了很多复杂的例子,但是基本都看不懂
如何根据其他一些变量的值在 init() 中初始化不同的值,例如基于来自切换的 true/false?
示例代码
我正在尝试这样的事情:
import SwiftUI
struct ToggleView: View {
@State var toggleValue: Bool = true
var testValue: String
init() {
if toggleValue {
self.testValue = "true"
} else {
self.testValue = "false"
}
}
var body: some View {
VStack {
Toggle(isOn: $toggleValue) {
Text("True or false?")
}.padding()
Text("Selected value:")
Text("\(testValue)")
}
}
}
struct ToggleView_Previews: PreviewProvider {
static var previews: some View {
ToggleView()
}
}
但是与 if toggleValue { 一致,我得到一个错误:
'self' used before all stored properties are initialized
我试过改变:
var testValue: String
init() {
至:
@Binding var testValue: String
init(testValue: Binding<String>) {
但是也没用。如何将此 testValue 与切换绑定,因此在点击切换后我的应用程序将打印:“Selected value: false”?
TLDR;您永远不能用另一个存储的 属性 初始化一个存储的 属性。如果您想用相同的值初始化两个属性,该值必须来自初始化程序中的参数或某个常量。
编译器实际上给出了一个非常有用的错误。在使用 self
之前,需要初始化所有存储的属性。在您的示例中,您有两个存储属性:toggleValue
和 testValue
。 toggleValue
已初始化,但 testValue
未初始化。由于读取存储的 属性 是 using self
的示例,因此您 不能 使用存储的 属性 来初始化另一个存储的 属性。您 可以 使用 init()
.
例如:
init(initialValue: Bool) {
testValue = initialValue ? "true" : "false"
}
或者您可以使 testValue 成为依赖于另一个 属性:
的计算 属性var testValue: String {
toggleValue ? "true" : "false"
}
如果你想保持 testValue
和 toggleValue
同步 和 能够修改 testValue 你可以使用绑定:
var testValue: Binding<String> {
Binding<String>(
get: { toggleValue ? "true" : "false" },
set: { toggleValue = [=12=] == "true" }
)
}
如果你只想初始化 testValue in sync with toggleValue 你可以使用静态常量:
static let initialValue = true
@State var toggleValue = ToggleView.initialValue
var testValue = ToggleView.initialValue ? "true" : "false"
或者在初始化器中使用常量:
init() {
let initialValue = true
toggleValue = initialValue
testValue = initialValue ? "true" : "false"
// Note that in this case the compiler will inform you the 'false'
// branch will never be executed (which is correct). To prevent this
// you can either depend on a static constant, create your own
// extension on bool to provide a string, or just use:
// testValue = "\(initialValue)"
}
请注意,结构有一个隐式初始化程序,它存储按出现顺序列出的属性。使用初始化属性作为可选参数。这意味着您可以通过以下方式初始化 ToggleView(无需指定初始化程序):
ToggleView(toggleValue: false, testValue: true)
ToggleView(testValue: true)