如何拖动旋转和缩放的CALayer?

时间:2017-08-27 18:05:43

标签: objective-c rotation scale calayer drag

我在CALayer中有一个图像(使用CALayers内容属性)。 CALayer具有可用于缩放和旋转的变换属性。当CALayer静止时,我可以毫无困难地使用该变换。

但是当我尝试拖动CALayer(使用mouseDragged:(NSEvent *)theEvent)时,它们全都崩溃了(当我拖动时图像变平)。

-(void)mouseDragged:(NSEvent *)theEvent {
    CGPoint loc = [self convertPoint:theEvent.locationInWindow fromView:nil];
    CGPoint deltaLoc = ccpSub(loc, downLoc); // subtract two points
    CGPoint newPos = ccpAdd(startPos, deltaLoc); // adds two points
    [layer changePosition:newPos];
    ...
}

在图层中

-(void)changePosition:(CGPoint)newPos {
    //prevent unintended animation actions
    self.actions = @{@"position": [NSNull null]};

    CGSize size = self.frame.size;
    CGRect newRect = CGRectMake(newPos.x, newPos.y, size.width, size.height);
    self.frame = newRect;
}

问题在于我使用CALayer的框架在我拖动时动态地改变CALayer的位置,但是当旋转角度不为零时,框架不再平行于x和y轴。解决这个问题的最佳方法是什么?

1 个答案:

答案 0 :(得分:0)

一种方法是为每次增量运动重新生成变换。

-(void)mouseDragged:(CGPoint)deltaLoc start:(CGPoint)startPos {
    CGPoint newPos = ccpAdd(startPos, deltaLoc);
    [self changePosition:newPos];
}

-(void)changePosition:(CGPoint)newPos {
    //prevent unintended animation actions
    self.actions = @{@"position": [NSNull null]};

    double angle = [[self valueForKeyPath: @"transform.rotation"] doubleValue];
    double scaleX = [[self valueForKeyPath: @"transform.scale.x"] doubleValue];
    double scaleY = [[self valueForKeyPath: @"transform.scale.y"] doubleValue];

    self.transform = CATransform3DIdentity;

    CGSize size = self.frame.size;
    CGRect newRect = CGRectMake(newPos.x, newPos.y, size.width, size.height);
    self.frame = newRect;

    [self applyTransformRotation:angle scale:ccp(scaleX, scaleY)];
}

-(void)applyTransformRotation:(double)angle scale:(CGPoint)scale {
    self.transform = CATransform3DMakeRotation(angle, 0, 0, 1);
    self.transform = CATransform3DScale(self.transform, scale.x, scale.y, 1);
}

我不知道这是否是最有效的方法,但它绝对有效。