Bojan
Bojan

Reputation: 147

UIView mask transparent.

I use CAShapeLayer to create filled circle (image #1).

Now I would like to mask that circle with another smaller circle, so it looks like image #2.

Later I will animate filling (image #3) the circle by reducing scale of the mask.

How can I achieve this?

enter image description here enter image description here enter image description here

Upvotes: 2

Views: 544

Answers (1)

Gavin Hope
Gavin Hope

Reputation: 2193

I'm not sure how correct the following approach is; it might be better to work with the CALayers directly...

However, if the views/layers you're working with are quite simple, the following code might be good enough for what you need.

It's based around using a subview for the inner/smaller circle - and then animating the transform property on UIView.

Just in case it's useful, here's a link to Apple's doc on Animating Views.

Here's the code:

@implementation ViewController
{
    UIView* _innerCircleView;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    UIView* outerCircleView = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 200, 200)];

    UIBezierPath* bigCircle = [UIBezierPath bezierPathWithArcCenter:CGPointMake(100, 100) radius:100 startAngle:0 endAngle:(M_PI * 2) clockwise:YES];
    [bigCircle closePath];
    CAShapeLayer* bigCircleLayer = [CAShapeLayer new];
    [bigCircleLayer setPath:bigCircle.CGPath];
    bigCircleLayer.fillColor = [UIColor blackColor].CGColor;
    [outerCircleView.layer addSublayer:bigCircleLayer];

    _innerCircleView = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 100, 100)];
    UIBezierPath* smallerCircle = [UIBezierPath bezierPathWithArcCenter:CGPointMake(50, 50) radius:50 startAngle:0 endAngle:(M_PI * 2) clockwise:YES];
    [smallerCircle closePath];
    CAShapeLayer* smallCircleLayer = [CAShapeLayer new];
    [smallCircleLayer setPath:smallerCircle.CGPath];
    smallCircleLayer.fillColor = [UIColor whiteColor].CGColor;
    [_innerCircleView.layer addSublayer:smallCircleLayer];

    [outerCircleView addSubview:_innerCircleView];
    [self.view addSubview:outerCircleView];

    UIButton* animateButton = [[UIButton alloc] initWithFrame:CGRectMake(100, 300, 100, 50)];
    animateButton.backgroundColor = [UIColor blueColor];
    [animateButton setTitle:@"Animate" forState:UIControlStateNormal];
    [animateButton addTarget:self action:@selector(animateTap:) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:animateButton];
}

- (void)animateTap:(id)s
{
    [UIView animateWithDuration:3.0f animations:^(){
        _innerCircleView.transform = CGAffineTransformScale(_innerCircleView.transform, 0.5, 0.5);
    }];
}

And a quick before and after from the simulator:

enter image description here

Upvotes: 3

Related Questions