更新状态变量不会更新 TextField 的文本
Updating state variable does not update TextField's text
我有一个 TextField
表格,应该根据特定的用户操作动态更新。由于我将此 SwiftUI
视图嵌入到 UIKit
视图中,因此我不得不对其进行一些自定义:
/// Base TextField
struct CustomTextFieldSUI: View {
@State var text: String = ""
var placeholder: Text
var disableAutoCorrect = false
var isSecure: Bool = false
var onEditingChanged: (Bool) -> () = { _ in }
var onCommit: () -> () = { }
var onChange: (String) -> Void
var keyboardType: UIKeyboardType = .default
var contentType: UITextContentType?
var body: some View {
ZStack(alignment: .leading) {
if text.isEmpty {
placeholder
.foregroundColor(placeholderColor)
}
if isSecure {
SecureField("", text: $text.onChange({ newText in
onChange(newText)
}), onCommit: onCommit)
.foregroundColor(foregroundColor)
} else {
TextField("", text: $text.onChange({ newText in
onChange(newText)
}), onEditingChanged: onEditingChanged, onCommit: onCommit)
.foregroundColor(foregroundColor)
.disableAutocorrection(disableAutoCorrect)
.keyboardType(keyboardType)
.textContentType(contentType)
.autocapitalization(keyboardType == UIKeyboardType.emailAddress ? .none : .words)
}
}
}
}
它本身用于创建另一个自定义视图:
struct TextFieldWithIconSUI: View {
@State var text: String = ""
@State var isSecure: Bool
let icon: Image
let placeholder: String
var prompt: String? = nil
let disableAutoCorrect: Bool = false
var keyboardType: UIKeyboardType = .default
var contentType: UITextContentType?
var onEditingChanged: (Bool) -> () = { _ in }
var onCommit: () -> () = { }
var onChange: (String) -> Void
var body: some View {
VStack {
ZStack {
RoundedRectangle(cornerRadius: 0)
HStack(alignment: .center, spacing: iconSpacing) {
CustomTextFieldSUI(
text: text,
placeholder: Text(placeholder),
placeholderColor: .gray,
foregroundColor: .white,
disableAutoCorrect: disableAutoCorrect,
isSecure: isSecure, onEditingChanged: onEditingChanged, onCommit: onCommit, onChange: { newText in
text = newText
onChange(newText)
},
keyboardType: keyboardType,
contentType: contentType)
icon
.scaledToFit()
.onTapGesture {
isSecure.toggle()
}
}
}
if (prompt != nil) {
VStack(alignment: .leading) {
Text(prompt!)
.padding(.leading, 10)
.padding(.top, -2)
.frame(maxWidth: .infinity, alignment: .leading)
.lineLimit(2)
}
}
}
}
}
现在在客户端视图中,我将它与列表一起使用来创建一个简单的自动完成列表:
TextFieldWithIconSUI(text: displayCountryName, isSecure: false, icon: emptyImage, placeholder: "Country", keyboardType: .default, contentType: .countryName, onEditingChanged: { changed in
self.shouldShowCountriesList = changed
}, onChange: { text in
self.displayCountryName = text
self.shouldShowCountriesList = true
})
在我的表单中的某处,我使用该 TextField 中的文本来显示自动更正列表。列表已显示,但当我 select 一个项目时,它不会更新 TextField 的文本,在调试器中状态变量已更新,但 UI 未显示新值。
if shouldShowCountriesList {
VStack(alignment: .leading) {
List {
ForEach(countriesList.filter { [=13=].lowercased().hasPrefix(country.object.lowercased()) }.prefix(3), id: \.self) { countryName in
Text(countryName)
.onTapGesture {
self.displayCountryName = countryName
self.shouldShowCountriesList = false
}
}
}
}
}
我不得不为我的自定义文本字段使用绑定变量:
struct CustomTextFieldSUI: View {
var text: Binding<String>
var placeholder: Text
var placeholderColor: Color
var foregroundColor: Color
var disableAutoCorrect = false
var isSecure: Bool = false
var onEditingChanged: (Bool) -> () = { _ in }
var onCommit: () -> () = { }
var onChange: (String) -> Void
var keyboardType: UIKeyboardType = .default
var contentType: UITextContentType?
var body: some View {
let bindingText = Binding(
get: {
self.text.wrappedValue
},
set: {
self.text.wrappedValue = [=10=]
onChange([=10=])
})
ZStack(alignment: .leading) {
if text.wrappedValue.isEmpty {
placeholder
.foregroundColor(placeholderColor)
}
if isSecure {
SecureField("", text: bindingText, onCommit: onCommit)
.foregroundColor(foregroundColor)
} else {
TextField("", text: bindingText, onEditingChanged: onEditingChanged, onCommit: onCommit)
.foregroundColor(foregroundColor)
.disableAutocorrection(disableAutoCorrect)
.keyboardType(keyboardType)
.textContentType(contentType)
.autocapitalization(keyboardType == UIKeyboardType.emailAddress ? .none : .words)
}
}
}
}
并从主机传递绑定变量。
我有一个 TextField
表格,应该根据特定的用户操作动态更新。由于我将此 SwiftUI
视图嵌入到 UIKit
视图中,因此我不得不对其进行一些自定义:
/// Base TextField
struct CustomTextFieldSUI: View {
@State var text: String = ""
var placeholder: Text
var disableAutoCorrect = false
var isSecure: Bool = false
var onEditingChanged: (Bool) -> () = { _ in }
var onCommit: () -> () = { }
var onChange: (String) -> Void
var keyboardType: UIKeyboardType = .default
var contentType: UITextContentType?
var body: some View {
ZStack(alignment: .leading) {
if text.isEmpty {
placeholder
.foregroundColor(placeholderColor)
}
if isSecure {
SecureField("", text: $text.onChange({ newText in
onChange(newText)
}), onCommit: onCommit)
.foregroundColor(foregroundColor)
} else {
TextField("", text: $text.onChange({ newText in
onChange(newText)
}), onEditingChanged: onEditingChanged, onCommit: onCommit)
.foregroundColor(foregroundColor)
.disableAutocorrection(disableAutoCorrect)
.keyboardType(keyboardType)
.textContentType(contentType)
.autocapitalization(keyboardType == UIKeyboardType.emailAddress ? .none : .words)
}
}
}
}
它本身用于创建另一个自定义视图:
struct TextFieldWithIconSUI: View {
@State var text: String = ""
@State var isSecure: Bool
let icon: Image
let placeholder: String
var prompt: String? = nil
let disableAutoCorrect: Bool = false
var keyboardType: UIKeyboardType = .default
var contentType: UITextContentType?
var onEditingChanged: (Bool) -> () = { _ in }
var onCommit: () -> () = { }
var onChange: (String) -> Void
var body: some View {
VStack {
ZStack {
RoundedRectangle(cornerRadius: 0)
HStack(alignment: .center, spacing: iconSpacing) {
CustomTextFieldSUI(
text: text,
placeholder: Text(placeholder),
placeholderColor: .gray,
foregroundColor: .white,
disableAutoCorrect: disableAutoCorrect,
isSecure: isSecure, onEditingChanged: onEditingChanged, onCommit: onCommit, onChange: { newText in
text = newText
onChange(newText)
},
keyboardType: keyboardType,
contentType: contentType)
icon
.scaledToFit()
.onTapGesture {
isSecure.toggle()
}
}
}
if (prompt != nil) {
VStack(alignment: .leading) {
Text(prompt!)
.padding(.leading, 10)
.padding(.top, -2)
.frame(maxWidth: .infinity, alignment: .leading)
.lineLimit(2)
}
}
}
}
}
现在在客户端视图中,我将它与列表一起使用来创建一个简单的自动完成列表:
TextFieldWithIconSUI(text: displayCountryName, isSecure: false, icon: emptyImage, placeholder: "Country", keyboardType: .default, contentType: .countryName, onEditingChanged: { changed in
self.shouldShowCountriesList = changed
}, onChange: { text in
self.displayCountryName = text
self.shouldShowCountriesList = true
})
在我的表单中的某处,我使用该 TextField 中的文本来显示自动更正列表。列表已显示,但当我 select 一个项目时,它不会更新 TextField 的文本,在调试器中状态变量已更新,但 UI 未显示新值。
if shouldShowCountriesList {
VStack(alignment: .leading) {
List {
ForEach(countriesList.filter { [=13=].lowercased().hasPrefix(country.object.lowercased()) }.prefix(3), id: \.self) { countryName in
Text(countryName)
.onTapGesture {
self.displayCountryName = countryName
self.shouldShowCountriesList = false
}
}
}
}
}
我不得不为我的自定义文本字段使用绑定变量:
struct CustomTextFieldSUI: View {
var text: Binding<String>
var placeholder: Text
var placeholderColor: Color
var foregroundColor: Color
var disableAutoCorrect = false
var isSecure: Bool = false
var onEditingChanged: (Bool) -> () = { _ in }
var onCommit: () -> () = { }
var onChange: (String) -> Void
var keyboardType: UIKeyboardType = .default
var contentType: UITextContentType?
var body: some View {
let bindingText = Binding(
get: {
self.text.wrappedValue
},
set: {
self.text.wrappedValue = [=10=]
onChange([=10=])
})
ZStack(alignment: .leading) {
if text.wrappedValue.isEmpty {
placeholder
.foregroundColor(placeholderColor)
}
if isSecure {
SecureField("", text: bindingText, onCommit: onCommit)
.foregroundColor(foregroundColor)
} else {
TextField("", text: bindingText, onEditingChanged: onEditingChanged, onCommit: onCommit)
.foregroundColor(foregroundColor)
.disableAutocorrection(disableAutoCorrect)
.keyboardType(keyboardType)
.textContentType(contentType)
.autocapitalization(keyboardType == UIKeyboardType.emailAddress ? .none : .words)
}
}
}
}
并从主机传递绑定变量。