SwiftUI | 选择器 - 更改选定行的颜色

Mof*_*waw 7 ios swift swiftui

我想更改所选行的颜色。

正如您所看到的,默认情况下它具有浅灰色。

我不知道该怎么做,因为我根本找不到访问这一行的方法。有什么办法可以做到这一点吗?

演示代码:

struct ContentView: View {
    
    var data = Array(0...20).map { "\($0)" }
    @State private var selected = 0

    
    var body: some View {
        VStack {
            Picker("", selection: $selected) {
                ForEach(0 ..< data.count) {
                    Text(data[$0])
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

UIKit 的答案也将受到欢迎,因为我也没有找到办法。

谢谢你!

mul*_*des 7

使用 Introspect Swift 包

在 SwiftUI 中这并不是一件容易的事。不过我做了一些研究。
SwiftUI 背后的底层类可以Picker追溯到. 要自定义其行为,您需要访问该类,并且文档有些严重缺乏。 看看 SO 上的其他帖子,配置选择器的方法似乎一直到 objC,例如使用该函数。我什至找不到这些钥匙的列表!然而,尝试设置文本的颜色不起作用...我发现我可以访问子视图并可以解决这个背景颜色问题。UIKitUIPickerViewUIPickerView
setValue(_ value: Any?, forKey key: String)

这只是说我认为我发现的最好方法是使用这个名为Introspect的 Swift 包。

这些家伙(和女孩)确实做得非常出色。

  • 首先在您的项目中安装 Swift 包。

  • 然后添加代码以内省 UIPickerView。这不是默认设置的一部分,因此您需要创建一个自定义扩展,例如:

import Introspect

extension View {
    public func introspectUIPickerView(customize: @escaping (UIPickerView) -> ()) -> some View {
        return inject(UIKitIntrospectionView(
            selector: { introspectionView in
                guard let viewHost = Introspect.findViewHost(from: introspectionView) else {
                    return nil
                }
                return Introspect.previousSibling(containing: UIPickerView.self, from: viewHost)
            },
            customize: customize
        ))
    }
}
Run Code Online (Sandbox Code Playgroud)
  • 在您的代码中,您现在可以访问UIPickerViewSwiftUI 的底层 UIKit 类Picker。在选择器之后添加以下内容:
Picker("Flavor", selection: $selectedFlavor) {
    ForEach(Flavor.allCases) { flavor in
        Text(flavor.rawValue.capitalized)
    }       
}
.pickerStyle(WheelPickerStyle()
.introspectUIPickerView { picker in
    picker.subviews[1].backgroundColor = UIColor.clear
}
Run Code Online (Sandbox Code Playgroud)

我使用了Apple 文档中的 Picker 示例并添加了.introspectUIPickerView修饰符。
结果:不再有灰色突出显示颜色。

并不是所有的东西都能工作,因为 UIPickerView 真的很旧而且有些东西不容易定制。因此,如果您想定制其他东西,您的里程可能会有所不同:)

这里用红色表示:

.introspectUIPickerView { picker in
                picker.subviews[1].backgroundColor = UIColor.red
                   .withAlphaComponent(0.2)
            }
Run Code Online (Sandbox Code Playgroud)

红色示例


Mof*_*waw 6

这是一种对其进行某种程度定制的方法。解决方法是简单地将一个带有您选择的颜色的圆角矩形完美地放在其下方。

它并不完美,因为灰色默认不透明度叠加在该颜色之上,并且必须根据框架找出约束。

struct ContentView: View {
    
    var data = Array(0...20).map { "\($0)" }
    @State private var selected = 0

    
    var body: some View {
        ZStack {
            RoundedRectangle(cornerRadius: 5)
                .frame(width: UIScreen.main.bounds.size.width-18, height: 32)
                .foregroundColor(.green)
            
            Picker("", selection: $selected) {
                ForEach(0 ..< data.count) {
                    Text(data[$0])
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)