Animate progress with filling the color of the border width of a UIImageView layer

寵の児 提交于 2019-12-06 10:09:03

问题


I have am UIImageView and I have made it to be circle with a width layer like in this image :

User can update the image and upload new one, I have a progress call back while image is uploaded. What I want is to animate the border with color while the image is uploaded, for example when user click upload the border start from top with green color and fill the width according to the progress.

I tried with this code:

        CAShapeLayer *circle = [CAShapeLayer layer];
        circle.path = [UIBezierPath bezierPathWithArcCenter:CGPointZero radius:27 startAngle:-M_PI_2 endAngle:2 * M_PI - M_PI_2 clockwise:YES].CGPath;
        circle.fillColor = [UIColor clearColor].CGColor;
        circle.strokeColor = [UIColor greenColor].CGColor;
        circle.lineWidth = 4;

        CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
        animation.duration = 10;
        animation.removedOnCompletion = NO;
        animation.fromValue = @(0);
        animation.toValue = @(1);
        animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
        [circle addAnimation:animation forKey:@"drawCircleAnimation"];

        [imageView.layer.sublayers makeObjectsPerformSelector:@selector(removeFromSuperlayer)];
        [imageView.layer addSublayer:circle];

But It shows the circle in wrong position and this aproch does not take a progress, it's static is there any way to fill the border width of the layer of UIImageView according to progress ?


回答1:


UIImageView is meant to show the images. I would not suggest changing it's behaviour. Even though you subclass the UIImageView and try to draw something in it, the drawRect of it will not get called. Let the imageView be imageView and use UIView for the rest I suggest you to subclass the UIView and then draw a bezier path in it and animate the bezier path curve, You can later add the imageview to the uiview .

UIView subclass:

- (void)drawRect:(CGRect)rect {
    [self drawImageHolderViewFrame:rect startAngle:_startAngle];
}

- (void)drawImageHolderViewFrame: (CGRect)frame startAngle: (CGFloat)startAngle
{
    CGRect ovalRect = CGRectMake(CGRectGetMinX(frame) , CGRectGetMinY(frame) , frame.size.width-10, frame.size.height-10);
    UIBezierPath* ovalPath = [UIBezierPath bezierPath];
    [ovalPath addArcWithCenter: CGPointMake(CGRectGetMidX(ovalRect), CGRectGetMidY(ovalRect)) radius: CGRectGetWidth(ovalRect) / 2 startAngle: -91 * M_PI/180 endAngle: -startAngle * M_PI/180 clockwise: YES];
    [UIColor.redColor setStroke];
    ovalPath.lineWidth = 2;
    [ovalPath stroke];
}

viewController class:

-(void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];
    _imageHolderView=[[MyView alloc]initWithFrame:CGRectMake(20, 20, 100, 100)];
    _imageHolderView.startAngle=90;
    _imageHolderView.backgroundColor=[UIColor clearColor];
    [self.view addSubview: _imageHolderView];
    [self startTImer];
}

-(void)startTImer{
    NSTimer *timer=[NSTimer scheduledTimerWithTimeInterval:0.02 target:self selector:@selector(animateBorder) userInfo:nil repeats:YES];
}

-(void)animateBorder{
    if (_startAngle<=-270) {
        _startAngle=90;
    }
    _startAngle--;
    _imageHolderView.startAngle=_startAngle;
    [_imageHolderView setNeedsDisplay];
}

This would give you:

Now you can add the imageview as a subview to the view you just created.




回答2:


Please try the code below:

CAShapeLayer *circle = [CAShapeLayer layer];
circle.path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(29, 29) radius:27 startAngle:-M_PI_2 endAngle:2 * M_PI - M_PI_2 clockwise:YES].CGPath;    
circle.fillColor = [UIColor clearColor].CGColor;   
circle.strokeColor = [UIColor greenColor].CGColor;   
circle.lineWidth = 4;


CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];     
animation.duration = 10;   
animation.removedOnCompletion = NO;    
animation.fromValue = @(0);    
animation.toValue = @(1);    
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];    
[circle addAnimation:animation forKey:@"drawCircleAnimation"];    



[imageCircle.layer.sublayers makeObjectsPerformSelector:@selector(removeFromSuperlayer)];    
[imageCircle.layer addSublayer:circle];    


来源:https://stackoverflow.com/questions/38011510/animate-progress-with-filling-the-color-of-the-border-width-of-a-uiimageview-lay

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!