如何修复 TextField Binding <String> 以在 SwiftUI 中显示和编辑
Posted
技术标签:
【中文标题】如何修复 TextField Binding <String> 以在 SwiftUI 中显示和编辑【英文标题】:How to fix TextField Binding <String> to show and edit in SwiftUI 【发布时间】:2021-05-19 04:50:31 【问题描述】:我想在TextField
中显示文本并能够对其进行编辑。但是我在绑定它时遇到了问题。这是我的代码:
struct DataView: View
@ObservedObject private var dataPresenter = DataPresenter()
var body: some View
VStack
TextField("Name", text: $dataPresenter.data?.name ?? "") // This is the error
.onAppear(perform:
dataPresenter.getData()
)
class DataPresenter: ObservableObject
@Injected private var getDataInteractor: GetDataInteractor
@Injected private var cancellables: Set<AnyCancellable>
@Published var data: GetDataResp?
func getData()
getDataInteractor.execute()
.sink error in
print("Error:", error)
receiveValue: response in
if response.errorCode == "00"
print(response)
self.data = response
.store(in: &cancellables)
struct GetDataResp: Codable, Equatable
var name : String?
var address : String?
var email : String?
enum CodingKeys: String, CodingKey
case name = "name"
case address = "address"
case email = "email"
init(from decoder: Decoder) throws
let values = try decoder.container(keyedBy: CodingKeys.self)
name = try values.decodeIfPresent(String.self, forKey: .name)
address = try values.decodeIfPresent(String.self, forKey: .address)
email = try values.decodeIfPresent(String.self, forKey: .email)
当我没有在$dataPresenter.data.name ?? ""
中使用?
时,我总是会收到这样的错误:
然后,当我用?
修复它时,我收到更多这样的错误:
我陷入了这个错误循环,使用force unwrap
会使应用程序崩溃。我有比名字更多的变量,所以我不能只在响应中self.name = response.name ?? ""
。我该如何解决这个问题?
任何建议将不胜感激。
【问题讨论】:
【参考方案1】:TextField
需要 Binding
,而不仅仅是 String
。因此,当您提供 ""
时,如果 Binding
为 nil,您最终会得到非等效类型(Binding<String>
与 String
)。
要解决这个问题,您可能需要创建一个自定义绑定来处理 data
是 nil
的情况。
这是一种可能的解决方案:
struct DataView: View
@ObservedObject private var dataPresenter = DataPresenter()
var body: some View
VStack
Text(dataPresenter.data?.name ?? "Empty")
TextField("Name", text: dataPresenter.nonOptionalNameBinding())
struct GetDataResp
var name : String
class DataPresenter: ObservableObject
@Published var data: GetDataResp?
func nonOptionalNameBinding() -> Binding<String>
.init
return self.data?.name ?? ""
set: newValue in
if self.data == nil
self.data = GetDataResp(name: newValue)
else
self.data?.name = newValue
您可能需要根据您的需要在set:
部分以不同方式处理这种情况。而且,当然,我删除了GetDataResp
,我认为它比我那里的更详细,但这应该让你开始。
更新,基于 cmets:
struct GetDataResp: Codable, Equatable
var name : String?
var address : String?
var email : String?
struct DataView: View
@ObservedObject private var dataPresenter = DataPresenter()
var body: some View
VStack
Text(dataPresenter.data?.name ?? "Empty")
TextField("Name", text: dataPresenter.nonOptionalBinding(keyPath: \.name))
TextField("Address", text: dataPresenter.nonOptionalBinding(keyPath: \.address))
TextField("Email", text: dataPresenter.nonOptionalBinding(keyPath: \.email))
class DataPresenter: ObservableObject
@Published var data: GetDataResp?
func nonOptionalBinding(keyPath: WritableKeyPath<GetDataResp,String?>) -> Binding<String>
.init
return self.data?[keyPath: keyPath] ?? ""
set: newValue in
if self.data == nil
self.data = GetDataResp()
self.data?[keyPath: keyPath] = newValue
【讨论】:
我仍然被困在这里,因为GetDataResp
已经回复了姓名、地址、日期、电子邮件等。我不能做else
部分。当我添加一个参数时,它不能分配,因为它是一个 let 常量。 func nonOptionalNameBinding(data: String?) -> Binding<String> .init return data ?? "" set: newValue in if self.dataMerchant == nil print("empty", newValue) else data = newValue
我希望我可以使用DataView
中的参数,这样我就可以根据需要创建文本字段
不太清楚您所说的“我希望我可以使用 DataView 中的参数,以便我可以根据需要创建文本字段”是什么意思。如果你想让它成为非可选的,GetDataResp
将不得不是非可选的。但是,如果你保持它是可选的,你将不得不做这样的事情。如果您包含 GetDataResp
的代码(在您的原始问题中 - cmets 中的代码效果不佳),我可以尝试向您展示如何使用它。
嘿伙计,刚刚更新了GetDataResp
,检查我的代码。谢谢大佬
看起来不会改变我对我的回答。我仍然不知道您评论中的代码在做什么。例如,dataMerchat
是什么?您的问题中从未提及。
好吧,在你的方法中,else
是:self.data?.name = newValue
。但是,除了名称之外,我还有其他几个变量,例如地址、电子邮件等。我的意思是,当您在 DataView
中使用 self.data?.name = newValue
部分时,它是硬编码的。如何分配self.data?.address = newValue
等?您是在告诉我为 1 个变量创建 1 个方法吗?希望我能让你清楚我还在挣扎什么。感谢您的回答以上是关于如何修复 TextField Binding <String> 以在 SwiftUI 中显示和编辑的主要内容,如果未能解决你的问题,请参考以下文章
如何在 panGesture 之后修复新的 textField 位置?
当您点击另一个 TextField 时,如何获取要更新的 TextField 的绑定值?