如何在两个不同的锚点处组合两个旋转来转换UIView

时间:2014-03-30 10:29:05

标签: ios iphone cocoa-touch rotation transformation

我想首先围绕它的左边缘旋转我的UIView,然后围绕它的右边缘旋转。第一次旋转应产生开门效果,一旦完成,第二次旋转应开始。当第二次旋转完成时,效果应该就像视图在z平面中被按下一样。转换是手动动画的一部分,当然应该是无缝的。

two consecutive rotations around two different points

凭直觉我猜不可能使用锚点并连接在不同锚点发生的2次旋转(但如果我错了请纠正我)。因此,我没有使用锚点,而是使用矩阵组合来产生“旋转”的效果。

第一次旋转非常简单,但我不知道如何追加第二次旋转。也许在应用第二次旋转之前,我应该通过在y-coord上向右平移并在z-coord中向下移动(使用类似cos(90°角)* view.width)来到达右边缘的位置。第一次轮换结束。然而,我做的尝试并没有成功。任何的想法? 这是我到目前为止第一次轮换的内容:

-(void) transform:(float) percentage{

    CATransform3D transform = CATransform3DIdentity;

    //here I get the angle for the 1st rotation (percentage 0 -> angle 0; percentage 0.5 -> angle 45°
    float angle = [self getFirstRotationAngle: percentage];
    CATransform3D translateToRotateAt = CATransform3DMakeTranslation(myView.frame.size.width / 2.0, 0.0, 0.0);
    CATransform3D rotation1 = CATransform3DIdentity;
    rotation1.m34 = 1.0 / -500;
    rotation1 = CATransform3DRotate(rotation1, angle, 0.0f, 1.0f, 0.0f);
    CATransform3D translateBackToRotateAt = CATransform3DMakeTranslation(-myView.frame.size.width / 2.0, 0.0, 0.0f);

    transform = CATransform3DConcat(translateToRotateAt, rotation1);
    transform = CATransform3DConcat(transform , translateBackToRotateAt);

    if (percentage > 0.5){
        angle = [self getSecondRotationAngle: percentage];

        // here I should get the second part of the transformation and concatenate it to the first part
    }

    myView.layer.transform = transform;
}

1 个答案:

答案 0 :(得分:0)

这个方法可以为你做一个转换,你的学位赋予它

func makeTransform(horizontalDegree: CGFloat, verticalDegree: CGFloat, maxVertical: CGFloat,rotateDegree: CGFloat, maxHorizontal: CGFloat) -> CATransform3D {
    var transform = CATransform3DIdentity
           
    transform.m34 = 1 / -500
    
    let xAnchor = (horizontalDegree / (2 * maxHorizontal)) + 0.5
    let yAnchor = (verticalDegree / (-2 * maxVertical)) + 0.5
    let anchor = CGPoint(x: xAnchor, y: yAnchor)
    
    setAnchorPoint(anchorPoint: anchor, forView: self.imgView)
    let hDegree  = (CGFloat(horizontalDegree) * .pi)  / 180
    let vDegree  = (CGFloat(verticalDegree) * .pi)  / 180
    let rDegree  = (CGFloat(rotateDegree) * .pi)  / 180
    transform = CATransform3DRotate(transform, vDegree , 1, 0, 0)
    transform = CATransform3DRotate(transform, hDegree , 0, 1, 0)
    transform = CATransform3DRotate(transform, rDegree , 0, 0, 1)
    
    return transform
}

func setAnchorPoint(anchorPoint: CGPoint, forView view: UIView) {
    var newPoint = CGPoint(x: view.bounds.size.width * anchorPoint.x, y: view.bounds.size.height * anchorPoint.y)
    var oldPoint = CGPoint(x: view.bounds.size.width * view.layer.anchorPoint.x, y: view.bounds.size.height * view.layer.anchorPoint.y)
    
    newPoint = newPoint.applying(view.transform)
    oldPoint = oldPoint.applying(view.transform)
    
    var position = view.layer.position
    position.x -= oldPoint.x
    position.x += newPoint.x
    
    position.y -= oldPoint.y
    position.y += newPoint.y
    
    print("Anchor: \(anchorPoint)")
    
    view.layer.position = position
    view.layer.anchorPoint = anchorPoint
}