SwiftUI 滑块和绑定提示?
SwiftUI sliders and binding tips?
我正在 SwiftUI 中为 macOS 开发一个图像编辑应用程序,但我觉得我有很多代码重复,应该更优雅一些。
我有一些滑块和一些绑定,以确保值更新并在滑块值更改时调用处理方法。目前我对每个滑块都有一个绑定:
let vStretch = Binding<Double>(
get: {
self.verticalStretchLevel
},
set: {
self.verticalStretchLevel = [=10=]
applyProcessing("vertical stretch")
}
)
let straighten = Binding<Double>(
get: {
self.straightenLevel
},
set: {
self.straightenLevel = [=10=]
applyProcessing("straighten")
}
)
let vignette = Binding<Double>(
get: {
self.vignetteLevel
},
set: {
self.vignetteLevel = [=10=]
applyProcessing("vignette")
}
)
这很丑吧?任何人都可以指出一些文章、网站或给我一些关于如何做到这一点的建议吗?
提前致谢!
我最终制作了一个滑块视图,它也有绑定:
//
// SliderView.swift
//
// Created by Michel Storms on 07/12/2020.
//
import SwiftUI
struct SliderView: View {
var runFilters: () -> Void // links to function from parent view
let label: String
let level: Binding<Double>
var body: some View {
if label.count == 1 {
HStack {
Text(label).frame(width: sliderValueWidth)
Slider(value: intensity(for: level) )
TextField("", value: level, formatter: sliderFormatter(), onCommit: { self.runFilters() } ).frame(width: sliderValueWidth)
}
.onLongPressGesture{ level.wrappedValue = 0.5 ; self.runFilters() }
.onTapGesture(count: 2, perform: { level.wrappedValue = 0.5 ; self.runFilters() })
.frame(height: sliderTextSize)
.font(.system(size: sliderTextSize))
} else {
VStack {
HStack{
Text(label)
Spacer()
TextField("", value: level, formatter: sliderFormatter(), onCommit: { self.runFilters() } ).frame(width: sliderValueWidth)
}
.frame(height: sliderTextSize)
.font(.system(size: sliderTextSize))
Slider(value: intensity(for: level) ).frame(height: sliderTextSize)
}
.onLongPressGesture{ level.wrappedValue = 0.5 ; self.runFilters() }
.onTapGesture(count: 2, perform: { level.wrappedValue = 0.5 ; self.runFilters() })
.frame(height: sliderHeight)
.font(.system(size: sliderTextSize))
}
}
func intensity(for sliderLevel: Binding<Double>) -> Binding<Double> {
Binding<Double>(
get: { sliderLevel.wrappedValue },
set: { sliderLevel.wrappedValue = [=10=]; self.runFilters() }
)
}
func sliderFormatter() -> NumberFormatter {
let formatter = NumberFormatter()
formatter.allowsFloats = true
formatter.numberStyle = .decimal
formatter.alwaysShowsDecimalSeparator = true
formatter.maximumFractionDigits = 2
formatter.minimumFractionDigits = 2
formatter.decimalSeparator = "."
return formatter
}
}
...然后像这样显示滑块:
var body: some View {
return List {
VStack {
SliderView(runFilters: self.runFilters, label: "Exposure", level: $appState.exposureLevel)
SliderView(runFilters: self.runFilters, label: "Contrast", level: $appState.contrastLevel)
SliderView(runFilters: self.runFilters, label: "Brightness", level: $appState.brightnessLevel)
SliderView(runFilters: self.runFilters, label: "Shadows", level: $appState.shadowsLevel)
SliderView(runFilters: self.runFilters, label: "Highlights", level: $appState.highlightsLevel)
SliderView(runFilters: self.runFilters, label: "Vibrance", level: $appState.vibranceLevel)
SliderView(runFilters: self.runFilters, label: "Saturation", level: $appState.saturationLevel)
SliderView(runFilters: self.runFilters, label: "Clarity", level: $appState.clarityLevel)
SliderView(runFilters: self.runFilters, label: "Black Point", level: $appState.blackpointLevel)
if debug {
SliderView(runFilters: self.runFilters, label: "DEBUG / TEST", level: $appState.debugAndTestSliderLevel)
}
}
.font(.system(size: sliderTextSize))
我正在 SwiftUI 中为 macOS 开发一个图像编辑应用程序,但我觉得我有很多代码重复,应该更优雅一些。
我有一些滑块和一些绑定,以确保值更新并在滑块值更改时调用处理方法。目前我对每个滑块都有一个绑定:
let vStretch = Binding<Double>(
get: {
self.verticalStretchLevel
},
set: {
self.verticalStretchLevel = [=10=]
applyProcessing("vertical stretch")
}
)
let straighten = Binding<Double>(
get: {
self.straightenLevel
},
set: {
self.straightenLevel = [=10=]
applyProcessing("straighten")
}
)
let vignette = Binding<Double>(
get: {
self.vignetteLevel
},
set: {
self.vignetteLevel = [=10=]
applyProcessing("vignette")
}
)
这很丑吧?任何人都可以指出一些文章、网站或给我一些关于如何做到这一点的建议吗?
提前致谢!
我最终制作了一个滑块视图,它也有绑定:
//
// SliderView.swift
//
// Created by Michel Storms on 07/12/2020.
//
import SwiftUI
struct SliderView: View {
var runFilters: () -> Void // links to function from parent view
let label: String
let level: Binding<Double>
var body: some View {
if label.count == 1 {
HStack {
Text(label).frame(width: sliderValueWidth)
Slider(value: intensity(for: level) )
TextField("", value: level, formatter: sliderFormatter(), onCommit: { self.runFilters() } ).frame(width: sliderValueWidth)
}
.onLongPressGesture{ level.wrappedValue = 0.5 ; self.runFilters() }
.onTapGesture(count: 2, perform: { level.wrappedValue = 0.5 ; self.runFilters() })
.frame(height: sliderTextSize)
.font(.system(size: sliderTextSize))
} else {
VStack {
HStack{
Text(label)
Spacer()
TextField("", value: level, formatter: sliderFormatter(), onCommit: { self.runFilters() } ).frame(width: sliderValueWidth)
}
.frame(height: sliderTextSize)
.font(.system(size: sliderTextSize))
Slider(value: intensity(for: level) ).frame(height: sliderTextSize)
}
.onLongPressGesture{ level.wrappedValue = 0.5 ; self.runFilters() }
.onTapGesture(count: 2, perform: { level.wrappedValue = 0.5 ; self.runFilters() })
.frame(height: sliderHeight)
.font(.system(size: sliderTextSize))
}
}
func intensity(for sliderLevel: Binding<Double>) -> Binding<Double> {
Binding<Double>(
get: { sliderLevel.wrappedValue },
set: { sliderLevel.wrappedValue = [=10=]; self.runFilters() }
)
}
func sliderFormatter() -> NumberFormatter {
let formatter = NumberFormatter()
formatter.allowsFloats = true
formatter.numberStyle = .decimal
formatter.alwaysShowsDecimalSeparator = true
formatter.maximumFractionDigits = 2
formatter.minimumFractionDigits = 2
formatter.decimalSeparator = "."
return formatter
}
}
...然后像这样显示滑块:
var body: some View {
return List {
VStack {
SliderView(runFilters: self.runFilters, label: "Exposure", level: $appState.exposureLevel)
SliderView(runFilters: self.runFilters, label: "Contrast", level: $appState.contrastLevel)
SliderView(runFilters: self.runFilters, label: "Brightness", level: $appState.brightnessLevel)
SliderView(runFilters: self.runFilters, label: "Shadows", level: $appState.shadowsLevel)
SliderView(runFilters: self.runFilters, label: "Highlights", level: $appState.highlightsLevel)
SliderView(runFilters: self.runFilters, label: "Vibrance", level: $appState.vibranceLevel)
SliderView(runFilters: self.runFilters, label: "Saturation", level: $appState.saturationLevel)
SliderView(runFilters: self.runFilters, label: "Clarity", level: $appState.clarityLevel)
SliderView(runFilters: self.runFilters, label: "Black Point", level: $appState.blackpointLevel)
if debug {
SliderView(runFilters: self.runFilters, label: "DEBUG / TEST", level: $appState.debugAndTestSliderLevel)
}
}
.font(.system(size: sliderTextSize))