Which is the best way to change the color/view of disclosure indicator accessory view in a table view cell in iOS?

Viewed 42768

I need to change the color of the disclosureIndicatorView accessory in a UITableViewCell. I think there are two ways to get this done, but I'm not able to figure out which one's the optimum. So here is what I think I can do.

There is a property of UITableViewCell - accessoryView. So I can use setAccessoryView:(UIView *)view and pass view as the UIImageView holding the image that I want.

I have written an utility class which creates the content view (stuff like background color, adding other stuff, etc) for my cell and I add this content view to the cell in UITableViewDelegate. The other option is to draw a UIImage overriding the drawRect method of CustomContentView utility class.

Performing option 1 - I can get the things done the apple way. Just give them the view and they do the rest. But I guess adding a new UIView object to every row might turn out to be a heavy object allocation and decreasing the frame rate. As compared to just a UIImage object in my contentView. I believe UIImage is lighter than UIView.

Please throw some light people and help me decide over it.

12 Answers

If you're interested in drawing the indicator, instead of using an image file, here's code I worked out to do so:

// (x,y) is the tip of the arrow
CGFloat x = CGRectGetMaxX(self.bounds) - RIGHT_MARGIN;
CGFloat y = CGRectGetMidY(self.bounds);
const CGFloat R = 4.5;
CGContextRef ctxt = UIGraphicsGetCurrentContext();
CGContextMoveToPoint(ctxt, x-R, y-R);
CGContextAddLineToPoint(ctxt, x, y);
CGContextAddLineToPoint(ctxt, x-R, y+R);
CGContextSetLineCap(ctxt, kCGLineCapSquare);
CGContextSetLineJoin(ctxt, kCGLineJoinMiter);
CGContextSetLineWidth(ctxt, 3);
// If the cell is highlighted (blue background) draw in white; otherwise gray
if (CONTROL_IS_HIGHLIGHTED) {
    CGContextSetRGBStrokeColor(ctxt, 1, 1, 1, 1);
} else {
    CGContextSetRGBStrokeColor(ctxt, 0.5, 0.5, 0.5, 1);
}
CGContextStrokePath(ctxt);

If you make a custom UIView subclass, do the above in the drawRect: method, and use that as your accessory view, you'll be able to make the color anything you want.

An accessory view (custom or UIImageView won't be a major performance problem as long as you are properly recycling UITableViewCell instances.

benzado's solution works fine, but it showed a black background. In the UIView class that you setup (the one who's drawRect function you put in his code) needs to have the following initWithFrame implementation in order for the disclosure drawing to have a transparent background:

- (id)initWithFrame:(CGRect)frame {

    self = [super initWithFrame:frame];
    if (self) {
        [self setBackgroundColor:[UIColor clearColor]];
        // Initialization code.
    }
    return self;
}

Naturally, you can set this to whatever color you want...

In iOS 13+ the disclosure indicator is set via a non-templeted UIImage, which is determined by the user's dark mode preference. Since the image is non-templated, it will not respect the cell's tintColor property. In other words, the dark mode preference has top priority. If you don't wan't to use the disclosure indicator derived by iOS, you will have to use a custom image.

Change the tint colour of table view cell. Check the screenshot to do the same via Storyboard.

Related