我有一个名为“score”的 Int 属性的视图,我想用滑块调整它。
struct IntSlider: View {
@State var score:Int = 0
var body: some View {
VStack{
Text(score.description)
Slider(value: $score, in: 0.0...10.0, step: 1.0)
}
}
}
Run Code Online (Sandbox Code Playgroud)
但是 SwiftUI 的 Slider 仅适用于双打/浮动。
我怎样才能让它与我的整数一起工作?
Mar*_*eIV 22
作为本页其他答案的替代方案,我提出了一种解决方案,该解决方案利用类型约束的通用扩展方法来简化调用站点。这是您需要做的所有事情的示例:
Slider(value: .convert(from: $count), in: 1...8, step: 1)
Run Code Online (Sandbox Code Playgroud)
由于泛型/重载,它会自动将任何 Int
类型(例如Int
, Int8
, Int64
)转换为任何 Float
类型(例如Float
, Float16
, CGFloat
, Double
),反之亦然。
将扩展添加到项目(或项目引用的包中)后,您只需调用.convert
任何绑定站点,它就会“正常工作”。
不需要任何其他东西来使用它(即没有“代理”结构、变量或其他本地项目来扰乱您的视图。)您只需直接内联使用它(见上文。)
当在任何需要 的地方时Binding
,只需键入.
,代码完成就会自动建议convert
作为一个选项。这是有效的,因为每个扩展方法都是在 上定义的Binding
,并且它返回 a Binding
(即Self
) 作为其结果类型,从而使其可以被自动完成系统发现。(对于任何类型的任何此类静态方法都是如此。)
这是前面提到的扩展方法......
public extension Binding {
static func convert<TInt, TFloat>(from intBinding: Binding<TInt>) -> Binding<TFloat>
where TInt: BinaryInteger,
TFloat: BinaryFloatingPoint{
Binding<TFloat> (
get: { TFloat(intBinding.wrappedValue) },
set: { intBinding.wrappedValue = TInt($0) }
)
}
static func convert<TFloat, TInt>(from floatBinding: Binding<TFloat>) -> Binding<TInt>
where TFloat: BinaryFloatingPoint,
TInt: BinaryInteger {
Binding<TInt> (
get: { TInt(floatBinding.wrappedValue) },
set: { floatBinding.wrappedValue = TFloat($0) }
)
}
}
Run Code Online (Sandbox Code Playgroud)
...这是一个可在操场上使用的演示,展示它们的使用情况。
(注意:不要忘记复制上面的扩展方法!)
struct ConvertTestView: View {
@State private var count: Int = 1
var body: some View {
VStack{
HStack {
ForEach(1...count, id: \.self) { n in
Text("\(n)")
.font(.title).bold().foregroundColor(.white)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(.blue)
}
}
.frame(maxHeight: 64)
HStack {
Text("Count: \(count)")
Slider(value: .convert(from: $count), in: 1...8, step: 1)
}
}
.padding()
}
}
Run Code Online (Sandbox Code Playgroud)
最后,这是结果......
struct IntSlider: View {
@State var score: Int = 0
var intProxy: Binding<Double>{
Binding<Double>(get: {
//returns the score as a Double
return Double(score)
}, set: {
//rounds the double to an Int
print($0.description)
score = Int($0)
})
}
var body: some View {
VStack{
Text(score.description)
Slider(value: intProxy , in: 0.0...10.0, step: 1.0, onEditingChanged: {_ in
print(score.description)
})
}
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
260 次 |
最近记录: |