为啥我不能强制解开我的 $string 以用作 TextField 值?
Posted
技术标签:
【中文标题】为啥我不能强制解开我的 $string 以用作 TextField 值?【英文标题】:Why can't I force unwrap my $string to use as a TextField value?为什么我不能强制解开我的 $string 以用作 TextField 值? 【发布时间】:2021-05-03 11:32:12 【问题描述】:这给了我以下错误:
无法强制解开非可选类型 'Binding
我不明白为什么我不能强制解开绑定?
struct Person
var name: String
struct ContentView: View
@State private var person: Person? = Person(name: "Peter")
var body: some View
if person != nil
TextField("", text: $person!.name)
【问题讨论】:
题外话,但您确定要将像 Person 这样的模型对象作为状态变量吗? 为什么person
是可选的?
@JoakimDanielson 你是对的,我不会。我从我的代码中提取了这个以简化示例。
@vadian。提取代码以简化示例。但是假设您有一个可供选择的人员列表,一个选项是根本不选择一个人。在这种情况下, Person 将为零,所以我需要计算
我不明白。如果您有一个列表,则该对象是一个数组,而 none selected 是一个空数组。如果视图是列表中的行视图,则如果未选择该行,则不会显示该视图。我想说的是,与 Swift 语言不同,SwiftUI 严重依赖非可选项,您应该首先寻找一种避免可选项的设计。
【参考方案1】:
当您在视图中声明State
变量时,您将通过在变量名称中添加前导$
来获得Binding
值。
因此,在您的代码中,您将拥有一个绑定到可选 Person
类型的 $person
。 $person
是 Binding<Person?>
要将值传递给TextField
,您需要Binding<String>
。您不能强制解开 $person
,因为它不是可选值。这是一个可选类型的Binding
。要访问Person
结构中的name
字段,您需要一个Binding<Person>
。
幸运的是,有一种方法可以得到你想要的。
通过使用this initializer,您将拥有Binding<Person>?
。请注意,现在你有一个可选的Binding
,而不是一个可选的Binding
。
您应该可以像这样使用这个新绑定:
// Binding($person) returns Binding<Person>?
TextField("", text: Binding($person)!.name)
更新:
正如@Jessy 在 cmets 中提到的,我们可以使用map
将返回的Binding
转换为TextField
,而不是强制解包可选绑定。
var body: some View
Binding($person).map
TextField("", text: $0.name)
【讨论】:
该初始化程序是解决方案的一个很好的部分,但!
不是一个好方法。 if let
或我对 map
所做的更好;更新你的答案,我会删除我的,因为你有更完整的信息。
现在,这有多酷。不完全确定我理解映射发生了什么,但是谢谢,伙计们,这完全为我整理好了!以上是关于为啥我不能强制解开我的 $string 以用作 TextField 值?的主要内容,如果未能解决你的问题,请参考以下文章