如何在 SwiftUI 中将 Binding<String?> 转换为<String> Binding



如何转换绑定<字符串>到SwiftUI 中的绑定

变量声明为:

@Binding var name: String?

这取决于你在哪里使用它,但很可能,你需要一些东西,比如

Binding(name) ?? .constant("")

在某些情况下,可能需要在适当的位置创建代理绑定,如https://stackoverflow.com/a/59274498/12299030.

对于带有参数的场景,您可以使用中的方法https://stackoverflow.com/a/62217832/12299030.

对于ValueOptional的情况,您可以使用默认值创建自己的Binding Extension

Swift 5扩展

extension Binding where Value: Equatable {


/// Given a binding to an optional value, creates a non-optional binding that projects
/// the unwrapped value. If the given optional binding contains `nil`, then the supplied
/// value is assigned to it before the projected binding is generated.
///
/// This allows for one-line use of optional bindings, which is very useful for CoreData types
/// which are non-optional in the model schema but which are still declared nullable and may
/// be nil at runtime before an initial value has been set.
///
///     class Thing: NSManagedObject {
///         @NSManaged var name: String?
///     }
///     struct MyView: View {
///         @State var thing = Thing(name: "Bob")
///         var body: some View {
///             TextField("Name", text: .bind($thing.name, ""))
///         }
///     }
///
/// - note: From experimentation, it seems that a binding created from an `@State` variable
/// is not immediately 'writable'. There is seemingly some work done by SwiftUI following the render pass
/// to make newly-created or assigned bindings modifiable, so simply assigning to
/// `source.wrappedValue` inside `init` is not likely to have any effect. The implementation
/// has been designed to work around this (we don't assume that we can unsafely-unwrap even after
/// assigning a non-`nil` value), but a side-effect is that if the binding is never written to outside of
/// the getter, then there is no guarantee that the underlying value will become non-`nil`.
@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
static func bindOptional(_ source: Binding<Value?>, _ defaultValue: Value) -> Binding<Value> {
self.init(get: {
source.wrappedValue ?? defaultValue
}, set: {
source.wrappedValue = ($0 as? String) == "" ? nil : $0
})
}
}

用法

struct ContentView: View { 
@Binding var title: String?
var body: some View { 
TextField("Title Value", text: .bindOptional($title, "Default Title"))
}
}

相关内容

最新更新