SwiftUI如何自定义Slider蓝线?
How customise Slider blue line in SwiftUI?
喜欢UISlider
let slider = UISlider()
slider.minimumTrackTintColor = .red
从 Apple 的 2021 平台开始,您可以使用 tint
修饰符更改滑块旋钮左侧轨道的颜色。除此之外,SwiftUI 的 Slider
不允许您自定义其外观。
如果您需要更多自定义,那么目前您唯一的选择是创建一个 UISlider
并将其包装在 UIViewRepresentable
中。通过 the “Interfacing with UIKit” tutorial and watch WWDC 2019 Session 231: Integrating SwiftUI 学习如何使用 UIViewRepresentable
.
The Slider
documentation 之前提到了一个名为 SliderStyle
的类型,但是 SliderStyle
并没有文档,并且在 SwiftUI 的 public 接口中实际上没有定义该类型Xcode 11 beta 4 的框架。它可能会出现在以后的版本中。也有可能我们将不得不等待 SwiftUI 的未来(13 之后)版本才能实现此功能。
如果 SliderStyle
确实出现,它可能允许您自定义 Slider
的外观,就像 ButtonStyle
允许您自定义 Button
的外观一样——承担绘制它的全部责任。因此,如果您想抢先一步,您可能需要在网上寻找 ButtonStyle
教程。
但是 SliderStyle
最终可能更像 TextFieldStyle
。 Apple 提供了少量 TextFieldStyle
供您选择,但您无法定义自己的
.accentColor(.red)
这将适用于 iOS 和 Mac Catalyst。
查看可自定义的滑块示例 here
正如其他答案中所指出的,您在 SwiftUI 中自定义 Slider
的能力有限。您可以更改 .accentColor(.red)
,但这只会更改 minimumTrackTintColor。
Slider
与 .accentColor(.red)
的示例
此外,您无法更改 thumbTintColor 等其他内容。
如果你想要更多的自定义而不只是 minimumTrackTintColor
,你别无选择,只能在 SwiftUI
中使用 UISlider
,如 所述。
这里是一些关于如何在 SwiftUI
中使用 UISlider
的代码
struct SwiftUISlider: UIViewRepresentable {
final class Coordinator: NSObject {
// The class property value is a binding: It’s a reference to the SwiftUISlider
// value, which receives a reference to a @State variable value in ContentView.
var value: Binding<Double>
// Create the binding when you initialize the Coordinator
init(value: Binding<Double>) {
self.value = value
}
// Create a valueChanged(_:) action
@objc func valueChanged(_ sender: UISlider) {
self.value.wrappedValue = Double(sender.value)
}
}
var thumbColor: UIColor = .white
var minTrackColor: UIColor?
var maxTrackColor: UIColor?
@Binding var value: Double
func makeUIView(context: Context) -> UISlider {
let slider = UISlider(frame: .zero)
slider.thumbTintColor = thumbColor
slider.minimumTrackTintColor = minTrackColor
slider.maximumTrackTintColor = maxTrackColor
slider.value = Float(value)
slider.addTarget(
context.coordinator,
action: #selector(Coordinator.valueChanged(_:)),
for: .valueChanged
)
return slider
}
func updateUIView(_ uiView: UISlider, context: Context) {
// Coordinating data between UIView and SwiftUI view
uiView.value = Float(self.value)
}
func makeCoordinator() -> SwiftUISlider.Coordinator {
Coordinator(value: $value)
}
}
#if DEBUG
struct SwiftUISlider_Previews: PreviewProvider {
static var previews: some View {
SwiftUISlider(
thumbColor: .white,
minTrackColor: .blue,
maxTrackColor: .green,
value: .constant(0.5)
)
}
}
#endif
然后您可以像这样在 ContentView
中使用此滑块:
struct ContentView: View {
@State var sliderValue: Double = 0.5
var body: some View {
VStack {
Text("SliderValue: \(sliderValue)")
// Slider(value: $sliderValue).accentColor(.red).padding(.horizontal)
SwiftUISlider(
thumbColor: .green,
minTrackColor: .red,
maxTrackColor: .blue,
value: $sliderValue
).padding(.horizontal)
}
}
}
示例:
如果明亮的白色滑块手柄在您的深色模式设计上格格不入,您可以使用 .label 颜色和 .softLight 告诉它慢下来。它只在灰度下看起来不错,除非你能弄清楚混合模式和色调旋转。
最好看的结果是来自带有 .blendMode(.sourceAtop) 的重叠形状...但不幸的是,这会阻止交互。
@Environment(\.colorScheme) var colorScheme
var body: some View {
let hackySliderBGColor: Color = colorScheme == .dark ? Color(.secondarySystemBackground) : Color(.systemBackground)
let hackySliderAccentColor: Color = colorScheme == .dark ? Color(.label) : Color(.systemGray2)
let hackySliderBlendMode: BlendMode = colorScheme == .dark ? .softLight : .multiply
...
ZStack {
Rectangle()
.foregroundColor(hackySliderBGColor)
// This second Rect prevents a white sliver if slider is at max value.
.overlay(Rectangle()
.foregroundColor(hackySliderBGColor)
.offset(x: 5)
)
Slider(value: $pointsToScoreLimit,
in: themin...themax, step: 5)
.accentColor(hackySliderAccentColor)
.blendMode(hackySliderBlendMode)
}
示例:
所以我尝试使用 .accentColor(.red)
但没有成功,所以我注意到对于较新的版本,必须使用 .tint(.red)
才能使更改可见。
希望对您有所帮助。
喜欢UISlider
let slider = UISlider()
slider.minimumTrackTintColor = .red
从 Apple 的 2021 平台开始,您可以使用 tint
修饰符更改滑块旋钮左侧轨道的颜色。除此之外,SwiftUI 的 Slider
不允许您自定义其外观。
如果您需要更多自定义,那么目前您唯一的选择是创建一个 UISlider
并将其包装在 UIViewRepresentable
中。通过 the “Interfacing with UIKit” tutorial and watch WWDC 2019 Session 231: Integrating SwiftUI 学习如何使用 UIViewRepresentable
.
The Slider
documentation 之前提到了一个名为 SliderStyle
的类型,但是 SliderStyle
并没有文档,并且在 SwiftUI 的 public 接口中实际上没有定义该类型Xcode 11 beta 4 的框架。它可能会出现在以后的版本中。也有可能我们将不得不等待 SwiftUI 的未来(13 之后)版本才能实现此功能。
如果 SliderStyle
确实出现,它可能允许您自定义 Slider
的外观,就像 ButtonStyle
允许您自定义 Button
的外观一样——承担绘制它的全部责任。因此,如果您想抢先一步,您可能需要在网上寻找 ButtonStyle
教程。
但是 SliderStyle
最终可能更像 TextFieldStyle
。 Apple 提供了少量 TextFieldStyle
供您选择,但您无法定义自己的
.accentColor(.red)
这将适用于 iOS 和 Mac Catalyst。 查看可自定义的滑块示例 here
正如其他答案中所指出的,您在 SwiftUI 中自定义 Slider
的能力有限。您可以更改 .accentColor(.red)
,但这只会更改 minimumTrackTintColor。
Slider
与 .accentColor(.red)
此外,您无法更改 thumbTintColor 等其他内容。
如果你想要更多的自定义而不只是 minimumTrackTintColor
,你别无选择,只能在 SwiftUI
中使用 UISlider
,如
这里是一些关于如何在 SwiftUI
中使用UISlider
的代码
struct SwiftUISlider: UIViewRepresentable {
final class Coordinator: NSObject {
// The class property value is a binding: It’s a reference to the SwiftUISlider
// value, which receives a reference to a @State variable value in ContentView.
var value: Binding<Double>
// Create the binding when you initialize the Coordinator
init(value: Binding<Double>) {
self.value = value
}
// Create a valueChanged(_:) action
@objc func valueChanged(_ sender: UISlider) {
self.value.wrappedValue = Double(sender.value)
}
}
var thumbColor: UIColor = .white
var minTrackColor: UIColor?
var maxTrackColor: UIColor?
@Binding var value: Double
func makeUIView(context: Context) -> UISlider {
let slider = UISlider(frame: .zero)
slider.thumbTintColor = thumbColor
slider.minimumTrackTintColor = minTrackColor
slider.maximumTrackTintColor = maxTrackColor
slider.value = Float(value)
slider.addTarget(
context.coordinator,
action: #selector(Coordinator.valueChanged(_:)),
for: .valueChanged
)
return slider
}
func updateUIView(_ uiView: UISlider, context: Context) {
// Coordinating data between UIView and SwiftUI view
uiView.value = Float(self.value)
}
func makeCoordinator() -> SwiftUISlider.Coordinator {
Coordinator(value: $value)
}
}
#if DEBUG
struct SwiftUISlider_Previews: PreviewProvider {
static var previews: some View {
SwiftUISlider(
thumbColor: .white,
minTrackColor: .blue,
maxTrackColor: .green,
value: .constant(0.5)
)
}
}
#endif
然后您可以像这样在 ContentView
中使用此滑块:
struct ContentView: View {
@State var sliderValue: Double = 0.5
var body: some View {
VStack {
Text("SliderValue: \(sliderValue)")
// Slider(value: $sliderValue).accentColor(.red).padding(.horizontal)
SwiftUISlider(
thumbColor: .green,
minTrackColor: .red,
maxTrackColor: .blue,
value: $sliderValue
).padding(.horizontal)
}
}
}
示例:
如果明亮的白色滑块手柄在您的深色模式设计上格格不入,您可以使用 .label 颜色和 .softLight 告诉它慢下来。它只在灰度下看起来不错,除非你能弄清楚混合模式和色调旋转。
最好看的结果是来自带有 .blendMode(.sourceAtop) 的重叠形状...但不幸的是,这会阻止交互。
@Environment(\.colorScheme) var colorScheme
var body: some View {
let hackySliderBGColor: Color = colorScheme == .dark ? Color(.secondarySystemBackground) : Color(.systemBackground)
let hackySliderAccentColor: Color = colorScheme == .dark ? Color(.label) : Color(.systemGray2)
let hackySliderBlendMode: BlendMode = colorScheme == .dark ? .softLight : .multiply
...
ZStack {
Rectangle()
.foregroundColor(hackySliderBGColor)
// This second Rect prevents a white sliver if slider is at max value.
.overlay(Rectangle()
.foregroundColor(hackySliderBGColor)
.offset(x: 5)
)
Slider(value: $pointsToScoreLimit,
in: themin...themax, step: 5)
.accentColor(hackySliderAccentColor)
.blendMode(hackySliderBlendMode)
}
示例:
所以我尝试使用 .accentColor(.red)
但没有成功,所以我注意到对于较新的版本,必须使用 .tint(.red)
才能使更改可见。
希望对您有所帮助。