Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-cloud-platform/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在SwiftUI中创建计算的@State变量_Swiftui_Computed Properties - Fatal编程技术网

在SwiftUI中创建计算的@State变量

在SwiftUI中创建计算的@State变量,swiftui,computed-properties,Swiftui,Computed Properties,假设我正在设计一个快捷界面,要求用户输入用户名。屏幕将进行一些检查,以确保用户名有效。如果用户名无效,它将显示一条错误消息。如果用户点击“Disclose”,它将隐藏错误消息 最后,我可能会得出这样的结论: 这将很容易显示错误消息并正确地排除它们 现在想象一下,我想使用一个不同的组件而不是按钮来调用dismise方法。此外,假设我使用的组件只接受绑定(例如切换)。(注意:我意识到这不是一个理想的组件,但在这个简化的演示应用程序中,这是为了说明目的。)我可能会尝试创建一个抽象的组件来抽象这个行为

假设我正在设计一个快捷界面,要求用户输入用户名。屏幕将进行一些检查,以确保用户名有效。如果用户名无效,它将显示一条错误消息。如果用户点击“Disclose”,它将隐藏错误消息

最后,我可能会得出这样的结论:

这将很容易显示错误消息并正确地排除它们

现在想象一下,我想使用一个不同的组件而不是按钮来调用dismise方法。此外,假设我使用的组件只接受
绑定
(例如
切换
)。(注意:我意识到这不是一个理想的组件,但在这个简化的演示应用程序中,这是为了说明目的。)我可能会尝试创建一个抽象的组件来抽象这个行为,并最终得到:

@State private var bindableIsVisibleError: Bool {
    get { return self.model.usernameResult.isVisibleError }
    set { if !newValue { self.model.dismissUsernameResultError() } }
}

// ...


// replace Dismiss Button with:
Toggle(isOn: $bindableIsVisibleError, label: { EmptyView() })
。。。但是,这是无效语法,并在
@State
行上产生以下错误:

属性包装器无法应用于计算属性

如何创建可绑定的计算属性?即使用自定义getter和setter进行
绑定


虽然不理想,因为它(A)只提供了一个setter,并且(B)添加了状态复制(这与SwiftUI的单一真相来源原则背道而驰),但我认为我可以用一个正常的状态变量来解决这个问题:

@State private var bindableIsVisibleError: Bool = true {
    didSet { self.model.dismissUsernameResultError() }
}

这不起作用,因为从未调用过
didSet

一种解决方案是直接使用绑定,它允许您指定显式getter和setter:

func bindableIsVisibleError() -> Binding<Bool> {
    return Binding(
        get: { return self.model.usernameResult.isVisibleError },
        set: { if !$0 { self.model.dismissUsernameResultError() } })
}

虽然这是可行的,但它看起来不像使用计算属性那么干净,我不确定创建绑定的最佳方法是什么?(例如,使用示例中的函数、使用get only变量或其他方法。)

以下是我更喜欢的“动态”计算属性和绑定方法


有没有办法创建只读计算属性绑定?i、 e.没有setter的绑定。@JAHelia,是的,只需提供空setter,如
set:{uin}
@State private var bindableIsVisibleError: Bool = true {
    didSet { self.model.dismissUsernameResultError() }
}
func bindableIsVisibleError() -> Binding<Bool> {
    return Binding(
        get: { return self.model.usernameResult.isVisibleError },
        set: { if !$0 { self.model.dismissUsernameResultError() } })
}
Toggle(isOn: bindableIsVisibleError(), label: { EmptyView() })
private var bindableIsVisibleError: Binding<Bool> { Binding (
    get: { self.model.usernameResult.isVisibleError },
    set: { if !$0 { self.model.dismissUsernameResultError() } }
    )
}
Toggle(isOn: bindableIsVisibleError, label: { EmptyView() })