UIView有CGAffineTransform類型的屬性transform,它是定義在二維空間上完成View的平移,旋轉,縮放等效果的實現。
初始化: CGAffineTransform ?transform = CGAffineTransformIdentity;
CGAffineTransformIdentity是系統提供的一個常量,/* The identity transform: [ 1 0 0 1 0 0 ]. */(和原圖一樣的transform);
?CGAffineTransform transform? = CGAffineTransformMake(CGFloat a,CGFloat b,
CGFloat c,CGFloa td,CGFloat tx,CGFloat ty)
我們來解釋下這里面參數的作用和變換的效果;
下面是原始的(默認的)transform
人后我們再來看它的計算公式:3 X 3矩陣合成得到(x`,y`,1)
矩陣算法公式:
相信大家有所了解,我是懂了點點(數學是歷史老師教的),看不到直觀的東西。
接下來我們我們新建工程,在widow上建立兩個同樣大小位置相同的View,第一個為沙色,第二個是淺海藍色,我修改第二個View的transform中a的值為0.2:CGAffineTransformMake(0.2,0,0,1,0,0);
圖一是沒有改變的原圖,圖二是改變之后的View,很明顯的差異
我用3秒動畫完成變換,發現它是兩邊開始往中間縮小,打印View的frame原來的{{100,100},{100,100}}變成了{{140,100},{20,100}}。我們來計算下是不是根據公式計算的。
根據變換的transform我們知道 a = 0.2 , b = 0 , c = 0 , d = 1 , t.x = 0 , t.y = 0;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?x = 100 , ?y = 100
x` = ax + cy + t.x = 0.2 * 100 + 0 * 100 + 0 = 20
y` = bx + dy + t.y = 0 * 100 + 1 * 100 + 0 = 100
結合上面的圖和下面的計算,瞬間明白了這是x按照a值進行了比例縮放,y按照d的值進行比列縮放,最重要的是縮放的過程中View的point(中心點)是不會改變的。
接著對b,c,t.x ,ty,進行深度研究發現:
x會跟著c的值進行拉伸(View的寬度是跟著改變),y會跟著b的值進行拉伸(View的高度跟著改變),要注意到的是c和b的值改變不會影響到View的point(center中心點)的改變。這是個很有意思的兩個參數。
x會跟著t.x進行x做表平移,y會跟著t.y進行平移。這里的point(center)是跟著變換的。
下面是Apple整合的transform
平移 :
①根據本身的transform進行平移 ? CGAffineTransformMakeTranslation(CGFloat tx,CGFloat ty)
②根據本身的transform后者另外的transform進行平移CGAffineTransformTranslate(CGAffineTransform t,CGFloat tx,CGFloat ty)
縮放 :
①根據本身的transform進行縮放?
CGAffineTransformMakeScale(CGFloat sx,CGFloat sy)
②根據本身的transform后者另外的transform進行縮放
?CGAffineTransformScale(CGAffineTransform t,CGFloat sx,CGFloat sy)
旋轉 :
① 根據本身的transform進行旋轉
?CGAffineTransformMakeRotation(CGFloat angle) (angle 旋轉的角度)
②根據本身的transform后者另外的transform進行旋轉
CGAffineTransformRotate(CGAffineTransform t,CGFloat angle)
恢復?:反向旋轉
CGAffineTransformInvert(CGAffineTransform t) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
合并:
CGAffineTransformConcat(CGAffineTransform t1,CGAffineTransform t2) ? ? ??
兩個transform合并起來
傾斜:
這個使我們自己定義
-(CGAffineTransform) CGAffineTransformMakeShear(CGFloat x,CGFloat y)
{ ? CGAffineTransform transform = CGAffineTransformIdentity;
transform.c= -x;
transform.b= y;
returntransform; ??}
layer.affineTransform = CGAffineTransformMakeShear(1,0);
評測:
①Bool CGAffineTransformIsIdentity(CGAffineTransform t) ? ? ? ? ? ? ? ? ??
?查看是不是默認的transform
②bool CGAffineTransformEqualToTransform(CGAffineTransform t1,CGAffineTransform t2) ?
?比較兩個transform是否相等
仿射矩陣應用:
①CGPointApplyAffineTransform(CGPoint point,CGAffineTransform t)? 得到新的中心CGPoint
②CGSizeApplyAffineTransform(CGSize size,CGAffineTransform t) ? ? ? ? ?得到新的size CGSize
③CGRectApplyAffineTransform(CGRect rect,CGAffineTransform t) ? ? ? ?得到新的rect CGRect
放射矩陣一個常用的情形就是根據用戶的手勢來相應的改變視圖的變換
UIPanGestureRecognizer ? ? ? ? ? ? ? ? ? 位移
UIPinchGestureRecognizer ? ? ? ? ? ? ? ?縮放
UIRotationGestureRecognizer ? ? ? ? ?旋轉
蘋果官方的建議,要多次使用transform,最好是初始化一個CGAffineTransform,進行多次操作。
Note that you do not typically need to create affine transforms directly. If you want only to draw an object that is scaled or rotated, for example, it is not necessary to construct an affine transform to do so. The most direct way to manipulate your drawing—whether by movement, scaling, or rotation—is to call the functionsCGContextTranslateCTM,CGContextScaleCTM, orCGContextRotateCTM, respectively. You should generally only create an affine transform if you want to reuse it later.(原諒我英語不夠好。)
Good lucky , every one!五一快樂!