[英]How to change selected segment color in SwiftUI Segmented Picker
我想在 SwiftUI 分段选择器中设置选定的分段颜色并将文本颜色更改为白色。
我已经尝试过使用选择器视图的修饰符和修改外观代理的色调。 不幸的是,它们似乎都不起作用。
import SwiftUI
struct PickerView: View {
@State var pickerSelection = 0
init() {
UISegmentedControl.appearance().tintColor = UIColor.blue
}
var body: some View {
Picker(selection: $pickerSelection, label: Text("")) {
Text("Active").tag(0).foregroundColor(Color.white)
Text("Completed").tag(1)
}.pickerStyle(SegmentedPickerStyle()).foregroundColor(Color.orange)
}
}
在 SwiftUI 中有什么方法可以做到这一点,还是我应该通过使用 UIViewControllerRepresentable 来使用 UISegmentedControl?
SwiftUI 目前不支持本机 SegmentedPicker 样式(有关工作解决方法,请参阅答案的底部)。 但是使用.colorMultiply()
修饰符将颜色应用于分段选择器的方法是有限的:
UIAppearance
完全控制 selectedSegmentTintColor
自 beta 3 起可用于更改选定段的颜色。
要更改textColor
,您应该将setTitleTextAttributes
用于.selected
状态和.normal
状态(未选中)。
所以它会像:
init() {
UISegmentedControl.appearance().selectedSegmentTintColor = .blue
UISegmentedControl.appearance().setTitleTextAttributes([.foregroundColor: UIColor.white], for: .selected)
UISegmentedControl.appearance().setTitleTextAttributes([.foregroundColor: UIColor.blue], for: .normal)
}
同样正如迈克所提到的,您也可以设置背景颜色,例如:
UISegmentedControl.appearance().backgroundColor = .yellow
另外,别忘了你也可以设置 SwiftUI 颜色! 例如:
UISegmentedControl.appearance().selectedSegmentTintColor = UIColor(Color.accentColor)
最近我遇到了一个类似的问题,我需要为SwiftUI SegmentedControl
自定义background
和foreground
。我发现这篇文章也很有帮助,但我也想分享我现在正在使用的其他解决方案。 有一个非常不错的包叫做SwiftUI Introspect ,它允许...
从
SwiftUI
内省底层 UIKit 组件
有了这个包,我创建了以下SegmentedControl
使用此代码:
VStack {
Picker("Activity view", selection: $selectedActivity) {
ForEach(ActivityView.allCases) { activity in
Text(activity.description)
}
}
.introspectSegmentedControl { segmentedControl in
segmentedControl.backgroundColor = .clear
segmentedControl.tintColor = TCHColors.SegmentedControl.backgroundSelected
segmentedControl.selectedSegmentTintColor = TCHColors.SegmentedControl.backgroundSelected
segmentedControl.setTitleTextAttributes([
NSAttributedString.Key.foregroundColor: TCHColors.SegmentedControl.selectedText
], for: .selected)
segmentedControl.setTitleTextAttributes([
NSAttributedString.Key.foregroundColor: TCHColors.SegmentedControl.normalText
], for: .normal)
}
.pickerStyle(.segmented)
}
.padding(.horizontal, 16)
您可以使用这个包从 SwiftUI 访问许多其他底层组件。
这个回答对我有帮助,但我想补充一点。 我使用的颜色是视图的参数,因此将这些方法放在 init 中不允许我访问颜色。
或者,您可以直接在分段选取器上使用onAppear
方法,如下所示。
import SwiftUI
struct PickerView: View {
var color: UIColor
@State var pickerSelection = 0
var body: some View {
Picker(selection: $pickerSelection, label: Text("")) {
Text("Active").tag(0).foregroundColor(Color.white)
Text("Completed").tag(1)
}.pickerStyle(SegmentedPickerStyle()).foregroundColor(Color.orange)
.onAppear {
UISegmentedControl.appearance().tintColor = color
}
}
}
🔴 不幸的是,没有 SwiftUI 原生的方法来更改分段控件的默认颜色。 让我们覆盖默认颜色的解决方案是更改 UISegmentedControl 的外观,就像我们在基于 UIKit 的应用程序中所做的那样。
🔴 为了实现这一点,有必要明确定义我们正在处理的视图的init()
方法:
struct ContentView: View {
init() {
}
...
}
🔴 在init()
主体中,我们将指定选定段的色调颜色、正常状态下的文本颜色和选定状态下的文本颜色。 以下是所有操作的完成方式:
init() {
UISegmentedControl.appearance().selectedSegmentTintColor = .systemIndigo
UISegmentedControl.appearance().setTitleTextAttributes([.foregroundColor: UIColor.systemYellow], for: .normal)
UISegmentedControl.appearance().setTitleTextAttributes([.foregroundColor: UIColor.white], for: .selected)
}
🔴 上面代码的结果如下图所示:
完成😊
这是分段选择器功能的手动实现:
@ViewBuilder func viewSegmentedButtons(arr: [String], selIndex: Int, baseColor: Color, closure:@escaping (_ selectedIndex: Int) -> Void) -> some View {
let columns = Array(repeating: GridItem(spacing: 1), count:arr.count)
LazyVGrid(columns: columns, spacing: 1.0) {
ForEach(Array(arr.enumerated()), id: \.element) { index, translation in
Button {
closure(index)
} label: {
ZStack {
Rectangle()
.foregroundColor(index == selIndex ? baseColor : Color(.systemBackground))
.cornerRadius(radius: index==0 ? cRadius : 0, corners: [.topLeft, .bottomLeft])
.cornerRadius(radius: index==arr.count-1 ? cRadius : 0, corners: [.topRight, .bottomRight])
Text(translation)
.padding(.vertical, 10)
.font(.footnote)
.foregroundColor(index != selIndex ? baseColor : Color(.systemBackground) )
}
}
}
}
.foregroundColor(baseColor)
.overlay(
RoundedRectangle(cornerRadius: cRadius)
.stroke(baseColor, lineWidth: 2)
)
.font(.callout)
.background(baseColor)
.cornerRadius(cRadius)
.padding(.bottom, 10)
}
使用示例:
@State private var levelIndex: Int = 0
var body: some View {
VStack {
Text("Level:")
viewSegmentedButtons(arr: ["Easy", "Meduim", "Hard"], selIndex: levelIndex, baseColor: .orange) { selectedIndex in
withAnimation {
levelIndex = selectedIndex
}
}
}
}
这是我在 SwiftUI 中工作的解决方案:
init(){
UISegmentedControl.appearance().selectedSegmentTintColor = .green
UISegmentedControl.appearance().setTitleTextAttributes([.foregroundColor: UIColor.black], for: .selected)
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.