Customizing the colors of a UISegmentedControl - ios

Does anybody know of a way to customize the appearance of the string based UISegmentedControl? I am trying to set the background color of the cell and the text color differently depending on the selected state of the item.
Alternatively, do you know of a way to create UIImages on the fly in which to include custom strings? (e.g. create UUImage with white background, overlay text, add to segmented control).
I know that you can only have strings or images in the segmented control...

UISegmentedControl has a tintColor property -- this allows you to change what color the control is, but not the general "style" (the rounded, beveled shape):
segmentedControl.tintColor = [UIColor blueColor];
As for creating UIImages on the fly, you can create a CGContext, do whatever drawing you need to in that context (including strings), and then get a UIImage out of the context's CGImage:
CGContextRef drawContext = CGBitmapContextCreate(<many parameters>);
//do drawing here
CGImageRef finalImage = CGBitmapContextCreateImage(drawContext);
UIImage *cellImage = [UIImage finalImage];
Please note, that if you use code like UIView.appearance().tintColor = .myColor (or equiv. in ObjC), the effect most likely won't take place.

segmentedControl.tintColor = [UIColor colorWithRed:0.61176f green:0.61176f blue:0.61176f alpha:1.0f];
segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar;

Most of the answers here don't answer the specific question of how to set a button color based on selected state which implies another color is desired for unselected state. I struggled with this for quite some time and wanted to share my solution for others to use.
My example uses a UISegmentedControl with three segments. The unselected color for all three should be the same to give it a uniform look. The selected state for the first and last segment have unique colors.
The issue is that the segmented control is not guaranteed to be in the same order so the colors will get mixed up as you select back and forth. Dan posted a solution that uses tags but unfortunately it's no longer guaranteed to work for iOS 6 and up.
Most of this code is taken from this post. I changed it slightly to have unique selected colors.
What makes it work is the sorting but take note of these 2 important lines for setting the selected color:
NSInteger selectedIdx = betterSegmentedControl.selectedSegmentIndex;
[[sortedViews objectAtIndex:selectedIdx] setTintColor:[self.segmentColors objectAtIndex:selectedIdx]];
- (void) updateSegmentColors
{
UIColor *checkColor = [UIColor colorWithRed: 29/255.0 green:166/255.0 blue:47/255.0 alpha:1.0];
NSArray *segmentColors = [[NSArray alloc] initWithObjects:checkColor, [UIColor blueColor], [UIColor redColor], nil];
UISegmentedControl *betterSegmentedControl = self.StatusControl;
// Get number of segments
NSUInteger numSegments = [betterSegmentedControl.subviews count];
// Reset segment's color (non selected color)
for( int i = 0; i < numSegments; i++ ) {
// reset color
[[betterSegmentedControl.subviews objectAtIndex:i] setTintColor:nil];
[[betterSegmentedControl.subviews objectAtIndex:i] setTintColor:[UIColor blueColor]];
}
// Sort segments from left to right
NSArray *sortedViews = [betterSegmentedControl.subviews sortedArrayUsingFunction:compareViewsByOrigin context:NULL];
// Change color of selected segment
NSInteger selectedIdx = betterSegmentedControl.selectedSegmentIndex;
[[sortedViews objectAtIndex:selectedIdx] setTintColor:[self.segmentColors objectAtIndex:selectedIdx]];
// Remove all original segments from the control
for (id view in betterSegmentedControl.subviews) {
[view removeFromSuperview];
}
// Append sorted and colored segments to the control
for (id view in sortedViews) {
[betterSegmentedControl addSubview:view];
}
}
NSInteger static compareViewsByOrigin(id sp1, id sp2, void *context)
{
// UISegmentedControl segments use UISegment objects (private API). But we can safely cast them to UIView objects.
float v1 = ((UIView *)sp1).frame.origin.x;
float v2 = ((UIView *)sp2).frame.origin.x;
if (v1 < v2)
return NSOrderedAscending;
else if (v1 > v2)
return NSOrderedDescending;
else
return NSOrderedSame;
}
I placed the code in it's own method because I'm loading these segmented controls in a table view and need to run it upon loading (existing states from storage) and when a user changes a selection. Now I just need to call [Self updateSegmentColors]; when something changes.

All you have to do is:
// Get an array of the subviews of a UISegmentedControl, for example myUISegmentedControl:
NSArray *arri = [myUISegmentedControl subviews];
// Change the tintColor of each subview within the array:
[[arri objectAtIndex:0] setTintColor:[UIColor redColor]];
[[arri objectAtIndex:1] setTintColor:[UIColor greenColor]];

The best way I have found of doing something like this is setting different attributes for different UIControlStates on the segmented control.
self.segmentedControl.tintColor = [UIColor cb_Grey1Color];
self.segmentedControl.backgroundColor = [UIColor cb_Grey3Color];
NSDictionary *selectedAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
[UIFont cbGothamBookFontWithSize:13.0], NSFontAttributeName,
[UIColor whiteColor], NSForegroundColorAttributeName,
[UIColor cb_Grey1Color], NSBackgroundColorAttributeName, nil];
[self.segmentedControl setTitleTextAttributes:selectedAttributes forState:UIControlStateSelected];
NSDictionary *unselectedAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
[UIFont cbGothamBookFontWithSize:13.0], NSFontAttributeName,
[UIColor cb_Grey2Color], NSForegroundColorAttributeName,
[UIColor cb_Grey3Color], NSBackgroundColorAttributeName, nil];
[self.segmentedControl setTitleTextAttributes:unselectedAttributes forState:UIControlStateNormal];

Font Color swift 3 and swift 4 if you want to change
For Unselected item
segcntrl.setTitleTextAttributes(titleTextAttributes, for: .normal)
For Selected item
segcntrl.setTitleTextAttributes(titleTextAttributes, for: .selected)
//MARK:- Segment color change
self.segc.setTitleTextAttributes([NSAttributedStringKey.foregroundColor:
UIColor.white], for: UIControlState.selected)
self.segc.setTitleTextAttributes([NSAttributedStringKey.foregroundColor:
UIColor.white], for: UIControlState.normal)

As of iOS13, you would be no longer able to modify the tint color of the segment controller. Need to use selectedSegmentTintColor if the color has to be customized.
self.yourSegmentControl.selectedSegmentTintColor = UIColor(red: 240.0/255.0, green: 183.0/255.0, blue: 0.0/255.0, alpha: 1.0)

Here is a sample code that works with iOS9, but it is a hack, and might not work in later versions:
UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] initWithItems:#[#"Title1", #"Title2"]];
for (id segment in [segmentedControl subviews])
{
for (id view in [segment subviews])
{
NSString *desc = [view description];
if ([desc containsString:#"UISegmentLabel"])
{
[segment setTintColor:([desc containsString:#"Title1"] ? [UIColor blueColor] : [UIColor greenColor])];
}
}
}

I was able to do it via Interface Builder in XCode 6. Attached is the tint property:

I wanted to accomplish something similar - set the background color of the selected segment to one color while the 'outline' of the rest of the segments were a different color.
Borrowing heavily from Portland Runner's answer, the idea is to subclass the UISegmentedControl, and override 2 methods to both style the initial state as well as capture the change event to style it automatically as the user selects different segments.
- (void)layoutSubviews {
[super layoutSubviews];
[self updateSegmentColors];
}
-(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesEnded:touches withEvent:event];
[self updateSegmentColors];
}
- (void)updateSegmentColors {
NSArray* segments = [self.subviews sortedArrayUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) {
// UISegmentedControl segments use UISegment objects (private API). But we can safely cast them to UIView objects.
float v1 = ((UIView *)obj1).frame.origin.x;
float v2 = ((UIView *)obj2).frame.origin.x;
if (v1 < v2) return NSOrderedAscending;
else if (v1 > v2) return NSOrderedDescending;
else return NSOrderedSame;
}];
for (int i=0; i<segments.count; i++) {
if (i == self.selectedSegmentIndex) {
[segments[i] setTintColor:[UIColor redColor]];
} else {
[segments[i] setTintColor:[UIColor grayColor]];
}
}
}

Swift 5.0
if #available(iOS 13.0, *) {
// For selected segment
control.selectedSegmentTintColor = UIColor.red
}
// For control's background
control.layer.backgroundColor = UIColor.black.cgColor

Storyboard Solution
Xcode 11
Select the control and multiple color options are now available. If you need further refinement - check out User Defined Runtime Attributes.

Related

Wrong barButton item tint for play/pause buttons built programatically

I have a UIToolbar with audio controls. Sometime around iOS 7 upgrade the color of the bar changed and iOS started shading my buttons differently. That introduced a bug where the play and pause buttons which I change programatically don't match the new look of the toolbar:
Toolbar starts out looking fine:
Now I pressed play so code inserted pause button but wrong color:
Now I pressed pause and code inserted play button, again with wrong color:
I want the play and pause buttons to have that same dark look as the other buttons. I assume I have to do something differently when building the replacement buttons. The raw icon images are all that lighter color, but iOS toolbar seems to be automatically recoloring to darker color from the storyboard, as seen in first screenshot.
Here's the code I use to build the buttons:
- (UIBarButtonItem *) makeBarButton: (NSString *) imageName action:(SEL)targetAction
{
UIImage* image = [UIImage imageNamed:imageName];
CGRect frame = CGRectMake(0 - 20, 0 - 20, image.size.width + 20, image.size.height + 20);
UIButton *button = [[UIButton alloc] initWithFrame:frame];
[button addTarget:self action:targetAction forControlEvents:UIControlEventTouchUpInside];
[button setImage:image forState:UIControlStateNormal];
[button setShowsTouchWhenHighlighted:YES];
return [[UIBarButtonItem alloc] initWithCustomView:button];
}
- (void) setAsPlaying:(BOOL)isPlaying
{
self.rootViewController.playing = isPlaying;
// we need to change which of play/pause buttons are showing, if the one to
// reverse current action isn't showing
if ((isPlaying && !self.pauseButton) || (!isPlaying && !self.playButton))
{
UIBarButtonItem *buttonToRemove = nil;
UIBarButtonItem *buttonToAdd = nil;
if (isPlaying)
{
buttonToRemove = self.playButton;
self.playButton = nil;
self.pauseButton = [self makeBarButton:#"icon_pause.png" action:#selector(pauseAudio:)];
buttonToAdd = self.pauseButton;
}
else
{
buttonToRemove = self.pauseButton;
self.pauseButton = nil;
self.playButton = [self makeBarButton:#"icon_play.png" action:#selector(playAudio:)];
buttonToAdd = self.playButton;
}
// Get the reference to the current toolbar buttons
NSMutableArray *toolbarButtons = [[self.toolbar items] mutableCopy];
// Remove a button from the toolbar and add the other one
if (buttonToRemove)
[toolbarButtons removeObject:buttonToRemove];
if (![toolbarButtons containsObject:buttonToAdd])
[toolbarButtons insertObject:buttonToAdd atIndex:4];
[self.toolbar setItems:toolbarButtons];
}
}
Appreciate your help with this.
Check the following:
If the images are stored inside your image assets, make sure they are template images.
Then you can either A) set their tint colour in Interface Builder to the grey colour you prefer or B) do it programmatically in your makeBarButton method as such;
button.tintColor = [UIColor grayColor];

UISegmentedControl segment order confusion

I'm trying to extend the functionality of the UISegmentedControl and I'm running into some issues with working with individual segments. The problem seems to be relatively generic, so I'm borrowing some code from an example on-line: http://www.framewreck.net/2010/07/custom-tintcolor-for-each-segment-of.html
For easy reference:
UISegmentedControlExtension.h
#interface UISegmentedControl(CustomTintExtension)
-(void)setTag:(NSInteger)tag forSegmentAtIndex:(NSUInteger)segment;
-(void)setTintColor:(UIColor*)color forTag:(NSInteger)aTag;
-(void)setTextColor:(UIColor*)color forTag:(NSInteger)aTag;
-(void)setShadowColor:(UIColor*)color forTag:(NSInteger)aTag;
#end
UISegmentedControlExtension.m
#import "UISegmentedControlExtension.h"
#implementation UISegmentedControl(CustomTintExtension)
-(void)setTag:(NSInteger)tag forSegmentAtIndex:(NSUInteger)segment {
[[[self subviews] objectAtIndex:segment] setTag:tag];
}
-(void)setTintColor:(UIColor*)color forTag:(NSInteger)aTag {
// must operate by tags. Subview index is unreliable
UIView *segment = [self viewWithTag:aTag];
SEL tint = #selector(setTintColor:);
// UISegment is an undocumented class, so tread carefully
// if the segment exists and if it responds to the setTintColor message
if (segment && ([segment respondsToSelector:tint])) {
[segment performSelector:tint withObject:color];
}
}
-(void)setTextColor:(UIColor*)color forTag:(NSInteger)aTag {
UIView *segment = [self viewWithTag:aTag];
for (UIView *view in segment.subviews) {
SEL text = #selector(setTextColor:);
// if the sub view exists and if it responds to the setTextColor message
if (view && ([view respondsToSelector:text])) {
[view performSelector:text withObject:color];
}
}
}
-(void)setShadowColor:(UIColor*)color forTag:(NSInteger)aTag {
// you probably know the drill by now
// you could also combine setShadowColor and setTextColor
UIView *segment = [self viewWithTag:aTag];
for (UIView *view in segment.subviews) {
SEL shadowColor = #selector(setShadowColor:);
if (view && ([view respondsToSelector:shadowColor])) {
[view performSelector:shadowColor withObject:color];
}
}
}
#end
The above example claims that "at some point later, the segment indexes change" -- I don't believe this is the case, but there is definitely something strange going on with the indexes from something like:
[_segmentedControl titleForSegmentAtIndex:i]
and then using the example's code:
[_segmentedControl setTintColor:[UIColor blueColor] forTag:Blue];
If I go through and map the indexes of each segment using the title of the segment:
typedef NS_ENUM(int, colorvalues) {
Blue, Brown, Green, Red, White, Yellow
};
if ([#"Blue" isEqual: title]) {
NSLog(#"Setting Blue(%d) tag on segment: %d", Blue, i);
[_segmentedControl setTag:Blue forSegmentAtIndex:i];
} else if ([#"Brown" isEqual: title]) {
NSLog(#"Setting Brown tag on segment: %d", i);
[_segmentedControl setTag:Brown forSegmentAtIndex:i];
} else if ([#"Green" isEqual: title]) {
NSLog(#"Setting Green tag on segment: %d", i);
[_segmentedControl setTag:Green forSegmentAtIndex:i];
} else if ([#"Red" isEqual: title]) {
NSLog(#"Setting Red tag on segment: %d", i);
[_segmentedControl setTag:Red forSegmentAtIndex:i];
} else if ([#"White" isEqual: title]) {
NSLog(#"Setting White tag on segment: %d", i);
[_segmentedControl setTag:White forSegmentAtIndex:i];
} else if ([#"Yellow" isEqual: title]) {
NSLog(#"Setting Yellow tag on segment: %d", i);
[_segmentedControl setTag:Yellow forSegmentAtIndex:i];
}
and then set the Tint using the example code above:
[_segmentedControl setTintColor:[UIColor blueColor] forTag:Blue];
[_segmentedControl setTintColor:[UIColor brownColor] forTag:Brown];
[_segmentedControl setTintColor:[UIColor greenColor] forTag:Green];
[_segmentedControl setTintColor:[UIColor redColor] forTag:Red];
[_segmentedControl setTintColor:[UIColor whiteColor] forTag:White];
[_segmentedControl setTintColor:[UIColor yellowColor] forTag:Yellow];
I end up with:
If I create the UISegmentedControl programmatically I can influence the offsetting of the indexing by setting the selected segment before adding it to the subview. With the selected segment set to 0 things line up correctly. However through the interface builder things are consistently broken, even when choosing a different selected segment via the GUI. I'm assuming because the control is being added to the subview before the segment is selected.
Any ideas what's causing this strange behavior?
[[[self subviews] objectAtIndex:segment] setTag:tag];
This line has problem. Set the segments in reverse order. Eg.
#define kTagSecond 222
#define kTagFirst 111
[self.segment setTag:kTagFirst forSegmentAtIndex:1];
[self.segment setTag:kTagSecond forSegmentAtIndex:0];
Where kTagFirst is the first segment and kTagSecond is the second segment

Why doesn't UIButton.imageView setTintColor: work in IBAction

I'm trying to change the color of UIButton image. In the viewDidLoad method I change the tint color to either the "appColor" or a grey color, that works fine. When the user taps the button, I try to change the tint color again but nothing happens. I even tried to change the image with UIButton.imageView setImage and nothing happens either. What am I doing wrong?
This works
- (void)viewDidLoad{
if ([checkActivityArray containsObject:[place objectId]]){
[checkCount setTextColor:appColor];
checkButton.imageView.image = [checkButton.imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
[checkButton.imageView setTintColor:appColor];
}
else{
[checkCount setTextColor:[UIColor colorWithRed:170.0/255.0 green:170.0/255.0 blue:170.0/255.0 alpha:1]];
checkButton.imageView.image = [checkButton.imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
[checkButton.imageView setTintColor:[UIColor colorWithRed:170.0/255.0 green:170.0/255.0 blue:170.0/255.0 alpha:1]];
}
}
This doesn't
- (IBAction)checkMarkButton:(UIButton *)sender {
sender.enabled = NO;
CheckMarkController *checkMark = [[CheckMarkController alloc]init];
BOOL didComplete = NO;
if ([checkActivityArray containsObject:[place objectId]]){
didComplete = [checkMark removeCheckMark:place];
}else{
didComplete = [checkMark addCheckMark:place];
}
if (didComplete) {
checkActivityArray = [[NSMutableArray alloc] initWithContentsOfFile:checkMarkArrayFileName];
int tempInt = [checkCount.text intValue];
if ([checkActivityArray containsObject:[place objectId]]){
[sender.imageView setImage:[checkButton.imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]];
[sender.imageView setTintColor:appColor];
[checkCount setTextColor:appColor];
tempInt++;
checkCount.text = [NSString stringWithFormat:#"%d", tempInt];
}
else{
sender.imageView.image = [sender.imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
[sender.imageView setTintColor:[UIColor colorWithRed:170.0/255.0 green:170.0/255.0 blue:170.0/255.0 alpha:1]];
[checkCount setTextColor:[UIColor colorWithRed:170.0/255.0 green:170.0/255.0 blue:170.0/255.0 alpha:1]];
tempInt--;
checkCount.text = [NSString stringWithFormat:#"%d", tempInt];
}
sender.enabled = YES;
}
}
According to the iOS Developer Library:
To refresh subview rendering when this property changes, override the tintColorDidChange method.
And the tintColorDidChange method is defined here:
UIView tintColorDidChange
The system calls this method on a view when your code changes the value of the tintColor property on that view. In addition, the system calls this method on a subview that inherits a changed interaction tint color.
In your implementation, refresh the view rendering as needed.

Search Bar background color Gray ios7

I am currently working on an app that worked fine until ios7 came along. The search bar used to be transparent and blended into the blue background of the navigation bar. Now that I am working in ios7, the nav bar is blue, however the search bar has a gray background to it. How do I make it blue or transparent?
Here is an image:
Try this:
if(IOS_7)
{
self.searchBar.searchBarStyle = UISearchBarStyleMinimal;
}
You can set "Bar Tint" to "Clear Color" in Interface Builder (.xib):
It can also be done in code:
self.searchBar.barTintColor = [UIColor clearColor];
To make it a flat color, you simply need to remove the UISearchBarBackground view.
I created a recursive method to properly clean the search bar.
- (void) removeUISearchBarBackgroundInViewHierarchy:(UIView *)view
{
for (UIView *subview in [view subviews]) {
if ([subview isKindOfClass:NSClassFromString(#"UISearchBarBackground")]) {
[subview removeFromSuperview];
break; //To avoid an extra loop as there is only one UISearchBarBackground
} else {
[self removeUISearchBarBackgroundInViewHierarchy:subview];
}
}
}
You can simply send your search bar to the method and change the color afterward.
[self removeUISearchBarBackgroundInViewHierarchy:self.searchDisplayController.searchBar];
self.searchDisplayController.searchBar.backgroundColor = yourUIColor;
Swift 4.2
You can use this extension to change Font and Background color of the SearchBar.
extension UISearchBar {
var textField: UITextField? {
let subViews = subviews.flatMap { $0.subviews }
guard let tf = (subViews.filter { $0 is UITextField }).first as? UITextField else { return nil }
return tf
}
func setTextColor(color: UIColor) {
textField?.textColor = color
}
func setBackgroundColor(color: UIColor) {
textField?.backgroundColor = color
}
}
**Edit - This worked for me in iOS 7
// Set the color to whatever blue color that is in your screenshot
self.searchBar.backgroundImage = [UIImage imageWithColor:[UIColor redColor] cornerRadius:5.0f];
If you want all of your search bar's to be a certain color do this:
// Put this in your app delegate's didFinishLaunchingWithOptions method
// Whatever color you want for searchBarColor
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) { // For iOS 7
UIColor *searchBarColor = [UIColor blueColor];
[[UISearchBar appearance] setBackgroundColor:searchBarColor];
}
If you just want that particular search bar background to be a color:
// Set it in your viewDidLoad method of your controller
// Replace the yourSearchBar property with whatever you're doing to instantiate the search bar
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) { // For iOS 7
{
UIColor *searchBarColor = [UIColor blueColor];
self.yourSearchBar.backgroundColor = searchBarColor;
}

is groupTableViewBackgroundColor deprecated on iOS 6?

I was just testing my app with iOS 6.0 and Xcode 4.5GM and I have set up a view like this:
[self.view setBackgroundColor:[UIColor groupTableViewBackgroundColor]];
So, the view has the same pattern than a common table view.
This works fine on iOS 4 and 5, but in iOS 6 it just gives me a white background.
Is this deprecated? If so, how can I replace it?
Thanks
This method will be deprecated during the 6.0 seed program
If you want to have a background in your own view that looks like the table view background,
then you should create an empty table view and place it behind your content.
First, add this to your viewDidLoad:
self.tableView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"tableViewBackground.png"]];
OR
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"tableViewBackground.png"]];
Then add this images to your app:
tableViewBackground.png
tableViewBackground#2x.png
I've written a UIColor category to replace groupTableViewBackgroundColor:
#interface UIColor (UITableViewBackground)
+ (UIColor *)groupTableViewBackgroundColor;
#end
#implementation UIColor (UITableViewBackground)
+ (UIColor *)groupTableViewBackgroundColor
{
__strong static UIImage* tableViewBackgroundImage = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
UIGraphicsBeginImageContextWithOptions(CGSizeMake(7.f, 1.f), NO, 0.0);
CGContextRef c = UIGraphicsGetCurrentContext();
[[self colorWithRed:185/255.f green:192/255.f blue:202/255.f alpha:1.f] setFill];
CGContextFillRect(c, CGRectMake(0, 0, 4, 1));
[[self colorWithRed:185/255.f green:193/255.f blue:200/255.f alpha:1.f] setFill];
CGContextFillRect(c, CGRectMake(4, 0, 1, 1));
[[self colorWithRed:192/255.f green:200/255.f blue:207/255.f alpha:1.f] setFill];
CGContextFillRect(c, CGRectMake(5, 0, 2, 1));
tableViewBackgroundImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
});
return [self colorWithPatternImage:tableViewBackgroundImage];
}
#end
This solution also allows to tweak the appearance of the background. Feel free to change the drawing code :)
In iOS6 SKD, comments in UIInterface.h suggest the following:
Group style table view backgrounds can no longer be represented by
a simple color.
If you want to have a background in your own view
that looks like the table view background, then you should create
an empty table view and place it behind your content.
This method will be deprecated during the 6.0 seed program
A simple solution is to set the background with equivalent RGB values:
[self.view setBackgroundColor:[UIColor colorWithRed:215.0/255.0 green:217.0/255.0 blue:223.0/255.0 alpha:1.0]];
You can them set the view background to color to White or whatever you like in the xib to suppress the warning.
If it helps anyone, here's specifically what I'm doing in my custom view to get this background (using hint from Mr Beloeuvre)
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor clearColor];
UITableView *tv = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStyleGrouped];
[self.view addSubview:tv];
[self.view sendSubviewToBack:tv];
// ...
}
Try this:
[myTableView setBackgroundView:nil];
[myTableView setBackgroundView:[[[UIView alloc] init] autorelease]];
You may have difficult time to locate the view if you use storyboard and have many views. You can click on "Show the Version editor" button the right top corner. This will change story view to XML text view. Search for "groupTableViewBackGroundColor". You should find views with this attribute.
It's good idea to use standard methods for previous iOs versions. So I improved solution of James Boutcher:
+ (void)setBackgroundColorForTableView:(UITableView*) tableView
{
UIColor* color = [UIColor whiteColor];
NSString* version = [[UIDevice currentDevice] systemVersion];
if([version floatValue] < 6.0)
{
tableView.backgroundColor = color;
}
else
{
tableView.backgroundView = nil;
UIView* bv = [[UIView alloc] init];
bv.backgroundColor = color;
tableView.backgroundView = bv;
[bv release];
}
}
Elaborating on #NSElvis's solution, here is the identical grouped table view background asset (it's wide enough so you don't get funny effects in landscape orientation)
back-tableview#2x.png
To use it, simply do
[YOUR_VIEW setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:#"back-tableview"]]];

Resources