How can I cast an @Binding in Swift
I don’t think there’s a way to cast but you can create another Binding based on the first one:
import SwiftUI
var d = 1.0
// Create a Binding<Double> (for lack of another source)
var bd = Binding<Double>(get: { d }, set: { d = $0 })
// "Convert" to Binding<Int> by recreating another Binding
let bi = Binding<Int>(get: { Int(bd.wrappedValue) },
set: { bd.wrappedValue = Double($0) })
Using @Binding with type casting in swiftui
The Binding
type allow for both reading and writing. Since you can't safely read the value of an AabbData
and assume it's an AbData
this cannot work.
If you want to try anyway, then you'll have to create a new Binding (possibly with the Binding(get:set:)
constructor) that does the casting there.
For example, noting that this forced cast is probably not advisable for all the usual reasons:
let binding = Binding<AbData>(get: {
data.aabbData[index] as! AbData
}, set: {
data.aabbData[index] = $0
})
Casting a bindingDouble to type Int - Swift UI
@ObservedObject is a property wrapper around the actual object. So, to access the non-binding values of those properties, you could use wrappedValue
:
func randomise(startNumber: Int, endNumber: Int) -> Int{
let startNum = $value.startNumber
let endNum = $value.endNumber
let generated = arc4random_uniform(UInt32(endNum.wrappedValue - startNum.wrappedValue)) + UInt32(startNum.wrappedValue)
return Int(generated)
}
OR
You could get rid of the $
when you access your value variable, removing the Binding that way:
func randomise(startNumber: Int, endNumber: Int) -> Int{
let startNum = value.startNumber
let endNum = value.endNumber
let generated = arc4random_uniform(UInt32(endNum - startNum)) + UInt32(startNum)
return Int(generated)
}
Converting optional Binding to non-optional Binding
Binding
has an associated type Value
already, so by trying to use T
, you're putting a new generic on top of Value
, which already exists.
But, you will still end up using T
because you'll want to constrain Value
to scenarios where it is Optional:
extension Binding {
func safeBinding<T>(defaultValue: T) -> Binding<T> where Value == Optional<T> {
.init {
self.wrappedValue ?? defaultValue
} set: { newValue in
self.wrappedValue = newValue
}
}
}
As noted in the comments, the Xcode compiler has difficulty if just Binding.init
is used (note that I used just .init
). This can be solved by explicitly using Binding<T>.init
:
extension Binding {
func safeBinding<T>(defaultValue: T) -> Binding<T> where Value == Optional<T> {
Binding<T>.init {
self.wrappedValue ?? defaultValue
} set: { newValue in
self.wrappedValue = newValue
}
}
}
Cannot convert value of type 'BindingString?' to expected argument type 'BindingString'
Because all core data fields are optional, you have to wrap it into Binding
. And as you're using core data and may face a lot of optionals, you can create an extension:
extension Binding {
func toUnwrapped<T>(defaultValue: T) -> Binding<T> where Value == Optional<T> {
Binding<T>(get: { self.wrappedValue ?? defaultValue }, set: { self.wrappedValue = $0 })
}
}
Use it like this:
TextField("title", text: $text.name.toUnwrapped(defaultValue: ""))
Related Topics
Creating a Type Bound to a Certain Range in Swift
Scntext Alignment Not Working in iOS
Swiftui 2 Pop to Root View with No Scene Delegate
Prevent Error "Funk" Sound in Event Monitor Os X
@Objc Redundancy When Having @Objcmembers Private Dynamic Var
How to Suppress Warnings in Swift 3
Getting an Issue with Upgrade to Xcode 10.2
Accessing Swift Set Elements by Their Hash Value
Module Compiled with Swift 4.0 Cannot Be Imported in Swift 3.0.2
Gcd Pattern for Chaining Async Operations While Piping the Results
Xcode UI Test:Accessibility Query Fail on Uitableviewcell
Getting a Segmentation Fault: 11 with Swift 5.2 When Using Filemanager.Default.Currentdirectorypath
iOS Swift: Unsafemutableaddressor Crash on iOS 8
Can Not Conform to Protocol by Creating Extension with Where Clauses
How to Copy Skspritenode with Skphysicsbody