简体   繁体   中英

SwiftUI | Picker - Change selected row color

I want to change the color of the selected row.

As you may see, by default it has this light gray color.

I have no idea how to do that since I have found no way to access this row at all. Is there any way to do that?

Demo code:

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])
                }
            }
        }
    }
}

A UIKit answer would also be welcomed since I have found no way either.

Thank you!

I want to change the color of the selected row.

As you may see, by default it has this light gray color.

I have no idea how to do that since I have found no way to access this row at all. Is there any way to do that?

Demo code:

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])
                }
            }
        }
    }
}

A UIKit answer would also be welcomed since I have found no way either.

Thank you!

Using the Introspect Swift Package

It is not trivial to do in SwiftUI. I did some research however.
The underlying class behind SwiftUI's Picker goes back to UIKit and it is the UIPickerView . To customise its behaviour you need access then to the UIPickerView class and the documentation is somewhat severely lacking.
And looking at other posts on SO it seems that the way to configure the picker goes all the way to objC for example with the setValue(_ value: Any?, forKey key: String) function. I could not even find a list of those keys! And trying to set up the color of the text did not work however... I found out that I can access the subviews and could solve this background color problem.

This is just to say that I think the best way I found is using this Swift Package called Introspect .

These guys (and girls) did really an amazing job.

  • First install the Swift Package in your project.

  • Then add the code to introspect the UIPickerView. This is not part of the defaults so you need to create a custom extension like:

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
        ))
    }
}
  • In your code you have now access to the UIPickerView , the underlying UIKit class of your SwiftUI's Picker . Add this after the 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
}

I used the Picker example from the Apple docs and added the .introspectUIPickerView modifier.
The result: no more grey highlighted color.

Not everything will work because the UIPickerView is really old and some things are not easily customisable. So if you want to customise other things your mileage might vary :)

Here in red with :

.introspectUIPickerView { picker in
                picker.subviews[1].backgroundColor = UIColor.red
                   .withAlphaComponent(0.2)
            }

示例WithRed

More simple use:

.accentColor(your color)

Picker("", selection: $selected) {
    ForEach(0 ..< data.count) {
        Text(data[$0])
    }
}
.accentColor(.black)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM