首先在iOS中,CALayer 是UIView 的內(nèi)容承載,UIView是為圖層提供了底層的事件處理,本身更像是一個CALayer的管理器。
-
UIView
@property(nonatomic) CGAffineTransform transform; // default is CGAffineTransformIdentity. animatable -
CALayer
@property CATransform3D transform; - (CGAffineTransform)affineTransform; - (void)setAffineTransform:(CGAffineTransform)m;
那么各種拉伸變換,其中最相關(guān)的幾個屬性是 Frame 、 center 、 transform
frame 是由center、bounds和transform共同計算而來,transform改變,frame會受到影響,但是center和bounds不會受到影響。
CMT (CGAffineTransform)
CoreGraphics Frameworks
默認(rèn)情況下transform為 CGAffineTransformIdentify,可以使用frame但是一旦進(jìn)行了變換,則矩陣變化 frame則相對不可信,使用 bounds+center 進(jìn)行計算。
UIView transform的原點是該View 的center,基于自己的坐標(biāo)系進(jìn)行變換。
關(guān)于 CGAffineTransform 結(jié)構(gòu)體的 矩陣變換,可在參考鏈接中查看。
UIView animation動畫block中,進(jìn)行frame前后變換,平移是相關(guān)的縮放就會存在渲染樹問題:
因為縮放會影響平移,而平移卻不會影響縮放,所以先平移到中心和目標(biāo)frame一致,然后縮放。
CGAffineTransform moveTrans = CGAffineTransformMakeTranslation(CGRectGetMidX(toRect) - CGRectGetMidX(fromRect), CGRectGetMidY(toRect) - CGRectGetMidY(fromRect));
CGAffineTransform scaleTrans = CGAffineTransformMakeScale(toRect.size.width / fromRect.size.width, toRect.size.height / fromRect.size.height);
//先平移后旋轉(zhuǎn)
CGAffineTransformConcat(scaleTrans, moveTrans);
CATransform3D
QuartzCore Frameworks 中CoreAnimation
CALayer 中frame、bounds、position和anchorPoint 相關(guān)屬性。
所有的變換支點都是以 anchorPoint 進(jìn)行的,默認(rèn)(0.5 ,0.5),改變 anchorPoint則會對 frame.original 產(chǎn)生影響;而position 屬性值其實是 CALayer 的 anchorPoint 點在其 superLayer 中的位置坐標(biāo)。
position.x = frame.origin.x + anchorPoint.x * bounds.size.width;
position.y = frame.origin.y + anchorPoint.y * bounds.size.height;
position 和 anchorPoint,單一改變,只會影響 frame 根據(jù)另一個屬性進(jìn)行變化、
frame.origin.x = position.x - anchorPoint.x * bounds.size.width;
frame.origin.y = position.y - anchorPoint.y * bounds.size.height;
frame.size.width = bounds.size.width;
frame.size.height = bounds.size.height;
CATransform3D 和 CGAffineTransform 可通過接口 CATransform3DGetAffineTransform 相互轉(zhuǎn)換.
注意點: UIkit 下坐標(biāo)系和 Quartz 坐標(biāo)系不同,這就是為什么用 UIGraphicsGetCurrentContext 的context 需要添加轉(zhuǎn)換 坐標(biāo)系
CGContextScaleCTM(ctx, 1.0, -1.0);
CALayer 下 3D變換矩陣,結(jié)構(gòu)體參數(shù)詳解:
- 待續(xù)
- m34 透視
- m44
//根據(jù)圖片的旋轉(zhuǎn)矩陣求旋轉(zhuǎn)角度
- (CGFloat)angleFromTransform:(CATransform3D)transform
{
CGFloat angle = 0.0f;
angle = atan2f(transform.m21,transform.m11);
return angle;
}
GPUImageTransformFilter
GPUImageStretchDistortionFilter
其他相關(guān)屬性
resizableImageWithCapInsets
UIEdgeInsets insets = UIEdgeInsetsMake(0, 0, 100, 0);
UIImage *tempImage = [self.currentImage resizableImageWithCapInsets:insets resizingMode:UIImageResizingModeStretch];
這個接口主要使用在UI設(shè)計的資源使用中,不需要設(shè)計師給定icon的固定大小,是一個可變的展示處理方式,和 Assets 中,資源右下角 slicing 模式下調(diào)整一樣。
UIViewContentMode 則是UIView 用來內(nèi)容填充模式的一個屬性;
參考