让 swift @Binding 接受任何符合 `BinaryFloatingPoint` 的值?

Posted

技术标签:

【中文标题】让 swift @Binding 接受任何符合 `BinaryFloatingPoint` 的值?【英文标题】:Let swift @Binding accept any value conforming to `BinaryFloatingPoint`? 【发布时间】:2022-01-22 09:06:13 【问题描述】:

我有以下代码:

class MyModel:ObservableObject 
    
    @Published var time:Double = 0
        



struct ContentView: View 
    
    @StateObject var model = MyModel()

    @State var someValue:Float = 0

    var body: some View 
        
        TView(value: $model.time)

    



struct TView: View 
    
    @Binding var value:Float
    
    var body: some View 
        
        Text("value: \(value)")
        
    

显然代码无法工作,因为绑定需要Float,而model.time 是Double。错误:Cannot convert value of type 'Binding<Double>' to expected argument type 'Binding<Float>'

我想模仿 Slider 的作用,只要它们符合 BinaryFloatingPoint,它就可以绑定到值。

我查看了Swift.Math.FloatingDouble 确实符合BinaryFloatingPoint

...
extension Double : BinaryFloatingPoint 
...

查看滑块初始化:

init<V>(value: Binding<V>, in bounds: ClosedRange<V> = 0...1, onEditingChanged: @escaping (Bool) -> Void =  _ in ) where V : BinaryFloatingPoint, V.Stride : BinaryFloatingPoint

如何更改TView,使其可以绑定到任何符合BinaryFloatingPoint的类型。

我的目标是做 Slider 所做的事情,允许我传入 DoubleFloat 等...

我尝试将TView 更改为:

struct TView: View 
    
    @Binding var value:Float
    
    init<V>(theValue:Binding<V>) where V : BinaryFloatingPoint 
        self._value = theValue
    
    
    var body: some View 
        
        Text("value: \(value)")
        
    

但是,它出错了:Cannot assign value of type 'Binding&lt;V&gt;' to type 'Binding&lt;Float&gt;'

我怎样才能改变事情,使TView 可以绑定到任何符合BinaryFloatingPoint 的值?

【问题讨论】:

【参考方案1】:

将泛型移动到查看声明级别,例如

struct TView<V: BinaryFloatingPoint>: View        // << here !!

    @Binding var value:V                           // << here !!

    init(value:Binding<V>)                        // << here !!
        self._value = value
    

    var body: some View 
        Text("value: \(Double(value))")
    

使用 Xcode 13 / ios 15 测试

【讨论】:

以上是关于让 swift @Binding 接受任何符合 `BinaryFloatingPoint` 的值?的主要内容,如果未能解决你的问题,请参考以下文章

符合自定义协议的通用函数 - Swift

错误:初始化程序 'init(_:)' 要求 'Binding<String>' 符合 'StringProtocol'

Swift3,展开 Optional<Binding>(在 SQLite.swift 中)

Swift 中 @Binding 变量的 didSet

Swift didSet for var 使用 @Binding 在子级中更改

@@ EnvironmentObject初始化程序'init(_ :)'要求'Binding'符合'StringProtocol'