2013-05-08 52 views
14

嘗試動畫蒙上UIView的橢圓,將比例變換保留在中心位置。CABasicAnimation - 變換比例保持居中

我發現CALayer - CABasicAnimation not scaling around center/anchorPoint,和隨後加入一bounds屬性到maskLayerCAShapeLayer然而,這與掩模定位在左上角只有它的1/4表示結束。我希望面具保持在屏幕的中心。

@synthesize maskedView; 
- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    UIViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:@"Next"]; 

    vc.view.frame = CGRectMake(0,0, self.view.frame.size.width, self.view.frame.size.height); 
vc.view.layer.bounds = self.view.layer.bounds; 

    CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init]; 

    CGRect maskRect = CGRectMake((self.view.frame.size.width/2)-50, (self.view.frame.size.height/2)-50, 100, 100); 
    CGMutablePathRef path = CGPathCreateMutable(); 
    CGPathAddEllipseInRect(path, nil, maskRect); 
    [maskLayer setPath:path]; 

    CGPathRelease(path); 

    vc.view.layer.mask = maskLayer; 
    [self.view addSubview:vc.view]; 

    maskedView = vc.view; 
    [self startAnimation]; 
} 

動畫...

-(void)startAnimation 
{ 
    maskedView.layer.mask.bounds = CGRectMake((self.view.frame.size.width/2)-50, (self.view.frame.size.height/2)-50, 100, 100); 
    maskedView.layer.mask.anchorPoint = CGPointMake(.5,.5); 
    maskedView.layer.mask.contentsGravity = @"center"; 

    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; 

    animation.duration = 1.0f; 
    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 
    animation.fromValue = [NSNumber numberWithFloat:1.0f]; 
    animation.toValue = [NSNumber numberWithFloat:5.0f]; 

    [maskedView.layer.mask addAnimation:animation forKey:@"animateMask"]; 
} 

更新

我似乎與在position鍵一秒鐘的動畫有固定的這個。這是正確的還是有更好的方法來做到這一點?

CABasicAnimation *animation2 = [CABasicAnimation animationWithKeyPath:@"position"]; 

animation2.duration = 1.0f; 

animation2.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 

animation2.fromValue = [NSValue valueWithCGPoint:CGPointMake((self.view.frame.size.width/2), (self.view.frame.size.height/2))]; 
animation2.toValue = [NSValue valueWithCGPoint:CGPointMake((self.view.frame.size.width/2), (self.view.frame.size.height/2))]; 

[toBeMask.layer.mask addAnimation:animation2 forKey:@"animateMask2"]; 

回答

6

我似乎已經用位置鍵上的第二個動畫來解決這個問題。這是正確的還是有更好的方法來做到這一點?

CABasicAnimation *animation2 = [CABasicAnimation animationWithKeyPath:@"position"]; 

animation2.duration = 1.0f; 

animation2.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 

animation2.fromValue = [NSValue valueWithCGPoint:CGPointMake((self.view.frame.size.width/2), (self.view.frame.size.height/2))]; 
animation2.toValue = [NSValue valueWithCGPoint:CGPointMake((self.view.frame.size.width/2), (self.view.frame.size.height/2))]; 

[toBeMask.layer.mask addAnimation:animation2 forKey:@"animateMask2"]; 
12

可以圍繞對象,而不是中心創建一個規模(0,0)是這樣的:

CABasicAnimation *scale = [CABasicAnimation animationWithKeyPath:@"transform"]; 
CATransform3D tr = CATransform3DIdentity; 
tr = CATransform3DTranslate(tr, self.bounds.size.width/2, self.bounds.size.height/2, 0); 
tr = CATransform3DScale(tr, 3, 3, 1); 
tr = CATransform3DTranslate(tr, -self.bounds.size.width/2, -self.bounds.size.height/2, 0); 
scale.toValue = [NSValue valueWithCATransform3D:tr]; 

所以我們用「身份」開始了變換(意思是「無轉變')。然後我們翻譯(移動)到對象的中心。然後我們縮放。然後我們回到原點,所以我們回到了我們開始的地方(我們只想影響比例操作)。

+0

縮放比例是否會影響您在之後做的翻譯?我正在測試這個(以及正常的仿射變換),並且視圖始終在左上方離開它的初始位置。 – Ixx 2016-07-02 16:47:58

+0

這個在我的案例中工作 'CABasicAnimation * scale = [CABasicAnimation animationWithKeyPath:@「transform」]; CATransform3D tr = CATransform3DIdentity; tr = CATransform3DScale(tr,3,3,1); scale.toValue = [NSValue valueWithCATransform3D:tr];' – 2017-03-28 06:58:22

4

我不知道爲什麼,但CAShapeLayer不會將邊界屬性設置爲圖層。就我而言,這就是問題所在。 嘗試設置邊界。這應該工作。

我做了這樣的事情建立初始圈

self.circle = [CAShapeLayer layer]; 
CGRect roundedRect = CGRectMake(0, 0, width, width); 
self.circle.bounds = roundedRect; 
UIBezierPath *start = [UIBezierPath bezierPathWithRoundedRect:roundedRect cornerRadius:width/2]; 
[self.circle setPath:start.CGPath]; 
self.circle.position = CGPointMake(whatever suits you); 
self.circleView.layer.mask = self.circle; 
[self.circleView.layer.mask setValue: @(1) forKeyPath: @"transform.scale"]; 

而像這樣的縮放來

CABasicAnimation *scale = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; 
scale.fromValue = [self.circleView.layer.mask valueForKeyPath:@"transform.scale"]; 
scale.toValue = @(100); 
scale.duration = 1.0; 
scale.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 
[self.circleView.layer.mask setValue:scale.toValue forKeyPath:scale.keyPath]; 
[self.circleView.layer.mask addAnimation:scale forKey:scale.keyPath]; 

PD:AnchorPoint默認情況下(0.5 ,. 5)根據蘋果的文件...但我們都知道這並不意味着什麼是正確的?

希望它有幫助!

3

我已經寫了以下功能與許多添加的調整和選項,可能對許多其他人有用。

func layerScaleAnimation(layer: CALayer, duration: CFTimeInterval, fromValue: CGFloat, toValue: CGFloat) { 
    let timing = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn) 
    let scaleAnimation: CABasicAnimation = CABasicAnimation(keyPath: "transform.scale") 

    CATransaction.begin() 
    CATransaction.setAnimationTimingFunction(timing) 
    scaleAnimation.duration = duration 
    scaleAnimation.fromValue = fromValue 
    scaleAnimation.toValue = toValue 
    layer.add(scaleAnimation, forKey: "scale") 
    CATransaction.commit() 
} 

注:不要忘了更新動畫完成後的大小,因爲CATransaction恢復到實際大小。

+0

scrubber? ,。。/ ,. – 2017-09-10 06:13:07

+0

猜測洗滌器應該是層? anywas。幫助我很好。謝謝>) – 2017-09-10 06:15:12

+1

@DavidSeek是它的圖層不是scrubber,我已經更新了我的答案,謝謝。 – Aamir 2017-09-10 06:36:51