Nic Hubbard
Nic Hubbard

Reputation: 42139

iPad grouped tableView background color? What is it?

I love the new grouped background color of my tableView on ipad. I would like to use that same color on the background of my UIViewController which is on the right side of my split controller.

Does anyone know what this color is? It seems to be a slight gradient.

Upvotes: 4

Views: 3577

Answers (5)

RLB
RLB

Reputation: 171

These are all the out of the box texture colors, static methods on UIColor:

+ (UIColor *)lightTextColor;                // for a dark background
+ (UIColor *)darkTextColor;                 // for a light background
+ (UIColor *)groupTableViewBackgroundColor;
+ (UIColor *)viewFlipsideBackgroundColor;
+ (UIColor *)scrollViewTexturedBackgroundColor __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_3_2);

Upvotes: 0

woof
woof

Reputation: 1288

[UIColor colorWithRed:0.953 green:0.953 blue:0.953 alpha:1] /#f3f3f3/

Upvotes: 1

Constantino Tsarouhas
Constantino Tsarouhas

Reputation: 6886

I'm just throwing it here, but if you could use SVG somewhere (like in a web page, or in an app using some kind of SVG-to-Core-Graphics library, I know a few exist, but it's not the ideal solution), I've got the code:

<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 1 1" preserveAspectRatio="none">
    <linearGradient id="g146" gradientUnits="userSpaceOnUse" x1="0%" y1="0%" x2="0%" y2="100%">
        <stop stop-color="#E2E5EA" offset="0" />
        <stop stop-color="#D1D3D9" offset="1" />
    </linearGradient>
    <rect x="0" y="0" width="1" height="1" fill="url(#g146)" />
</svg>

Created using the DigitalColor Meter app (IMO an awful name for an Apple app), Xcode 4.5ß4 and SVG Gradient Background Maker.

Upvotes: 0

herzbube
herzbube

Reputation: 13378

Based on Lutz's answer, and the answer to this question, the following custom view controller code creates a replica of the table view's background view. There is, however, a problem with auto-rotation, which is being addressed in the second code snippet below.

// You also need to link against QuartzCore.framework
#import <QuartzCore/QuartzCore.h>

- (void) loadView
{
  CGRect mainViewFrame = [self mainViewFrame];
  self.view = [[[UIView alloc] initWithFrame:mainViewFrame] autorelease];
  CAGradientLayer* gradient = [CAGradientLayer layer];
  gradient.frame = self.view.bounds;
  UIColor* startColor = [UIColor colorWithRed:226.0/255.0 green:229.0/255.0 blue:234.0/255.0 alpha:1.0];
  UIColor* endColor = [UIColor colorWithRed:208.0/255.0 green:210.0/255.0 blue:216.0/255.0 alpha:1.0];
  // Cast to (id) is necessary to get rid of a compiler warning
  gradient.colors = [NSArray arrayWithObjects:(id)startColor.CGColor, (id)endColor.CGColor, nil];
  // Inserting at index position 0 ensures that the gradient is drawn
  // in the background even if the view already has subviews or other
  // sublayers
  [view.layer insertSublayer:gradient atIndex:0];

  // add more subviews
}

- (CGRect) mainViewFrame
{
  // add your frame calculating code here
}

- (void) willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration
{
  [UIView animateWithDuration:duration
                        delay:0
                      options:UIViewAnimationCurveLinear
                   animations:^{
                     ((CALayer*)[self.view.layer.sublayers objectAtIndex:0]).frame = self.view.bounds;
                   }
                   completion:NULL];
}

The problem with the above code is that, while the rotation animation is running, the original white background is visible for a very short time. Unfortunately I don't understand enough about layers to fix this, so I started to look for an alternative to CAGradientLayer. Setting CALayer.contents with a gradient image is what I found.

Most of the code below deals with creating the pattern image required as input for the convenience constructor, only this time the gradient is drawn "manually" with Core Graphics instead of with a CAGradientLayer. The gradient drawing code, by the way, is heavily based on Ray Wenderlich's Core Graphics 101 tutorial.

#import <QuartzCore/QuartzCore.h>

- (void) loadView
{
  CGRect mainViewFrame = [self mainViewFrame];
  self.view = [[[UIView alloc] initWithFrame:mainViewFrame] autorelease];
  UIColor* startColor = [UIColor colorWithRed:226.0/255.0 green:229.0/255.0 blue:234.0/255.0 alpha:1.0];
  UIColor* endColor = [UIColor colorWithRed:208.0/255.0 green:210.0/255.0 blue:216.0/255.0 alpha:1.0];

  UIImage* backgroundPattern = [self gradientImageWithSize:CGSizeMake(1, mainViewFrame.size.height)
                                                startColor:startColor
                                                  endColor:endColor];
  self.view.layer.contents = (id)backgroundPattern.CGImage;

  // add more subviews
}

- (CGRect) mainViewFrame
{
  // add your frame calculating code here
}

- (UIImage*) gradientImageWithSize:(CGSize)size startColor:(UIColor*)startColor endColor:(UIColor*)endColor
{
  UIGraphicsBeginImageContext(size);
  CGContextRef context = UIGraphicsGetCurrentContext();

  CGRect rect = CGRectMake(0, 0, size.width, size.height);
  [self drawLinearGradientWithContext:context rect:rect startColor:startColor.CGColor endColor:endColor.CGColor];

  UIImage* gradientImage = UIGraphicsGetImageFromCurrentImageContext();
  UIGraphicsEndImageContext();
  return gradientImage;
}

- (void) drawLinearGradientWithContext:(CGContextRef)context rect:(CGRect)rect startColor:(CGColorRef)startColor endColor:(CGColorRef)endColor
{
  CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

  CGFloat locations[] = { 0.0, 1.0 };
  NSArray* colors = [NSArray arrayWithObjects:(id)startColor, (id)endColor, nil];
  // NSArray is toll-free bridged, so we can simply cast to CGArrayRef
  CGGradientRef gradient = CGGradientCreateWithColors(colorSpace,
                                                      (CFArrayRef)colors,
                                                      locations);

  // Draw the gradient from top-middle to bottom-middle
  CGPoint startPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMinY(rect));
  CGPoint endPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMaxY(rect));

  // Remember context so that later on we can undo the clipping we are going to
  // add to the Core Graphics state machine
  CGContextSaveGState(context);
  // Add clipping with the specified rect so that we can simply draw into the
  // specified context without changing anything outside of the rect. With this
  // approach, the caller can give us a context that already has other stuff
  // in it
  CGContextAddRect(context, rect);
  CGContextClip(context);
  // Finally draw the gradient
  CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);
  // Undo clipping
  CGContextRestoreGState(context);

  // Cleanup memory allocated by CGContextDrawLinearGradient()
  CGGradientRelease(gradient);
  // Cleanup memory allocated by CGColorSpaceCreateDeviceRGB()
  CGColorSpaceRelease(colorSpace);
}

I like this code best because

  • It auto-rotates cleanly
  • There is no custom code to handle auto-rotation
  • The gradient-related functions can be refactored into a separate utility class to make them more re-usable

Upvotes: 3

Lutz Roeder
Lutz Roeder

Reputation: 67

It is not a color but a UIImageView with a gradient image:

UIImageView* imageView = (UIImageView*) self.tableView.backgroundView;
NSString* file = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/Test.png"];
NSData* data = UIImagePNGRepresentation(imageView.image);
[data writeToFile:file atomically:YES];

Upvotes: 3

Related Questions