如何将模型中的 Float 值绑定到 SwiftUI 视图中的 @Binding:Float 属性

How to bind a Float value from a model to a @Binding:Float property in a SwiftUI View

我有一个 Circular ProgressBar View,它将 @Binding var progress: Float 属性 作为其进度值,我希望能够从 TaskList 中恭敬地反对。我尝试将 progress = task.progress 的值从 Task 对象分配给 ContentView 中的 @State 属性 但当然这不能在视图中完成(请参见下面的注释代码行)。

如何将每个任务的进度值分别传递到 ProgressBar 视图?

任务模型:

class Task:Identifiable{
    var name = ""
    var progress: Float = 0.0
    
    init(name:String, progress:Float){
        self.name = name
        self.progress = progress
    }
}

内容视图

var tasks = [Task(name: "Ketchen Floors", progress: 0.5),
            Task(name: "Install Windows", progress: 0.75)]

struct ContentView: View {
    @State var progress:Float = 0.15
    
    var body: some View {
        List {
            ForEach(tasks) { task in
                // outputs error: Type '()' cannot conform to 'View'
                // progress = task.progress 
                HStack{
                    Text(task.name)
                    // here $progress value shoud come from task.progress
                    ProgressBar(progress: $progress)
                }
            }
        }
    }
}

进度条视图

struct ProgressBar: View {
    @Binding var progress: Float
    
    var body: some View {
        ZStack {
            Circle()
                .stroke(lineWidth:5.0)
                .opacity(0.3)
                .foregroundColor(Color.orange)
            
            Circle()
                .trim(from: 0.0, to: CGFloat(min(self.progress, 1.0)))
                .stroke(style: StrokeStyle(lineWidth: 5.0, lineCap: .round, lineJoin: .round))
                .foregroundColor(Color.orange)
                .rotationEffect(Angle(degrees: 270.0))
                .animation(.linear, value: progress)

            VStack{
                Text(String(format: "%.0f %%", min(self.progress, 1.0)*100.0))
                    .font(.caption2)
            }
        }
    }
}

屏幕

如您所见,每个项目都显示初始的 15% 进度值,这并不奇怪。同样,我想要的是能够分别使用每个任务的值,50% 的厨房地板和 75% 的安装 Windows。

首先,将您的数组添加到 ContentView 中并使其成为 @State

之后就可以直接按任务绑定var了

struct ContentView: View {
    @State var progress:Float = 0.15
    
    @State var tasks = [Task(name: "Ketchen Floors", progress: 0.5),
                 Task(name: "Install Windows", progress: 0.75)] // <---- Here
    
    var body: some View {
        List {
            ForEach($tasks) { $task in // <---- Here
                // outputs error: Type '()' cannot conform to 'View'
                // progress = task.progress
                HStack{
                    Text(task.name)
                    // here $progress value shoud come from task.progress
                    ProgressBar(progress: $task.progress) // <---- Here
                }
            }
        }
    }
}