首页 > 解决方案 > 滑块阅读字典键 SwiftUI

问题描述

如何在滑块上循环我的 Dic 键?滑块行为是将第一个键除以最后一个键。我想要的只是循环通过键值然后以某种方式返回值的值......

struct ContentView: View {
    
    @State private var currentValue = 0.0
    @ObservedObject var scoreModel = ScoreModel()
    var body: some View {
        
        let endValue = Dictionary(uniqueKeysWithValues:
            scoreModel.eventMDL.map { key, value in (key, value) })
                
        return VStack {
            Slider(value: $currentValue, in: endValue.keys.sorted()[1]...endValue.keys.sorted()[27])
                .rotationEffect(Angle(degrees: -90))
            Spacer()
            Text("\(currentValue, specifier: "%.0f")")
        }
        .frame(height: 280)
    }
}

该模型:

@Published var eventMDL = [340.0: 100.0,
                               330.0: 97.0,
                               320.0: 94.0,
                               310.0: 92.0,
                               300.0: 90.0,
                               290.0: 88.0,
                               280.0: 86.0,
                               270.0: 84.0,
                               260.0: 82.0,
                               250.0: 80.0,
                               240.0: 78.0,
                               230.0: 76.0,
                               220.0: 74.0,
                               210.0: 72.0,
                               200.0: 70.0,
                               190.0: 68.0,
                               180.0: 65.0,
                               170.0: 64.0,
                               160.0: 63.0,
                               150.0: 62.0,
                               140.0: 60.0,
                               130.0: 50.0,
                               120.0: 40.0,
                               110.0: 30.0,
                               100.0: 20.0,
                               90.0: 10.0,
                               80.0: 0.0,
                               0.0 : 0.0]

标签: dictionarysliderswiftui

解决方案


首先,我建议使用您的键创建一个数组并对其进行排序。由于您已经使用了一个@Published属性,因此我在以下位置添加了更新此数组didSet

class ScoreModel: ObservableObject {
    @Published var eventMDL = [
        340.0: 100.0,
        ...
        0.0: 0.0,
    ] {
        didSet {
            eventMDLKeysSorted = eventMDL.keys.reversed().sorted()
        }
    }

    lazy var eventMDLKeysSorted: [Double] = eventMDL.keys.reversed().sorted()
}

但是,如果eventMDL字典只分配一次,则不需要@Published

class ScoreModel: ObservableObject {
    let eventMDL = [
        340.0: 100.0,
        ...
        0.0: 0.0,
    ]

    lazy var eventMDLKeysSorted: [Double] = eventMDL.keys.reversed().sorted()
}

然后跟踪当前而不是

@State private var currentKey = 0.0

然后创建一个范围:

var firstKey: Double {
    scoreModel.eventMDLKeysSorted[1]
}

var lastKey: Double {
    scoreModel.eventMDLKeysSorted[scoreModel.eventMDLKeysSorted.count - 1]
}

并将其设置为 Slider 添加步长10(后续键之间的差异):

Slider(value: $currentKey, in: firstKey...lastKey, step: 10)

然后我们访问当前值:

var currentValue: Double {
    scoreModel.eventMDL[currentKey]! 
    // or provide a default value
    // or make currentValue optional
}

总结一下,这就是你的ContentView样子:

struct ContentView: View {
    @ObservedObject var scoreModel = ScoreModel()
    @State private var currentKey = 0.0

    var firstKey: Double {
        scoreModel.eventMDLKeysSorted[1]
    }

    var lastKey: Double {
        scoreModel.eventMDLKeysSorted[scoreModel.eventMDLKeysSorted.count - 1]
    }

    var currentValue: Double {
        return scoreModel.eventMDL[currentKey]!
    }

    var body: some View {
        VStack {
            Slider(value: $currentKey, in: firstKey...lastKey, step: 10)
                .rotationEffect(Angle(degrees: -90))
            Spacer()
            Text("\(currentValue, specifier: "%.0f")")
        }
        .frame(height: 280)
    }
}

此外,您可能需要设置 Slider 的起始位置:

init() {
     _currentKey = .init(initialValue: scoreModel.eventMDLKeysSorted[1])
}

推荐阅读