假设我们有一个二维空间(为了简化情况),以及层S和层C,其中C是S的子层。转换过程必须影响C的边界、位置、变换、S的子层的变换和C的锚点。我的猜测如下:
CGAffineTransform transformToChild(CALayer *S, CALayer *C) {
CGFloat txa = - C.bounds.origin.x - C.bounds.size.width * C.anchorPoint.x;
CGFloat tya = - C.bounds.origin.y - C.bounds.size.height * C.anchorPoint.y;
CGFloat txb = C.position.x;
CGFloat tyb = C.position.y;
CGAffineTransform sublayerTransform = CATransform3DGetAffineTransform(S.sublayerTransform);
CGAffineTransform fromS = CGAffineTransformTranslate(sublayerTransform, txb, tyb);
fromS = CGAffineTransformConcat(fromS, C.affineTransform);
fromS = CGAffineTransformTranslate(fromS, txa, tya);
return fromS;
}
但是当子图层的变换不是单位矩阵时(例如,在旋转到M_PI_2角度的情况下),这种方法就无法起作用。
完整的代码和图层如下:
CALayer *l1 = [CALayer new];
l1.frame = CGRectMake(-40, -40, 80, 80);
l1.bounds = CGRectMake(40, 40, 80, 80);
CALayer *l2 = [CALayer new];
l2.frame = CGRectMake(50, 40, 20, 20);
l2.bounds = CGRectMake(40, 40, 20, 20);
CGAffineTransform t2 = CGAffineTransformMakeRotation(M_PI / 2);
l2.affineTransform = t2;
[l1 addSublayer:l2];
CGAffineTransform toL2 = transformToChild(l1, l2);
CGPoint p = CGPointApplyAffineTransform(CGPointMake(70, 50), toL2);
NSLog(@"Custom Point %@", [NSValue valueWithCGPoint:p]);
p = [l1 convertPoint:CGPointMake(70, 50) toLayer:l2];
NSLog(@"CoreAnimation Point %@", [NSValue valueWithCGPoint:p]);
与系统结果的比较:
Custom Point NSPoint: {-50, 80}
CoreAnimation Point NSPoint: {50, 40}