自定义 属性 包装器无法准确反映 SwiftUI 中我的 TextField 的状态,知道为什么吗?
Custom property wrapper not accurately reflecting the state of my TextField in SwiftUI, any idea why?
我已经创建了一个 属性 包装器,我想在其中插入一些逻辑,并且“设置”值正在做正确的事情,但是文本字段没有更新为所有大写文本。文本字段不应该显示所有大写文本还是我误解了这是如何工作的?
这也是一个人为的例子,我的最终目标是在 属性 包装器中插入更多的逻辑,我只是使用大写的例子来让它工作。我在整个互联网上进行了搜索,但没有找到可行的解决方案。
import SwiftUI
import Combine
struct ContentView: View {
@StateObject var vm = FormDataViewModel()
var body: some View {
Form {
TextField("Name", text: $vm.name)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
class FormDataViewModel: ObservableObject {
@Capitalized var name: String = ""
}
@propertyWrapper
public class Capitalized {
@Published var value: String
public var wrappedValue: String {
get { value }
set { value = newValue.uppercased() } //Printing this shows all caps
}
public var projectedValue: AnyPublisher<String, Never> {
return $value
.eraseToAnyPublisher()
}
public init(wrappedValue: String) {
value = wrappedValue
}
}
SwiftUI 监视 @StateObject
或 @ObservedObject
中的 @Published
属性并触发 UI 更新它们的变化。
但它并没有深入ObservableObject
。您的 FormDataViewModel
没有任何 @Published
属性。
您可以做的一件事是模拟 @Published
对值变化的影响。
class FormDataViewModel: ObservableObject {
@Capitalized var name: String = ""
private var nameObserver: AnyCancellable?
init() {
nameObserver = _name.$value.sink {_ in
self.objectWillChange.send()
}
}
}
请尝试。
这可以用看起来更简单、更可靠的标准 @Published
来完成。
这是一个解决方案。测试 Xcode 12 / iOS 14.
class FormDataViewModel: ObservableObject {
@Published var name: String = "" {
didSet {
let capitalized = name.uppercased()
if name != capitalized {
name = capitalized
objectWillChange.send()
}
}
}
}
我已经创建了一个 属性 包装器,我想在其中插入一些逻辑,并且“设置”值正在做正确的事情,但是文本字段没有更新为所有大写文本。文本字段不应该显示所有大写文本还是我误解了这是如何工作的?
这也是一个人为的例子,我的最终目标是在 属性 包装器中插入更多的逻辑,我只是使用大写的例子来让它工作。我在整个互联网上进行了搜索,但没有找到可行的解决方案。
import SwiftUI
import Combine
struct ContentView: View {
@StateObject var vm = FormDataViewModel()
var body: some View {
Form {
TextField("Name", text: $vm.name)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
class FormDataViewModel: ObservableObject {
@Capitalized var name: String = ""
}
@propertyWrapper
public class Capitalized {
@Published var value: String
public var wrappedValue: String {
get { value }
set { value = newValue.uppercased() } //Printing this shows all caps
}
public var projectedValue: AnyPublisher<String, Never> {
return $value
.eraseToAnyPublisher()
}
public init(wrappedValue: String) {
value = wrappedValue
}
}
SwiftUI 监视 @StateObject
或 @ObservedObject
中的 @Published
属性并触发 UI 更新它们的变化。
但它并没有深入ObservableObject
。您的 FormDataViewModel
没有任何 @Published
属性。
您可以做的一件事是模拟 @Published
对值变化的影响。
class FormDataViewModel: ObservableObject {
@Capitalized var name: String = ""
private var nameObserver: AnyCancellable?
init() {
nameObserver = _name.$value.sink {_ in
self.objectWillChange.send()
}
}
}
请尝试。
这可以用看起来更简单、更可靠的标准 @Published
来完成。
这是一个解决方案。测试 Xcode 12 / iOS 14.
class FormDataViewModel: ObservableObject {
@Published var name: String = "" {
didSet {
let capitalized = name.uppercased()
if name != capitalized {
name = capitalized
objectWillChange.send()
}
}
}
}