English 中文(简体)
CAL mask子改变面罩
原标题:Animating a CALayer s mask size change

页: 1 CALayer。 面罩使用一种独特的形状,有三只环绕角,其余角落则断裂。

当我使用标准动画片复制我的<条码>时,<条码> itself < < < < / 代码 仅重重重。 然而,面罩立即使用,导致出现一些引人的问题。

我曾尝试用<条码>CABasicAnimation对面罩进行消毒,但 t有 any灭.。

我怎么能对面罩产生一刀切的消毒作用? 我是否需要删除面罩,或者我必须改变一下我目前如何掌握面罩(使用<代码>-(避免)draw InContext:CGContextRef)ctx。

Cheers, Alex

最佳回答

我找到了解决这一问题的办法。 其他答复部分正确,有帮助。

以下几点对于理解解决办法很重要:

  • The mask property is not animatable itself.
  • Since the mask is a CALayer it can be animated on its own.
  • Frame is not animatable, use bounds and position. This may not apply to you(if you weren t trying to animate the frame), but was an issue for me. (See Apple QA 1620)
  • A view layer s mask is not tied to UIView so it will not receive the core animation transaction that is applied to the view s layer.
  • We are modifying the CALayer directly, so we can t expect that UIView will have any idea of what we are trying to do, so the UIView animation won t create the core animation transaction to include changes to our properties.

为了解决该问题,我们将不得不利用核心估算本身,并可能依靠国际调查组为我们工作。

简言之,在您使用<代码>的同一期限内,建立。 WithDuration:...]. 这将造成一种单独的估计,但如果你的任期和缓解职能相同,则应当与你的估算组中的其他估算完全一致。

NSTimeInterval duration = 0.5;// match this to the value of the UIView animateWithDuration: call

[CATransaction begin];
[CATransaction setValue:[NSNumber numberWithFloat:duration] forKey:kCATransactionAnimationDuration];

self.myView.layer.mask.position = CGPointMake(newX, 0);
self.myView.layer.mask.bounds = CGRectMake(0, 0, newWidth, newHeight);

[CATransaction commit];
问题回答

我使用<条码>CAShape Layer,以掩盖<条码>查询,将<条码>本身.layer.mask设定至该层。

只要观点的大小发生变化,我就把“-setBounds:改为“如果在消化过程中对面罩进行了改变,则把面罩放在一起。

这里我是如何落实的:

- (void)setBounds:(CGRect)bounds
{
    [super setBounds:bounds];
    CAPropertyAnimation *boundsAnimation = (CABasicAnimation *)[self.layer animationForKey:@"bounds"];

    // update the mask
    self.maskLayer.frame = self.layer.bounds;

    // if the bounds change happens within an animation, also animate the mask path
    if (!boundsAnimation) {
        self.maskLayer.path = [self createMaskPath];
    } else {
        // copying the original animation allows us to keep all animation settings
        CABasicAnimation *animation = [boundsAnimation copy];
        animation.keyPath = @"path";

        CGPathRef newPath = [self createMaskPath];
        animation.fromValue = (id)self.maskLayer.path;
        animation.toValue = (__bridge id)newPath;

        self.maskLayer.path = newPath;

        [self.maskLayer addAnimation:animation forKey:@"path"];
    }
}

(例如<代码>本身.mask Layer被定为`自称'.layer.mask)

我的<代码>-createMaskPath计算了我用来掩盖这一看法的CGPathRef。 我也更新了<代码>-layout Subviews上的面罩。

CAL家的面罩不是令人难以想象的,这说明你在这方面没有uck。

mask弄你的面罩是否取决于面罩的面面/带? (你提供了一些法典?) 面罩有需求 Display 2. 变更财产?

Cheers, Corin

1. 结对:与Kekodas的回答相似,但更为笼统的是:

@implementation UIMaskView

- (void) layoutSubviews {
    [super layoutSubviews];

    CAAnimation* animation = [self.layer animationForKey:@"bounds"];
    if (animation) {
        [CATransaction begin];
        [CATransaction setAnimationDuration:animation.duration];
    }

    self.layer.mask.bounds = self.layer.bounds;
    if (animation) {
        [CATransaction commit];
    }
}

@end

遮掩的直径等于是牙齿,但你可以把被 set为面罩的层同起来。

如果你把化学文摘社保理商的开拓性财产归结起来,那就应当洗刷面罩。 我可以核实,这项工作来自我自己的项目。 但是,不肯定使用非校长的面罩。 您是否试图对面罩的内容进行估算?

Thanks, Jon

我找不到任何方案解决办法,因此,我只是用正确的定型和字母的数值来绘制一张小幅形象,而是使用。 因此,我不需要用面罩......

有可能改变面罩。

我更喜欢把Cashape Layer用作面罩。 在财产道路帮助下改变面罩非常方便。

在进行任何改变之前,将来文方的内容提上CGImageRef的事例,并创建一个新的估算层。 im酸时使用原层,并在im灭时显示。

The following is a sample code for creating key animation on property path. If you want to create your own path animation, make sure that there are always same number of points in the paths.

- (CALayer*)_mosaicMergeLayer:(CGRect)bounds content:(CGImageRef)content isUp:(BOOL)isUp {

    CALayer* layer = [CALayer layer];
    layer.frame = bounds;
    layer.backgroundColor = [[UIColor clearColor] CGColor];
    layer.contents = (id)content;

    CAShapeLayer* maskLayer = [CAShapeLayer layer];
    maskLayer.fillColor = [[UIColor blackColor] CGColor];
    maskLayer.frame = bounds;
    maskLayer.fillRule = kCAFillRuleEvenOdd;
    maskLayer.path = ( isUp ? [self _maskArrowUp:-bounds.size.height*2] : [self _maskArrowDown:bounds.size.height*2] );
    layer.mask = maskLayer;

    CAKeyframeAnimation* ani = [CAKeyframeAnimation animationWithKeyPath:@"path"];
    ani.removedOnCompletion = YES;
    ani.duration = 0.3f;
    ani.fillMode = kCAFillModeForwards;
    ani.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];

    NSArray* values = ( isUp ?
        [NSArray arrayWithObjects:
        (id)[self _maskArrowUp:0],
        (id)[self _maskArrowUp:-ceilf(bounds.size.height*1.2)],
        nil] 
    :       
        [NSArray arrayWithObjects:
        (id)[self _maskArrowDown:0],
        (id)[self _maskArrowDown:bounds.size.height],
        nil] 
    );
    ani.values = values;
    ani.delegate = self;
    [maskLayer addAnimation:ani forKey:nil];

    return layer;
}

- (void)_startMosaicMergeAni:(BOOL)up {

    CALayer* overlayer = self.aniLayer;
    CGRect bounds = overlayer.bounds;
    self.firstHalfAni = NO;

    CALayer* frontLayer = nil;
    frontLayer = [self _mosaicMergeLayer:bounds 
                                content:self.toViewSnapshot 
                                isUp:up];
    overlayer.contents = (id)self.fromViewSnapshot;
    [overlayer addSublayer:frontLayer];
}

迅速执行@stigi的答复,我的面罩层被打成形体。

override var bounds: CGRect {
    didSet {
        // debugPrint(self.layer.animationKeys()) //Very useful for know if animation is happening and key name
        let propertyAnimation = self.layer.animation(forKey: "bounds.size")

        self.shapeLayer?.frame = self.layer.bounds

        // if the bounds change happens within an animation, also animate the mask path
        if let boundAnimation = propertyAnimation as? CABasicAnimation {
            // copying the original animation allows us to keep all animation settings
            if let basicAnimation = boundAnimation.copy() as? CABasicAnimation {
                basicAnimation.keyPath = "path"

                let newPath = UIBezierPathUtils.customShapePath(rect: self.layer.bounds, cornersTriangleSize: cornerTriangleSize).cgPath
                basicAnimation.fromValue = self.shapeLayer?.path
                basicAnimation.toValue = newPath

                self.shapeLayer?.path = newPath
                self.shapeLayer?.add(basicAnimation, forKey: "path")
            }
        } else {
            self.shapeLayer?.path = UIBezierPathUtils.customShapePath(rect: self.layer.bounds, cornersTriangleSize: cornerTriangleSize).cgPath
        }
    }
}




相关问题
Code sign Error

I have created a new iPhone application.I have two mach machines. I have created the certificate for running application in iPhone in one mac. Can I use the other mac for running the application in ...

ABPersonViewController Usage for displaying contact

Created a View based Project and added a contact to the AddressBook using ABAddressBookRef,ABRecordRef now i wanted to display the added contact ABPersonViewController is the method but how to use in ...

将音频Clips从Peter改为服务器

我不禁要问,那里是否有任何实例表明从Peit向服务器发送音响。 I m不关心电话或SIP风格的解决办法,只是一个简单的袖珍流程......

• 如何将搜查线重新定位?

我正试图把图像放在搜索条左边。 但是,问题始于这里,搜索条线不能重新布署。

热门标签