1

I am have been experimenting with CGContextDrawLinearGradient and I terribly confused with what start point and end point mean? I thought they mean coordinates on the current CGContext so if I define start point to be 0,0 and end point to be 100,100, i would get a square with gradient. I get something else altogether that I just cannot connect to my co-ordinates.

This is the code that I have:

- (void)drawRect:(CGRect)rect {
// Drawing code 
CGContextRef current_context = UIGraphicsGetCurrentContext();
CGContextSaveGState(current_context);

// Gradient
CGFloat locations[3] = {0.0, 0.5, 1.0};
CGFloat components[12] = {1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0};
CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
CGGradientRef gradient = CGGradientCreateWithColorComponents(colorspace, components, locations, 3);
CGPoint startPoint = CGPointMake(0, 0);
CGPoint endPoint = CGPointMake(40, 40);
CGContextDrawLinearGradient(current_context, gradient, startPoint, endPoint, 0);


// Shadow
CGContextSetShadow(current_context, CGSizeMake(4,7), 1.0);

// Image
UIImage *logoImage = [UIImage imageNamed:@"logo.png"];
[logoImage drawInRect:bounds];
CGContextRestoreGState(current_context);

}

Thanks for your help in advance..

noobuntu
  • 903
  • 1
  • 18
  • 42
  • I wouldn't expect you to get a square, but I would expect the gradient. What are you seeing that you don't understand? Can you post a picture of what you got vs. what you expected? – user1118321 Mar 10 '14 at 04:50

2 Answers2

4

Most of your code is quite OK; the problem occurs in the following lines:

CGPoint startPoint = CGPointMake(0, 0);
CGPoint endPoint = CGPointMake(40, 40);
CGContextDrawLinearGradient(current_context, gradient, startPoint, endPoint, 0);

CGContextDrawLinearGradient expects to get a start and an end point (defining a line, not two diagonal edges of a square!).

The gradient is then drawn by colored lines perpendicular to this controlling line. The drawing starts with a line going through startPoint (perpendicular to the line between startPoint and endPoint) using the start color (color at location 0). The next line is drawn through a point 'one pixel' closer to the endPoint, with a color calculated to be somewhere between the start and the end or next color (depending of the number of color locations). Finally a line is drawn through the endPoint (again perpendicular...) using the end color.

The advantage of using a (controlling) line instead of a square is, that the gradient can be drawn in any direction; horizontally, vertically, somewhere between, only depending of the direction of the given line.

In your example code, the gradient should be diagonally, as your line has an angle of 45° to the x-axis :-).

LaborEtArs
  • 1,938
  • 23
  • 27
  • To expand on what you've said, the "shape" of the gradient, when no options are specified, is an infinite strip. It's the section of the plane defined by all of the imaginary, infinitely-long perpendicular lines you described. If `.DrawsBeforeStartLocation` or `.DrawsAfterEndLocation` are specified, then it's a half-plane. If both are specified, it's the whole plane. Also, the start and end points don't have to be within the context's "bounds". They can be anywhere and the gradient will just be clipped to the actual drawing destination. – Ken Thomases Sep 18 '15 at 06:57
0

code from raywanderlich tutorial

override func drawRect(rect: CGRect) {

  //2 - get the current context
  let context = UIGraphicsGetCurrentContext()
  let colors = [startColor.CGColor, endColor.CGColor]

  //3 - set up the color space
  let colorSpace = CGColorSpaceCreateDeviceRGB()

  //4 - set up the color stops
  let colorLocations:[CGFloat] = [0.0, 1.0]

  //5 - create the gradient
  let gradient = CGGradientCreateWithColors(colorSpace, 
                                            colors, 
                                            colorLocations)

  //6 - draw the gradient
  var startPoint = CGPoint.zeroPoint
  var endPoint = CGPoint(x:0, y:self.bounds.height)
  CGContextDrawLinearGradient(context, 
                              gradient, 
                              startPoint, 
                              endPoint, 
                              0)
}
IamMashed
  • 1,811
  • 2
  • 21
  • 32