? ? ? ?最近工作中遇到一個首頁要實現翻頁動畫的需求,上網搜索未找到自己滿意的方案,索性自己寫了一份,主要利用了CoreGraphics框架進行的圖片處理,在這里與大家分享實現思路,若大家有更好的方法可以與我交流交流。
? ? ? ? 首頁按日期加載多日的資訊,每次上滑或者下滑顯示另一天資訊時,需要用到翻頁動畫。下面是實現效果。
這里采用CATransform3D來實現,思路如下:
1,向后臺請求資訊數據。
2,渲染每日的UIView。并在圖片加載完成之后對其進行截圖,得到以中線分割的兩個UIImage對象。
? ? ?在YYKit的網絡圖片處理庫中,圖片加載完成會在block得到。可用臨時數組標示當日View是否加載完成,完成后替換切割圖片,替換對應的展示圖片。
同時開啟定時器,定時截圖,避免網絡不好,加載過慢。
渲染完成之后進行截圖,并緩存。下面是截圖代碼
- (UIImage*)captureImageFromView:(UIView*)view isUp:(BOOL)up{
CGRectscreenRect =CGRectMake(0,0,SCREEN_WIDTH,(SCREEN_HEIGHT-64)/2.0);
if(!up) {
screenRect=CGRectMake(0,(SCREEN_HEIGHT-64)/2.0,SCREEN_WIDTH,(SCREEN_HEIGHT-64)/2.0);
}
UIGraphicsBeginImageContextWithOptions(screenRect.size,NO, [UIScreenmainScreen].scale);
CGContextRefcontext =UIGraphicsGetCurrentContext();
if(context ==NULL){
returnnil;
}
//copy一份圖形上下位文,用來操作
CGContextSaveGState(context);
//將當前圖行位文進行矩陣變換
CGContextTranslateCTM(context, -screenRect.origin.x, -screenRect.origin.y);
[view.layerrenderInContext:context];
//圖形位文退出棧
CGContextRestoreGState(context);
UIImage*image =UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
returnimage;
}
3,緩存所有的UIImage對象,通過UIPanGestureRecognizer與CATransform3D實現翻頁動畫。
? ? ? ?首先,在上面兩個展示的UIImageView對象加入Pan手勢,并設置其錨點。
self.upImageView.layer.anchorPoint=CGPointMake(0.5,1.0);
self.downImageView.layer.anchorPoint=CGPointMake(0.5,0);
? ? ? 在layer層的tranform屬性可以是CATransform3D類型的四維仿射變換矩陣,并且提供預置好的進行旋轉、變形之后的仿射變換矩陣,我們只需改變CATransform3D的transform屬性就可以得到想要的動畫效果。在Pan手勢上滑過程中,需要一張臨時圖片在下面,frame跟所對應的展示ImageView一樣,同時當前ImageView的layer的tranform屬性根據滑動距離進行改變。
self.upImageView.layer.transform= [self transForm3DWithAngle:angle];
-(CATransform3D)TransForm3DWithAngle:(CGFloat)angle{
CATransform3Dtransform =CATransform3DIdentity;
transform.m34= -2.0/2000;
transform=CATransform3DRotate(transform,angle,1,0,0);
return transform;
}
CATransform3DRotate 是3D旋轉API。
CATransform3DCATransform3DRotate (CATransform3Dt,CGFloatangle,CGFloatx,CGFloaty,CGFloatz)
? ? ? ?第一個參數為transform對象,第二個為旋轉角度,第三,四,五個為旋轉軸。m34的只是CATransform3D結構體中的屬性,m34屬性可以實現透視效果,增加翻轉的3D效果。
? ? ? ?在旋轉超過90度時候,需要替換當前旋轉圖片,并做CTM替換。
UIGraphicsBeginImageContext(rect.size);
CGContextRefcontext =UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
//做CTM變換
//CGContextTranslateCTM(context, 0.0, rect.size.height);
//CGContextScaleCTM(context, 1.0, -1.0);
//CGContextRotateCTM(context, rotate);
//CGContextTranslateCTM(context, translateX, translateY);
CGContextScaleCTM(context, scaleX, scaleY);
//繪制圖片
CGContextDrawImage(context,CGRectMake(0,0, rect.size.width, rect.size.height), image.CGImage);
CGContextRestoreGState(context);
UIImage*newPic =UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
? ? ? ? 用戶松手之后,開啟定時器,根據Pan手勢的滑動趨勢或當前滑動的角度決定是否翻頁還是還原。