如何绑定到 SwiftUI 中可选的数据

2023-12-23

我很好奇,我们如何指定对属于可选部分的状态数据的绑定?例如:

struct NameRecord {
    var name = ""
    var isFunny = false
}

class AppData: ObservableObject {
    @Published var nameRecord: NameRecord?
}

struct NameView: View {
    @StateObject var appData = AppData()
    
    var body: some View {
        Form {
            if appData.nameRecord != nil {
                // At this point, I *know* that nameRecord is not nil, so
                // I should be able to bind to it.
                TextField("Name", text: $appData.nameRecord.name)
                Toggle("Is Funny", isOn: $appData.nameRecord.isFunny)
            } else {
                // So far as I can tell, this should never happen, but
                // if it does, I will catch it in development, when
                // I see the error message in the constant binding.
                TextField("Name", text: .constant("ERROR: Data is incomplete!"))
                Toggle("Is Funny", isOn: .constant(false))
            }
        }
        .onAppear {
            appData.nameRecord = NameRecord(name: "John")
        }
    }
}

我当然可以看到我错过了一些东西。 Xcode 给出类似错误Value of optional type 'NameRecord?' must be unwrapped to refer to member 'name' of wrapped base type 'NameRecord')并提供了一些没有帮助的 FixIts。

根据用户“workingdog support乌克兰”的回答,我现在知道如何绑定到我需要的部分,但是该解决方案对于具有许多不同类型字段的记录不能很好地扩展。

鉴于可选部分位于中间appData.nameRecord.name,似乎可能有一个解决方案可以执行类似于 SwiftUI 标头中的以下函数可能执行的操作:

public subscript<Subject>(dynamicMember keyPath: WritableKeyPath<Value, Subject>) -> Binding<Subject> { get }

我的 SwiftFu 不够,所以我不知道这是如何工作的,但我怀疑这就是为类似的事情做的工作$appData.nameRecord.name当 nameRecord 不是可选的时。我想要这个函数会导致绑定到的东西.constant当 keyPath 中的任何内容为零时(或者即使它执行了 fatalError,我会使用上面的条件来避免)。如果有一种方法可以获得像以下一样优雅的解决方案,那就太好了乔纳森的回答 https://stackoverflow.com/a/61002589/14840926工作狗也针对类似情况提出了这样的建议。该领域的任何指示将不胜感激!


Binding有一个可失败的初始值设定项,可将Binding<Value?>. https://developer.apple.com/documentation/swiftui/binding/init(_:)-5z9t9

if let nameRecord = Binding($appData.nameRecord) {
  TextField("Name", text: nameRecord.name)
  Toggle("Is Funny", isOn: nameRecord.isFunny)
} else {
  Text("Data is incomplete")
  TextField("Name", text: .constant(""))
  Toggle("Is Funny", isOn: .constant(false))
}

或者,减少重复:

if appData.nameRecord == nil {
  Text("Data is incomplete")
}

let bindings = Binding($appData.nameRecord).map { nameRecord in
  ( name: nameRecord.name,
    isFunny: nameRecord.isFunny
  )
} ?? (
  name: .constant(""),
  isFunny: .constant(false)
)

TextField("Name", text: bindings.name)
Toggle("Is Funny", isOn: bindings.isFunny)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何绑定到 SwiftUI 中可选的数据 的相关文章

随机推荐

  • 预定义值的 Django 模型类方法

    我正在编写一些具有如下模型的 Django 代码 class Status models Model code models IntegerField text models CharField maxlength 255 数据库中存储了大
  • 角度抛出错误未检测到匹配的服务工作者

    当使用 Angular v8 的 Service Worker 时 我总是遇到如下错误 这在 v7 中没有发生 下面是我的配置 包 json angular animations 8 2 14 angular common 8 2 14 a
  • iOS:登录后如何验证用户身份(自动登录)?

    我想使用自动登录功能 因此 当用户打开应用程序时 他会被委托到 登录屏幕 当他成功登录后 他应该被定向到他的帐户 我称之为 帐户屏幕 现在 当用户重新启动应用程序时 他应该直接进入他的帐户 而不会看到 登录屏幕 登录功能在我的项目中已经可以
  • 在 Azure B2C + 离子电容器 InAppBrowser 谷歌登录上获取 403 disallowed_useragent

    当我尝试单击 Azure B2C 登录页面上的 google 登录时 它会将我重定向到另一个页面 并显示错误 403 disallowed useragent 这是我到目前为止所尝试的 添加 尝试添加overrideUserAgent如在文
  • 递归 Java 调用中的空结果

    我正在做以下工作编码蝙蝠问题 http codingbat com prob p137918 给定一个包含一对括号的字符串 递归计算一个仅由括号及其内容组成的新字符串 因此 xyz abc 123 产生 abc parenBit xyz a
  • SSRS隐藏表格单元格中的文本框导致边框消失

    我有一份报告 里面有一张表格 每个表格单元格周围都有边框 我遇到的问题是 如果我隐藏任何单元格中的文本框 边框也会消失 我希望文本框隐藏但仍显示边框 有问题的文本框显示可见性切换图标 因此当我不想看到其中的任何内容时 我无法使用 iif 语
  • VB.NET form.show() 错误

    每次我使用时 form1 show I get Reference to a non shared member requires an object reference 一直有效 不知道出了什么问题 此外 它甚至没有显示在 启动表单 下拉
  • gridView 中的复选框

    我正在 gridview 中使用复选框 为了获取复选框 id 我正在使用以下代码 for int i 0 i lt GridView1 Rows Count i CheckBox chkDelete CheckBox GridView1 R
  • 检查 UIWebView 是否已加载

    我在一个选项卡中有一个 UIWebView 可以在 viewDidLoad 中加载 但是如果用户点击其他选项卡 加载将会中断 并且 void webView UIWebView webView didFailLoadWithError NS
  • 如何发现无意的对象指针比较?

    快速问题 有没有一个好的方法来找到用途 用对象代替isEqual 完整故事 我有一堆类似这样的代码 typedef long DataKey DataKey x DataKey y if x y do stuff 我现在需要更换使用long
  • 如何让盒子始终具有相同的宽度

    这里我必须装箱 看起来像这样 div class dataViewBox div class dataViewBox Download div class dataViewBox DownloadLink span class dataVi
  • MongoDB:检查嵌套数组是否包含子数组

    我有一个数据库建模如下的用例 name XYZ gradeCards id 1234 id of the report card comments GOOD NICE WOW id 2345 comments GOOD NICE TRY 现
  • select2-rails gem 不适用于 Rails4

    我已经尝试过给出的文档select2 rails 宝石 https github com argerim select2 rails 但我的浏览器控制台仍然抛出错误 未捕获的类型错误 select2 不是函数 我在用rails 4 0 1
  • System.IO.Compression.ZipFile .NET 4.5 输出 zip 不适合 Linux/Mac/Java

    使用 NET时System IO Compression ZipFile CreateFromDirectory类结果 zip 在带有正斜杠目录分隔符的系统上被严重提取 原因 zip 名称中包含反斜杠 为了解决这个问题 有一个解决方法 cl
  • Xcode - iPhone - 配置文件与默认钥匙串中的任何有效证书/私钥对不匹配

    我尝试将我的 iPhone 添加到 Xcode4 来测试我的应用程序 我在 Apple Developer Center 中添加了设备并下载了 Provision Profile 我们每月为该帐户支付 99 美元 而且我不是唯一使用该帐户的
  • 如何生成“粗”的贝塞尔曲线?

    我正在寻找一种通过 加厚 贝塞尔曲线以编程方式生成多边形的方法 像这样的东西 我最初的想法是找到直线中的法线 并从中生成多边形 但问题是法线可能会以陡峭的曲线相互交叉 如下所示 是否有任何公式或算法可以从贝塞尔曲线生成多边形 我在互联网上找
  • 如何在 Kotlin 中获取具体化泛型参数的实际类型参数?

    Using 具体化类型参数 https kotlinlang org docs reference inline functions html reified type parameters 可以编写一个内联函数 在运行时通过反射来处理类型
  • java中正十进制值和负十进制值的正则表达式

    负十进制值和正十进制值的正则表达式 以便可以 使用模式和匹配器与字符串匹配以获得正确的实现 谁能给我提供一下吗 0 9 0 9
  • RMI 连接在本地主机上被拒绝

    我正在尝试学习 RMI 编码 当我运行 RMI 的服务器端时 连接被拒绝 这是我的服务器主要方法 public static void main String args throws Exception Implementation imp
  • 如何绑定到 SwiftUI 中可选的数据

    我很好奇 我们如何指定对属于可选部分的状态数据的绑定 例如 struct NameRecord var name var isFunny false class AppData ObservableObject Published var