Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/96.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 自定义属性包装器不能准确反映SwiftUI中我的文本字段的状态,知道为什么吗?_Ios_Swiftui_Combine_Property Wrapper - Fatal编程技术网

Ios 自定义属性包装器不能准确反映SwiftUI中我的文本字段的状态,知道为什么吗?

Ios 自定义属性包装器不能准确反映SwiftUI中我的文本字段的状态,知道为什么吗?,ios,swiftui,combine,property-wrapper,Ios,Swiftui,Combine,Property Wrapper,我已经创建了一个属性包装器,我想在其中插入一些逻辑,“set”值做的是正确的,但是textfield没有用所有大写文本更新。文本字段不应该显示所有大写文本,还是我误解了它的工作原理 这也是一个人为的例子,我的最终目标是在属性包装器中插入更多的逻辑,我只是使用大写的例子来让它工作。我在互联网上到处搜索,没有找到一个有效的解决方案 import SwiftUI import Combine struct ContentView: View { @StateObject var vm = F

我已经创建了一个属性包装器,我想在其中插入一些逻辑,“set”值做的是正确的,但是textfield没有用所有大写文本更新。文本字段不应该显示所有大写文本,还是我误解了它的工作原理

这也是一个人为的例子,我的最终目标是在属性包装器中插入更多的逻辑,我只是使用大写的例子来让它工作。我在互联网上到处搜索,没有找到一个有效的解决方案

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
    }
}
导入快捷界面
进口联合收割机
结构ContentView:View{
@StateObject变量vm=FormDataViewModel()
var body:一些观点{
形式{
TextField(“Name”,text:$vm.Name)
}
}
}
结构内容视图\u预览:PreviewProvider{
静态var预览:一些视图{
ContentView()
}
}
类FormDataViewModel:ObserveObject{
@大写的变量名称:String=“”
}
@房地产经纪人
公共阶级资本化{
@已发布的变量值:字符串
公共变量wrappedValue:String{
获取{value}
set{value=newValue.uppercased()}//打印时显示所有大写字母
}
public var projectedValue:AnyPublisher{
返回$value
.删除任何发布者()
}
public init(wrappedValue:String){
value=wrappedValue
}
}

SwiftUI在
@StateObject
@ObservedObject
中监视
@已发布的
属性,并在这些属性发生更改时触发UI更新

但它并没有深入到
可观察对象的内部。您的
FormDataViewModel
没有任何
@已发布的
属性


您可以做的一件事是模拟
@Published
将对值更改执行的操作

class FormDataViewModel: ObservableObject {
    @Capitalized var name: String = ""
    private var nameObserver: AnyCancellable?

    init() {
        nameObserver = _name.$value.sink {_ in
            self.objectWillChange.send()
        }
    }
}

请尝试。

SwiftUI在
@StateObject
@ObservedObject
中监视
@Published
属性,并在它们发生更改时触发UI更新

但它并没有深入到
可观察对象的内部。您的
FormDataViewModel
没有任何
@已发布的
属性


您可以做的一件事是模拟
@Published
将对值更改执行的操作

class FormDataViewModel: ObservableObject {
    @Capitalized var name: String = ""
    private var nameObserver: AnyCancellable?

    init() {
        nameObserver = _name.$value.sink {_ in
            self.objectWillChange.send()
        }
    }
}

请尝试。

这可以通过标准的
@发布的
来完成,它看起来更简单、更可靠

这里有一个解决方案。使用Xcode 12/iOS 14进行测试

class FormDataViewModel: ObservableObject {
    @Published var name: String = "" {
        didSet {
            let capitalized = name.uppercased()
            if name != capitalized {
                name = capitalized
                objectWillChange.send()
            }
        }
    }
}

这可以通过标准的
@发布的
来实现,它看起来更简单、更可靠

这里有一个解决方案。使用Xcode 12/iOS 14进行测试

class FormDataViewModel: ObservableObject {
    @Published var name: String = "" {
        didSet {
            let capitalized = name.uppercased()
            if name != capitalized {
                name = capitalized
                objectWillChange.send()
            }
        }
    }
}

非常感谢!这起作用了。我的印象是,属性包装器可能是封装可重用逻辑的答案,但似乎我仍然需要使用支持变量来实现发布。非常感谢!这起作用了。我的印象是,属性包装器可能是封装可重用逻辑的答案,但似乎我仍然需要使用支持变量来实现发布。