Change colour of UIPickerView selection indicators

14,039

Solution 1

The best solution I can offer is to place 2 UIImages on top of your picker wheel at the width of 1 and length set to your preference. This is how I overcame this.

It does not work well if you require multiple size views so programatically doing it to cater for your size changes would be the next best solution. To programatically change the size using if statements:

How to resize the image programmatically in objective-c in iphone

If you change the size based on orientation add an if statement that handles orientation like so:

 if (UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation))
{
     // code for landscape orientation      
}
if (UIDeviceOrientationIsPortrait([UIDevice currentDevice].orientation))
{
     // code for Portrait orientation       
}

Kind regards

Solution 2

Swift 4.2

func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {

        pickerView.subviews[1].backgroundColor = UIColor.white
        pickerView.subviews[2].backgroundColor = UIColor.white

        return view
    }

This works for me!

Solution 3

This has been answered here: How to change the color of UIPickerView Selector

Basically:

pickerView.subviews[1].backgroundColor = UIColor.whiteColor()
pickerView.subviews[2].backgroundColor = UIColor.whiteColor()

Solution 4

Add this to your UIPickerView's viewForRow, titleForRow or attributedTitleForRow:

for lineSubview in pickerView.subviews {
  if lineSubview.frame.height < 1 {
    lineSubview.backgroundColor = UIColor.white.withAlphaComponent(0.15)
  }
}

This should be a little bit safer to use because we are looking for subviews that should be very short in height. If Apple changes the view hierarchy it most probably won't mess up anything :)

Solution 5

Try something like this:

- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {

    //On Selecting the component row
    if (component == 0) {

    } else if (component == 1) {

        [quantityPickerDelegate didChangeLabelText:[pickerArray objectAtIndex:row]];// delegate passing the selected value
        [pickerView reloadComponent:component]; //This will cause your viewForComp to hit
    }
}

- (UIView *)viewForRow:(NSInteger)row forComponent:(NSInteger)component
 {
 //...
 //Your usual code
  pickerLabel.textColor = defaultColor;

 if([self.pickerView selectedRowInComponent:component] == row) //this is the selected one, change its color
 {
        pickerLabel.textColor = [UIColor colorWithRed:0.0745 green:0.357 blue:1.0 alpha:1];
 } 
}
Share:
14,039
cjhill
Author by

cjhill

Hello. SOreadytohelp

Updated on June 15, 2022

Comments

  • cjhill
    cjhill almost 2 years

    Our UIPickerView has a dark background and the selection lines are incredibly hard to see. Is there anyway to change them to a colour of my choosing?

    Update: I'm talking about the --- above and below the "Panda" item.

        Cat
        Dog
      Elephant
    -----------
       Panda
    -----------
       Bear
      Giraffe
    
  • cjhill
    cjhill over 9 years
    Thanks, @rodrigo-carrilho, however that would just change the text colour. What I really needed was the lines above and below the selected item. I've updated my question to give a little more guidance on my problem.
  • cjhill
    cjhill over 9 years
    Not an ideal solution as I imagine it would be quite delicate, but it would do the job. Also best to set showsSelectionIndicator to NO if you do try this.
  • App Dev Guy
    App Dev Guy over 9 years
    I fully agree regarding being "not ideal", hence why I including the need to to calculate any future or past size alterations and orientation as I have had to in a few of my apps, I was just hoping that there was a newer solution not unlike yourself, but sadly there is not. While the iOS framework is quite powerful it's limited in many aspects and this is one of them. Fortunately as they move towards Swift and more web code like styling and coding, the flexibility should also increase. Glad I could help though.
  • DrMickeyLauer
    DrMickeyLauer over 5 years
    @DeyaEldeen It still works, though you have to remember that the picker subview hierarchy might not be fully constructed by the time you have created the object, hence you might need to defer the calls to e.g. the time when your datasource is queried.
  • DrMickeyLauer
    DrMickeyLauer over 5 years
    @DeyaEldeen either put the code in titleForRow or use a subclass, e.g. -(void)willMoveToSuperview:(UIView )newSuperview { [super willMoveToSuperview:newSuperview]; self.backgroundColor = [LTPickerView appearance].backgroundColor; } -(void)didAddSubview:(UIView *)subview { [super didAddSubview:subview]; if ( subview.bounds.size.height <= 1.0 ) { UIColor appearanceTintColor = [LTPickerView appearance].tintColor; if ( appearanceTintColor ) { subview.backgroundColor = appearanceTintColor; } } }
  • Alex Kolovatov
    Alex Kolovatov almost 4 years
    Thanks a lot! In my case, I set .clear color do hide this separator lines 'pickerView.subviews.forEach { $0.backgroundColor = .clear }'
  • Andy Weinstein
    Andy Weinstein over 3 years
    In iOS 14 I used a variation of this to get rid of the grey highlight background color for the selection: (safe is an operator that does range changing and returns nil if out of range): pickerView.subviews[safe:1]?.backgroundColor = UIColor.clear