Friday, June 1, 2012

Gradients on UIView and UILabels On iPhone


My application needs to display text in either a View or Label but the back ground must be a gradient as opposed to a true color. Using a graphics program to create desired look is no good as the text may vary depending on data returned from a server.



Does anyone know the quickest way to tackle this? Your thoughts are greatly appreciated.


Source: Tips4all

7 comments:

  1. You could also use a graphic image one pixel wide as the gradient, and set the view property to expand the graphic to fill the view (assuming you are thinking of a simple linear gradient and not some kind of radial graphic).

    ReplyDelete
  2. I realize this is an older thread, but for future reference:

    As of iPhone SDK 3.0, custom gradients can be implemented very easily, without subclassing or images, by using the new CAGradientLayer:

    UIView *view = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 100)] autorelease];
    CAGradientLayer *gradient = [CAGradientLayer layer];
    gradient.frame = view.bounds;
    gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor blackColor] CGColor], (id)[[UIColor whiteColor] CGColor], nil];
    [view.layer insertSublayer:gradient atIndex:0];


    Take a look at the CAGradientLayer docs. You can optionally specify start and end points (in case you don't want a linear gradient that goes straight from the top to the bottom), or even specific locations that map to each of the colors.

    ReplyDelete
  3. You can use Core Graphics to draw the gradient, as pointed to in Mike's response. As a more detailed example, you could create a UIView subclass to use as a background for your UILabel. In that UIView subclass, override the drawRect: method and insert code similar to the following:

    - (void)drawRect:(CGRect)rect
    {
    CGContextRef currentContext = UIGraphicsGetCurrentContext();

    CGGradientRef glossGradient;
    CGColorSpaceRef rgbColorspace;
    size_t num_locations = 2;
    CGFloat locations[2] = { 0.0, 1.0 };
    CGFloat components[8] = { 1.0, 1.0, 1.0, 0.35, // Start color
    1.0, 1.0, 1.0, 0.06 }; // End color

    rgbColorspace = CGColorSpaceCreateDeviceRGB();
    glossGradient = CGGradientCreateWithColorComponents(rgbColorspace, components, locations, num_locations);

    CGRect currentBounds = self.bounds;
    CGPoint topCenter = CGPointMake(CGRectGetMidX(currentBounds), 0.0f);
    CGPoint midCenter = CGPointMake(CGRectGetMidX(currentBounds), CGRectGetMidY(currentBounds));
    CGContextDrawLinearGradient(currentContext, glossGradient, topCenter, midCenter, 0);

    CGGradientRelease(glossGradient);
    CGColorSpaceRelease(rgbColorspace);
    }


    This particular example creates a white, glossy-style gradient that is drawn from the top of the UIView to its vertical center. You can set the UIView's backgroundColor to whatever you like and this gloss will be drawn on top of that color. You can also draw a radial gradient using the CGContextDrawRadialGradient function.

    You just need to size this UIView appropriately and add your UILabel as a subview of it to get the effect you desire.

    EDIT (4/23/2009): Per St3fan's suggestion, I have replaced the view's frame with its bounds in the code. This corrects for the case when the view's origin is not (0,0).

    ReplyDelete
  4. When using CAGradientLayer, as opposed to CGGradient, the gradient is not smooth, but has noticeable stepping to it. See :

    To get more attractive results it is better to use CGGradient.

    ReplyDelete
  5. See here:

    http://stackoverflow.com/questions/227005/manually-drawing-a-gradient-in-iphone-apps

    ReplyDelete
  6. This is what I got working- set UIButton in xCode's IB to transparent/clear, and no bg image.

    UIColor *pinkDarkOp = [UIColor colorWithRed:0.9f green:0.53f blue:0.69f alpha:1.0];
    UIColor *pinkLightOp = [UIColor colorWithRed:0.79f green:0.45f blue:0.57f alpha:1.0];

    CAGradientLayer *gradient = [CAGradientLayer layer];
    gradient.frame = [[shareWordButton layer] bounds];
    gradient.cornerRadius = 7;
    gradient.colors = [NSArray arrayWithObjects:
    (id)pinkDarkOp.CGColor,
    (id)pinkLightOp.CGColor,
    nil];
    gradient.locations = [NSArray arrayWithObjects:
    [NSNumber numberWithFloat:0.0f],
    [NSNumber numberWithFloat:0.7],
    nil];

    [[recordButton layer] insertSublayer:gradient atIndex:0];

    ReplyDelete
  7. I achieve this in a view with a subview that is an UIImageView. The image the ImageView is pointing to is a gradient. Then I set a background color in the UIView, and I have a colored gradient view. Next I use the view as I need to and everything I draw will be under this gradient view. By adding a second view on top of the ImageView, you can have some options whether your drawing will be below or above the gradient...

    ReplyDelete