Question

I am having a UIPicker, I want to change the color of the selector. Is it possible to change the color of the selector?

Was it helpful?

Solution

I suppose you're dealing with the iPhone SDK? There may be some other frameworks which uses this name, so maybe you can add your tags to include uikit, cocoa-touch or something.

Anyway, you can set showsSelectionIndicator of the UIPickerView instance to NO, so it hides the selector. Then you can create a new view with the adjusted selection style, and add it to the superview above the UIPickerView.

// Some sample code, but you can do this in IB if you want to
_pickerView = [[UIPickerView alloc] init];
_pickerView.showsSelectionIndicator = NO;
[_pickerView sizeToFit];
[self.view addSubview:_pickerView];

UIImage *selectorImage = [UIImage imageNamed:@"selectorImage.png"]; // You have to make it strechable, probably
UIView *customSelector = [[UIImageView alloc] initWithImage:selectorImage];
customSelector.frame = CGRectZero; // Whatever rect to match the UIImagePicker
[self.view addSubview:customSelector];
[customSelector release];

Hacking the UI Element itself will take much more work, and this has to work as well.

OTHER TIPS

Maybe it's not fully fits for answer to this question, in iOS 7 and later you can customize color by this way:

In the delegate methods

- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view

- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component

add following

[[pickerView.subviews objectAtIndex:1] setBackgroundColor:NEEDED_COLOR];
[[pickerView.subviews objectAtIndex:2] setBackgroundColor:NEEDED_COLOR];

UPDATE

Previous code works, but so-so. Here simple subclasses for UIPickerView

Swift:

class RDPickerView: UIPickerView
{
    @IBInspectable var selectorColor: UIColor? = nil

    override func didAddSubview(subview: UIView) {
        super.didAddSubview(subview)
        if let color = selectorColor
        {
            if subview.bounds.height <= 1.0
            {
                subview.backgroundColor = color
            }
        }

    }
}

Objective-C:

@interface RDPickerView : UIPickerView

@property (strong, nonatomic) IBInspectable UIColor *selectorColor;

@end

@implementation RDPickerView

- (void)didAddSubview:(UIView *)subview
{
    [subview didAddSubview:subview];
    if (self.selectorColor)
    {
        if (subview.bounds.size.height <= 1.0)
        {
            subview.backgroundColor = self.selectorColor;
        }
    }
}

@end

and you can set selector color directly in storyboard

Thanks to Ross Barbish - "With iOS 9.2 and XCode 7.2 released 12/8/2015, the height of this selection view is 0.666666666666667".

UPDATE:

It's fix for issue with iOS 10, not good but works. :/

class RDPickerView: UIPickerView
{
    @IBInspectable var selectorColor: UIColor? = nil

    override func didAddSubview(_ subview: UIView) {
        super.didAddSubview(subview)

        guard let color = selectorColor else {
            return
        }

        if subview.bounds.height <= 1.0
        {
            subview.backgroundColor = color
        }
    }

    override func didMoveToWindow() {
        super.didMoveToWindow()

        guard let color = selectorColor else {
            return
        }

        for subview in subviews {
            if subview.bounds.height <= 1.0
            {
                subview.backgroundColor = color
            }
        }
    }
}

Thanks Dmitry Klochkov, I'll try to find some better solution.

Here's an improvement to vsilux's answer, in form of a simple category to UIPickerView, without the need to subclass UIPickerView.

(Up-to-date answer as of November 2, 2018)

Swift 4, Xcode 10:

@IBInspectable var selectorColor: UIColor? {
    get {
        return objc_getAssociatedObject(self, &selectorColorAssociationKey) as? UIColor
    }
    set(newValue) {
        objc_setAssociatedObject(self, &selectorColorAssociationKey, newValue,
                                 objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
    }
}

open override func didAddSubview(_ subview: UIView) {

    super.didAddSubview(subview)
    if let color = selectorColor {
        if subview.bounds.height < 1.0 {
            subview.backgroundColor = color
        }
    }
}

You can change just the selection indicator's background color as well.
Just add a UIView above the selection indicator (it will become your overlay view), set it's alpha value low(depends on you, but I like my overlay to look transparent), give it a background color and you are good to go.

Consider this,

var overlayOnPicker:UIView = UIView(frame: CGRectMake(1, 68, mypicker.frame.width, 26))
// Adds a layer on the selection indicator

And do put the CGRect's X value=1 (Remember, it's a frame, so it will be placed according to the superview's coordinate system)

overlayOnPicker.backgroundColor = UIColor.whiteColor()
overlayOnPicker.alpha = 0.2
myDatePicker.addSubview(overlayOnPicker)
// You have to add the overlayOnPicker view as a subview to the Date Picker.
// myDatePicker is the UIDatePicker that I declared earlier in my code
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top