How to set the cagradientcolor to the uibutton cashapelayer objective c.I want to fill colour to different shaped button - objective-c

I want to add the colour to UIButton CAShape layer.Is that possible according to the reference in the url Gradient color effect on CAShapeLayer.. we can add the colour to the UIButton CAShape layer.I can see the colour to the button stroke but i want the gradient colour to the button CAShape layer.please help in setting the colour to UIButton CAShape layer.The code is
-(void)changeColour:(id)sender
{
#try{
if(m_cObjbuttonPtr1.layer.sublayers.count > 0){for(CALayer *layer in m_cObjbuttonPtr1.layer.sublayers){if([layer isKindOfClass:[CAShapeLayer class]]) [layer removeFromSuperlayer];}}if (m_cObjbuttonPtr2.layer.sublayers.count > 0){ for(CALayer *layer in m_cObjbuttonPtr2.layer.sublayers){if([layer isKindOfClass:[CAShapeLayer class]])[layer removeFromSuperlayer];}}if(m_cObjbuttonPtr3.layer.sublayers.count > 0){for(CALayer *layer in m_cObjbuttonPtr3.layer.sublayers){if([layer isKindOfClass:[CAShapeLayer class]]) [layer removeFromSuperlayer];}}if (m_cObjbuttonPtr4.layer.sublayers.count > 0){ for(CALayer *layer in m_cObjbuttonPtr4.layer.sublayers){if([layer isKindOfClass:[CAShapeLayer class]])[layer removeFromSuperlayer];}}if(m_cObjbuttonPtr5.layer.sublayers.count > 0){ for(CALayer *layer in m_cObjbuttonPtr5.layer.sublayers){if([layer isKindOfClass:[CAShapeLayer class]])[layer removeFromSuperlayer];}}}#catch (NSException *exception){}
UIButton *tempButton =(UIButton *)sender;
UIBezierPath *aPath = [UIBezierPath bezierPath];
[aPath moveToPoint:CGPointMake(0.0, 0.0)];
[aPath addLineToPoint:CGPointMake(0.0, 35.0)];
[aPath moveToPoint:CGPointMake(0.0, 35.0)];
[aPath addLineToPoint:CGPointMake(80.0, 55.0)];
[aPath moveToPoint:CGPointMake(80.0, 55.0)];
[aPath addLineToPoint:CGPointMake(180.0, 35.0)];
[aPath moveToPoint:CGPointMake(180.0, 35.0)];
[aPath addLineToPoint:CGPointMake(180.0, 0.0)];
[aPath moveToPoint:CGPointMake(180.0, 0.0)];
[aPath addLineToPoint:CGPointMake(0.0, 0.0)];
[aPath closePath];
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
if(tempButton.tag == 1)
shapeLayer.frame = m_cObjbuttonPtr1.bounds;
if(tempButton.tag == 2)
shapeLayer.frame = m_cObjbuttonPtr2.bounds;
if(tempButton.tag == 3)
shapeLayer.frame = m_cObjbuttonPtr3.bounds;
if(tempButton.tag == 4)
shapeLayer.frame = m_cObjbuttonPtr4.bounds;
if(tempButton.tag == 5)
shapeLayer.frame = m_cObjbuttonPtr5.bounds;
shapeLayer.path = aPath.CGPath;
[shapeLayer setStrokeColor:[[UIColor redColor] CGColor]];
shapeLayer.fillColor = [[UIColor redColor] CGColor];
shapeLayer.lineWidth = 2;
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
if(tempButton.tag == 1)
gradientLayer.frame = m_cObjbuttonPtr1.bounds;
if(tempButton.tag == 2)
gradientLayer.frame = m_cObjbuttonPtr2.bounds;
if(tempButton.tag == 3)
gradientLayer.frame = m_cObjbuttonPtr3.bounds;
if(tempButton.tag == 4)
gradientLayer.frame = m_cObjbuttonPtr4.bounds;
if(tempButton.tag == 5)
gradientLayer.frame = m_cObjbuttonPtr5.bounds;
gradientLayer.colors = [NSArray arrayWithObjects:
(id)[UIColor colorWithRed:0.98f green:0.31f blue:0.46f alpha:0.0].CGColor,
(id)[UIColor colorWithRed:0.98f green:0.31f blue:0.14f alpha:0.0].CGColor,nil];
gradientLayer.locations = [NSArray arrayWithObjects:
[NSNumber numberWithFloat:0.0f],
[NSNumber numberWithFloat:1.0f],
nil];
if(tempButton.tag == 1){
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
gradientLayer.startPoint = CGPointMake(0.5,1.0);
gradientLayer.endPoint = CGPointMake(0.5,0.0);
gradientLayer.frame = CGRectMake(0, 0, shapeLayer.frame.size.width, shapeLayer.frame.size.height);
NSMutableArray *colors = [NSMutableArray array];
for (int i = 0; i < 10; i++) {
[colors addObject:(id)[[UIColor colorWithHue:(0.1 * i) saturation:1 brightness:.8 alpha:1] CGColor]];
}
gradientLayer.colors = colors;
[gradientLayer setMask:shapeLayer];
[shapeLayer setFillRule:kCAFillRuleEvenOdd];
[shapeLayer setFillColor:[[UIColor orangeColor] CGColor]];
[m_cObjbuttonPtr1.layer addSublayer:shapeLayer];
}
if(tempButton.tag == 2){
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
gradientLayer.startPoint = CGPointMake(0.5,1.0);
gradientLayer.endPoint = CGPointMake(0.5,0.0);
gradientLayer.frame = CGRectMake(0, 0, m_cObjbuttonPtr2.layer.frame.size.width, m_cObjbuttonPtr2.layer.frame.size.height);
NSMutableArray *colors = [NSMutableArray array];
for (int i = 0; i < 10; i++) {
[colors addObject:(id)[[UIColor colorWithHue:(0.1 * i) saturation:1 brightness:.8 alpha:1] CGColor]];
}
gradientLayer.colors = [NSArray arrayWithObjects:
(id)[UIColor colorWithRed:0.98f green:0.31f blue:0.46f alpha:0.0].CGColor,
(id)[UIColor colorWithRed:0.98f green:0.31f blue:0.14f alpha:0.0].CGColor,
nil];
[gradientLayer setMask:shapeLayer];
[m_cObjbuttonPtr2.layer addSublayer:shapeLayer];
}
if(tempButton.tag == 3){
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
gradientLayer.startPoint = CGPointMake(0.5,1.0);
gradientLayer.endPoint = CGPointMake(0.5,0.0);
gradientLayer.frame = CGRectMake(0, 0, m_cObjbuttonPtr3.layer.frame.size.width, m_cObjbuttonPtr3.layer.frame.size.height);
NSMutableArray *colors = [NSMutableArray array];
for (int i = 0; i < 10; i++) {
[colors addObject:(id)[[UIColor colorWithHue:(0.1 * i) saturation:1 brightness:.8 alpha:1] CGColor]];
}
gradientLayer.colors = colors;
[gradientLayer setMask:shapeLayer];
[m_cObjbuttonPtr3.layer addSublayer:shapeLayer];
}
if(tempButton.tag == 4){
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
gradientLayer.startPoint = CGPointMake(0.5,1.0);
gradientLayer.endPoint = CGPointMake(0.5,0.0);
gradientLayer.frame = CGRectMake(0, 0, m_cObjbuttonPtr4.layer.frame.size.width, m_cObjbuttonPtr4.layer.frame.size.height);
NSMutableArray *colors = [NSMutableArray array];
for (int i = 0; i < 10; i++) {
[colors addObject:(id)[[UIColor colorWithHue:(0.1 * i) saturation:1 brightness:.8 alpha:1] CGColor]];
}
gradientLayer.colors = colors;
[gradientLayer setMask:shapeLayer];
[m_cObjbuttonPtr4.layer addSublayer:shapeLayer];
}
if(tempButton.tag == 5){
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
gradientLayer.startPoint = CGPointMake(0.5,1.0);
gradientLayer.endPoint = CGPointMake(0.5,0.0);
gradientLayer.frame = CGRectMake(0, 0, m_cObjbuttonPtr5.layer.frame.size.width, m_cObjbuttonPtr5.layer.frame.size.height);
NSMutableArray *colors = [NSMutableArray array];
for (int i = 0; i < 10; i++) {
[colors addObject:(id)[[UIColor colorWithHue:(0.1 * i) saturation:1 brightness:.8 alpha:1] CGColor]];
}
gradientLayer.colors = colors;
[gradientLayer setMask:shapeLayer];
[m_cObjbuttonPtr5.layer addSublayer:shapeLayer];
}
}

Related

CAGradientLayer in UILabel in UIStackView

This is a custom UIView subclass for a tableHeaderView.
I'm currently trying to put a gradient to an UILabel that's in a vertical UIStackView. It works really well without gradient even in RTL languages (gets moved to the right), but as soon as I add the gradient, the label that's the maskView of the gradientView gets completely out of its place. Here the code for better comprehension:
- (instancetype)initWithTitle:(NSString *)title subtitle:(NSString *)subtitle colors:(NSArray<UIColor *> *)colors {
if (self = [super initWithFrame:CGRectMake(0, 0, self.superview.frame.size.width, 200)]) {
// Labels
UILabel *titleLabel = [[UILabel alloc] init];
titleLabel.text = title;
titleLabel.font = [UIFont boldSystemFontOfSize:42.f];
titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
[titleLabel sizeToFit];
UILabel *subtitleLabel = [[UILabel alloc] init];
subtitleLabel.text = subtitle;
subtitleLabel.font = [UIFont systemFontOfSize:24.f];
subtitleLabel.lineBreakMode = NSLineBreakByWordWrapping;
[subtitleLabel sizeToFit];
// Create gradient
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = titleLabel.bounds;
NSMutableArray *cgcolors = [NSMutableArray new];
for (int i = 0; i < colors.count; i++) {
cgcolors[i] = (id)colors[i].CGColor;
}
gradient.colors = cgcolors;
gradient.locations = #[#0, #1];
UIView *gradientView = [[UIView alloc] initWithFrame:titleLabel.bounds];
[gradientView.layer addSublayer:gradient];
[gradientView addSubview:titleLabel];
gradientView.maskView = titleLabel;
// Stack
UIStackView *stackView = [[UIStackView alloc] initWithArrangedSubviews:#[gradientView, subtitleLabel]];
stackView.alignment = UIStackViewAlignmentLeading;
stackView.axis = UILayoutConstraintAxisVertical;
stackView.distribution = UIStackViewDistributionEqualCentering;
stackView.spacing = 0;
stackView.translatesAutoresizingMaskIntoConstraints = NO;
[self addSubview:stackView];
[NSLayoutConstraint activateConstraints:#[
[stackView.leadingAnchor constraintEqualToAnchor:self.leadingAnchor constant:25],
[stackView.centerYAnchor constraintEqualToAnchor:self.centerYAnchor],
[stackView.heightAnchor constraintEqualToConstant:titleLabel.frame.size.height + subtitleLabel.frame.size.height]
]];
}
return self;
}
With LTR languages, it looks good, but with RTL languages, the frame of the gradientView that contains the titleLabel becomes {[width of subtitleLabel], 0, 0, 0} for no reason. The cause is the gradient view, because without it it works fine, but I can't find why.
I tried titleLabel.layer.mask, placing the gradient block at the end, but nothing worked.
EDIT :
Working code:
- (instancetype)initWithTitle:(NSString *)title subtitle:(NSString *)subtitle colors:(NSArray<__kindof UIColor *> *)colors {
if (self = [super initWithFrame:CGRectMake(0, 0, self.superview.frame.size.width, 200)]) {
// Labels
UILabel *titleLabel = [[UILabel alloc] init];
titleLabel.text = title;
titleLabel.font = [UIFont boldSystemFontOfSize:42.f];
titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
[titleLabel sizeToFit];
UILabel *subtitleLabel = [[UILabel alloc] init];
subtitleLabel.text = subtitle;
subtitleLabel.font = [UIFont systemFontOfSize:24.f];
subtitleLabel.lineBreakMode = NSLineBreakByWordWrapping;
[subtitleLabel sizeToFit];
// Create gradient
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = titleLabel.bounds;
NSMutableArray *cgcolors = [NSMutableArray new];
for (int i = 0; i < colors.count; i++) {
cgcolors[i] = (id)colors[i].CGColor;
}
gradient.colors = cgcolors;
gradient.locations = #[#0, #1];
UIView *gradientView = [[UIView alloc] init];
[gradientView.layer addSublayer:gradient];
gradientView.maskView = titleLabel;
// Stack
UIStackView *stackView = [[UIStackView alloc] initWithArrangedSubviews:#[gradientView, subtitleLabel]];
stackView.alignment = UIStackViewAlignmentLeading;
stackView.axis = UILayoutConstraintAxisVertical;
stackView.distribution = UIStackViewDistributionEqualCentering;
stackView.spacing = 0;
stackView.translatesAutoresizingMaskIntoConstraints = NO;
[self addSubview:stackView];
[NSLayoutConstraint activateConstraints:#[
[stackView.leadingAnchor constraintEqualToAnchor:self.leadingAnchor constant:25],
[stackView.centerYAnchor constraintEqualToAnchor:self.centerYAnchor],
[stackView.heightAnchor constraintEqualToConstant:titleLabel.frame.size.height + subtitleLabel.frame.size.height],
[gradientView.widthAnchor constraintEqualToConstant:titleLabel.frame.size.width],
[gradientView.heightAnchor constraintEqualToConstant:titleLabel.frame.size.height]
]];
}
return self;
}
The problem is that your gradientView has no intrinsic content size.
Try changing your constraints to this:
[NSLayoutConstraint activateConstraints:#[
[stackView.leadingAnchor constraintEqualToAnchor:self.leadingAnchor constant:25],
[stackView.centerYAnchor constraintEqualToAnchor:self.centerYAnchor],
// shouldn't need to set a height anchor on the stackView
//[stackView.heightAnchor constraintEqualToConstant:titleLabel.frame.size.height + subtitleLabel.frame.size.height],
[gradientView.widthAnchor constraintEqualToConstant:titleLabel.frame.size.width],
[gradientView.heightAnchor constraintEqualToConstant:titleLabel.frame.size.height],
]];

Add gradient color on every ca shapelayer

I am trying to add gradient on ca shape layer its only giving gradient effect on current view frame if i am using it by adding masklayer it is not effecting on every layer seperately
here is my code:
CAShapeLayer *gradientMask = [CAShapeLayer layer];
gradientMask.fillColor = [[UIColor clearColor] CGColor];
gradientMask.strokeColor = [[UIColor blackColor] CGColor];
gradientMask.lineWidth = _borderStrokeWidth;
gradientMask.frame = CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height);
gradientMask.path = maskLayer.path;
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
gradientLayer.locations = [NSArray arrayWithObjects:
[NSNumber numberWithFloat:0.8f],
[NSNumber numberWithFloat:1.0f],
nil];
gradientLayer.startPoint = CGPointMake(0.5,1.0);
gradientLayer.endPoint = CGPointMake(1.0,0.5);
gradientLayer.frame = CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height);
NSArray *colors = [NSArray arrayWithObjects:(id)[UIColor redColor].CGColor, (id)[UIColor greenColor].CGColor,(id)[UIColor blueColor].CGColor,(id)[UIColor yellowColor].CGColor, nil];
gradientLayer.colors = colors;
[gradientLayer setMask:gradientMask];
// [gradientLayer setMask:shapeLayer];
[self.layer addSublayer:gradientLayer];
kindly give suggestions

How to remove already created path using CGMutablePathRef?

I am plotting line according bottom selected dots.First Showing start from 0 and after that it showing according to selected dots But line chart is showing previous drawn line.
Here I am using SHLineGrapgView. Here is code :
- (void)drawPlot:(SHPlot *)plot {
NSDictionary *theme = plot.plotThemeAttributes;
//
CAShapeLayer *backgroundLayer = [CAShapeLayer layer];
backgroundLayer.frame = self.bounds;
backgroundLayer.fillColor = [UIColor clearColor].CGColor;
backgroundLayer.backgroundColor = [UIColor clearColor].CGColor;
[backgroundLayer setStrokeColor:[UIColor clearColor].CGColor];
[backgroundLayer setLineWidth:((NSNumber *)theme[kPlotStrokeWidthKey]).intValue];
CGMutablePathRef backgroundPath= CGPathCreateMutable();
//
CAShapeLayer *circleLayer = [CAShapeLayer layer];
circleLayer.frame = self.bounds;
circleLayer.fillColor = [UIColor redColor].CGColor;
circleLayer.backgroundColor = [UIColor clearColor].CGColor;
[circleLayer setStrokeColor:((UIColor *)theme[kPlotPointFillColorKey]).CGColor];
[circleLayer setLineWidth:((NSNumber *)theme[kPlotStrokeWidthKey]).intValue];
CGMutablePathRef circlePath = CGPathCreateMutable();
//
CAShapeLayer *graphLayer = [CAShapeLayer layer];
graphLayer.frame = self.bounds;
graphLayer.fillColor = [UIColor clearColor].CGColor;
graphLayer.backgroundColor = [UIColor clearColor].CGColor;
[graphLayer setStrokeColor:((UIColor *)theme[kPlotStrokeColorKey]).CGColor];
[graphLayer setLineWidth:((NSNumber *)theme[kPlotStrokeWidthKey]).intValue];
CGMutablePathRef graphPath = CGPathCreateMutable();
double yRange = [_yAxisRange doubleValue]; // this value will be in dollars
double yIntervalValue = yRange / INTERVAL_COUNT;
//logic to fill the graph path, ciricle path, background path.
NSLog(#"plottingValues Dictionary %#",plot.plottingValues);
[plot.plottingValues enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSDictionary *dic = (NSDictionary *)obj;
NSLog(#"Plotting Dictionary %#",dic);
__block NSNumber *_key = nil;
__block NSNumber *_value = nil;
[dic enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
_key = (NSNumber *)key;
_value = (NSNumber *)obj;
}];
int xIndex = [self getIndexForValue:_key forPlot:plot];
//x value
double height = self.bounds.size.height - BOTTOM_MARGIN_TO_LEAVE;
double y = height - ((height / ([_yAxisRange doubleValue] + yIntervalValue)) * [_value doubleValue]);
(plot.xPoints[xIndex]).x = ceil((plot.xPoints[xIndex]).x);
(plot.xPoints[xIndex]).y = ceil(y);
}];
//move to initial point for path and background.
CGPathMoveToPoint(graphPath, NULL, _leftMarginToLeave, plot.xPoints[0].y);
CGPathMoveToPoint(backgroundPath, NULL, _leftMarginToLeave, plot.xPoints[0].y);
int count = (int)_xAxisValues.count;
for(int i=0; i< count; i++)
{
CGPathRef path=CGPathCreateCopy(graphPath);
CGPoint point = plot.xPoints[i];
// CGContextRef ref=CGContextCopyPath(<#CGContextRef _Nullable c#>)
// CGContextClip
CGPathAddLineToPoint(graphPath, NULL, point.x, point.y);
CGPathAddLineToPoint(backgroundPath, NULL, point.x, point.y);
CGFloat dotsSize = [_themeAttributes[kDotSizeKey] floatValue];
CGPathAddEllipseInRect(circlePath, NULL, CGRectMake(point.x - dotsSize/2.0f, point.y - dotsSize/2.0f, dotsSize, dotsSize));
}
//move to initial point for path and background.
CGPathAddLineToPoint(NULL, NULL, _leftMarginToLeave + PLOT_WIDTH, plot.xPoints[count -1].y);
CGPathAddLineToPoint(backgroundPath, NULL, _leftMarginToLeave + PLOT_WIDTH, plot.xPoints[count - 1].y);
//additional points for background.
CGPathAddLineToPoint(backgroundPath, NULL, _leftMarginToLeave + PLOT_WIDTH, self.bounds.size.height - BOTTOM_MARGIN_TO_LEAVE);
CGPathAddLineToPoint(backgroundPath, NULL, _leftMarginToLeave, self.bounds.size.height - BOTTOM_MARGIN_TO_LEAVE);
CGPathCloseSubpath(backgroundPath);
backgroundLayer.path = backgroundPath;
graphLayer.path = graphPath;
circleLayer.path = circlePath;
//animation
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:#"strokeEnd"];
animation.duration = 1;
animation.fromValue = #(0.0);
animation.toValue = #(1.0);
[graphLayer addAnimation:animation forKey:#"strokeEnd"];
backgroundLayer.zPosition = 0;
graphLayer.zPosition = 1;
circleLayer.zPosition = 2;
[self.layer addSublayer:graphLayer];
[self.layer addSublayer:circleLayer];
[self.layer addSublayer:backgroundLayer];
NSUInteger count2 = _xAxisValues.count;
for(int i=0; i< count2; i++){
CGPoint point = plot.xPoints[i];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.backgroundColor = [UIColor clearColor];
btn.tag = i;
btn.frame = CGRectMake(point.x, point.y - 20, 40, 40);
[btn addTarget:self action:#selector(clicked:) forControlEvents:UIControlEventTouchUpInside];
objc_setAssociatedObject(btn, kAssociatedPlotObject, plot, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
[self addSubview:btn];
}
}

How do you set a gradient fillcolor for cashapelayer without using a mask?

How do you set a gradient fillcolor for cashapelayer?
Related question with clearer explanation:
Using Cocoa To Follow A Path With A Gradient
I need a gradient that's not a mask, but instead a gradient based on the drawing of the cashapelayer's path.
I can't use a gradient mask on top, because I'm making a route on the minimap in my game. So if the player walks over his own tracks, it should be in a different color.
I want it like this mapview's polyline:
Source: http://cdn4.raywenderlich.com/wp-content/uploads/2014/06/23_multicolor_polyline.png
I made the minimap route by:
logging all the user's different directions, then running them through a loop into bezier paths.
I appended the Bezier paths, and then put it on a cashapelayer.
Is there a way to have a multicolored in a cashapelayer?
Is there a keypath for cabasicanimation that can put a gradient?
My code is below, and some images.
[mymapview.layer.sublayers makeObjectsPerformSelector:#selector(removeFromSuperlayer)];
[[mymapview subviews]
makeObjectsPerformSelector:#selector(removeFromSuperview)];
int i = 0;
int x = 17;
int y = 272;
int m = 16;
UIBezierPath *kpath = [UIBezierPath bezierPath]; while (i < HistDirections.count)
{
if (i > 0)
{
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(x, y)];
if ([[HistDirections objectAtIndex:i] intValue] ==1)
{
[path addLineToPoint:CGPointMake(x, y-m)];
y = y - m;
}
else if ([[HistDirections objectAtIndex:i] intValue] ==2)
{
[path addLineToPoint:CGPointMake(x-m, y)];
x = x -m;
}
else if ([[HistDirections objectAtIndex:i] intValue] ==3)
{
[path addLineToPoint:CGPointMake(x+m, y)];
x = x+m;
}
else
{
[path addLineToPoint:CGPointMake(x, y+m)];
y = y - m;
}
[kpath appendPath:path];
}
i++;
}
[CATransaction begin];
[CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[CATransaction setCompletionBlock:^{
UIImageView *viewpulse = [[UIImageView alloc] initWithFrame:CGRectMake(x -5, y-5, 10.0, 10.0)];
viewpulse.image = [UIImage imageNamed:#"arro.png"];
viewpulse.backgroundColor = [UIColor clearColor];
if(direction == 1)
{
viewpulse.transform = CGAffineTransformMakeRotation(-M_PI/2);
}
else if (direction == 2)
{
viewpulse.transform = CGAffineTransformMakeRotation(M_PI);
}
else if (direction == 4)
{
viewpulse.transform = CGAffineTransformMakeRotation(M_PI/2);
}
[mymapview addSubview:viewpulse];
CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:#"transform.scale"];
scaleAnimation.duration = 0.8;
scaleAnimation.repeatCount = HUGE_VAL;
scaleAnimation.autoreverses = YES;
scaleAnimation.fromValue = [NSNumber numberWithFloat:1.6];
scaleAnimation.toValue = [NSNumber numberWithFloat:0.8];
[viewpulse.layer addAnimation:scaleAnimation forKey:#"scale"];
}];
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
kpath.lineCapStyle = kCGLineCapRound;
kpath.lineCapStyle = kCGLineJoinRound;
shapeLayer.path = [kpath CGPath];
shapeLayer.strokeColor = [[UIColor colorWithRed:51/255.0f green:(51)/255.0f blue:170/255.0f alpha:1.0f] CGColor];
shapeLayer.lineWidth = 4.0;
shapeLayer.lineCap = kCALineCapRound;
shapeLayer.fillColor = [[UIColor clearColor] CGColor];
[mymapview.layer addSublayer:shapeLayer];
CABasicAnimation *HAnimation = [CABasicAnimation animationWithKeyPath:#"strokeEnd"];
float dur = (HistDirections.count * 0.27);
if (dur > 2)
{
dur = 2;
}
HAnimation.duration = dur;
HAnimation.repeatCount = 1.0;
HAnimation.fromValue = [NSNumber numberWithFloat:0.0f];
HAnimation.toValue = [NSNumber numberWithFloat:1.0f];
/*
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
gradientLayer.frame = mymapview.frame;
gradientLayer.colors = #[(__bridge id)[UIColor blueColor].CGColor,(__bridge id)[UIColor greenColor].CGColor,(__bridge id)[UIColor yellowColor].CGColor,(__bridge id)[UIColor orangeColor].CGColor, (__bridge id)[UIColor redColor].CGColor];
gradientLayer.startPoint = CGPointMake(0,0.5);
gradientLayer.endPoint = CGPointMake(1,0.5);
[mymapview.layer addSublayer:gradientLayer];
gradientLayer.mask = shapeLayer;*/
[CATransaction commit];
Gradient mask:
Monocolor line:
Nevermind! I figured out what I can do. Since I create the layer from multiple paths, I just put the cgpaths into an array, and looped each path into a unique cashapelayer with it's own color

Why does my marque not follow my image?

When adding an image as a SubView to another UIImageView, I am adding a marque over the new image that should follow as it is being edited (moved, zoom in/out, rotate).
I can not get the marque to stay connected to the frame of the new image though. It is initially connected when the image is added but once moved the marque goes away from the image frame.
Here is my code:
**viewDidLoad:**
if (!_marque)
{
_marque = [[CAShapeLayer layer] retain];
_marque.fillColor = [[UIColor clearColor] CGColor];
_marque.strokeColor = [[UIColor cyanColor] CGColor];
_marque.lineWidth = 1.0f;
_marque.lineJoin = kCALineJoinRound;
_marque.lineDashPattern = [NSArray arrayWithObjects:[NSNumber numberWithInt:10],[NSNumber numberWithInt:5], nil];
_marque.bounds = CGRectMake(_stampedImageView.frame.origin.x, _stampedImageView.frame.origin.y, 0, 0);
_marque.position = CGPointMake(_stampedImageView.frame.origin.x + self.view.frame.origin.x, _stampedImageView.frame.origin.y + self.view.frame.origin.y);
}
[[_stampedImageView layer] addSublayer:_marque];
**marque Method:**
if (![_marque actionForKey:#"linePhase"])
{
CABasicAnimation *dashAnimation;
dashAnimation = [CABasicAnimation animationWithKeyPath:#"lineDashPhase"];
[dashAnimation setFromValue:[NSNumber numberWithFloat:0.0f]];
[dashAnimation setToValue:[NSNumber numberWithFloat:15.0f]];
[dashAnimation setDuration:0.5f];
[dashAnimation setRepeatCount:HUGE_VALF];
[_marque addAnimation:dashAnimation forKey:#"linePhase"];
}
_marque.bounds = CGRectMake(_stampedImageView.frame.origin.x, _stampedImageView.frame.origin.y, 0, 0);
_marque.position = CGPointMake(_stampedImageView.frame.origin.x, _stampedImageView.frame.origin.y);
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddRect(path, NULL, frame);
[_marque setPath:path];
CGPathRelease(path);
_marque.hidden = NO;
**panGestureRecognizer:**
CGPoint translatedPoint = [(UIPanGestureRecognizer*)sender translationInView:self.view];
if([(UIPanGestureRecognizer*)sender state] == UIGestureRecognizerStateBegan)
{
_firstX = [_stampedImageView center].x;
_firstY = [_stampedImageView center].y;
}
translatedPoint = CGPointMake(_firstX+translatedPoint.x, _firstY+translatedPoint.y);
[_stampedImageView setCenter:translatedPoint];
[self showOverlayWithFrame:_stampedImageView.frame];
Could someone help me see what I am missing please?
Thanks!
I think you may have an error in this line:
CGPathAddRect(path, NULL, frame);
You haven't defined frame anywhere that I can see. Maybe _stampedImageView.frame?