首页 > 解决方案 > 如何翻译视图中的绑定?

问题描述

我创建了一个用于设置时间(分钟和秒)的视图。它使用两个绑定到两个状态变量的选轮器。

现在我想在应用程序的不同位置使用该视图,但我不喜欢当时有两个单独变量的界面。相反,我希望只有一个绑定变量以秒为单位保存时间(因此 time = 185 将转换为 3 分 5 秒)。

绑定之间是否可以有某种“适配器”?

这是视图:

import SwiftUI

struct TimePicker: View {
    var minutes: Binding<Int>
    var seconds: Binding<Int>

    var body: some View {
        HStack() {
            Spacer()
            Picker(selection: minutes, label: EmptyView()) {
                ForEach((0...9), id: \.self) { ix in
                    Text("\(ix)").tag(ix)
                }
                }.pickerStyle(WheelPickerStyle()).frame(width: 50).clipped()
            Text("Min.")
            Picker(selection: seconds, label: EmptyView()) {
                ForEach((0...59), id: \.self) { ix in
                    Text("\(ix)").tag(ix)
                }
                }.pickerStyle(WheelPickerStyle()).frame(width: 50).clipped()
            Text("Sec.")
            Spacer()
        }
    }
}

标签: bindingswiftuicombine

解决方案


这是基于Binding(get:set:)

struct TimePicker: View {
    @Binding var total: Int

    var minutes: Binding<Int> {
        Binding<Int>(get: { self._total.wrappedValue / 60 },
                     set: { self._total.wrappedValue = self._total.wrappedValue % 60 + $0 * 60 })
    }

    var seconds: Binding<Int> {
        Binding<Int>(get: { self._total.wrappedValue % 60 },
                     set: { self._total.wrappedValue = (self._total.wrappedValue / 60) * 60 + $0 })
    }

    var body: some View {
        HStack() {
            Spacer()
            Picker(selection: minutes, label: EmptyView()) {
                ForEach((0...9), id: \.self) { ix in
                    Text("\(ix)").tag(ix)
                }
            }.pickerStyle(WheelPickerStyle()).frame(width: 50).clipped()
            Text("Min.")
            Picker(selection: seconds, label: EmptyView()) {
                ForEach((0...59), id: \.self) { ix in
                    Text("\(ix)").tag(ix)
                }
                }.pickerStyle(WheelPickerStyle()).frame(width: 50).clipped()
            Text("Sec.")
            Spacer()
        }.frame(height: 200)
    }
}

struct TestTimePicker: View {

    @State var seconds = 185
    var body: some View {
        VStack {
            Text("Current: \(seconds)")
            TimePicker(total: $seconds)
        }
    }

}

struct TestConditionalPicker_Previews: PreviewProvider {
    static var previews: some View {
        TestTimePicker()
    }
}

推荐阅读