? ? ? ?最近工作中遇到一個(gè)首頁(yè)要實(shí)現(xiàn)翻頁(yè)動(dòng)畫的需求,上網(wǎng)搜索未找到自己滿意的方案,索性自己寫了一份,主要利用了CoreGraphics框架進(jìn)行的圖片處理,在這里與大家分享實(shí)現(xiàn)思路,若大家有更好的方法可以與我交流交流。
? ? ? ? 首頁(yè)按日期加載多日的資訊,每次上滑或者下滑顯示另一天資訊時(shí),需要用到翻頁(yè)動(dòng)畫。下面是實(shí)現(xiàn)效果。
這里采用CATransform3D來實(shí)現(xiàn),思路如下:
1,向后臺(tái)請(qǐng)求資訊數(shù)據(jù)。
2,渲染每日的UIView。并在圖片加載完成之后對(duì)其進(jìn)行截圖,得到以中線分割的兩個(gè)UIImage對(duì)象。
? ? ?在YYKit的網(wǎng)絡(luò)圖片處理庫(kù)中,圖片加載完成會(huì)在block得到。可用臨時(shí)數(shù)組標(biāo)示當(dāng)日View是否加載完成,完成后替換切割圖片,替換對(duì)應(yīng)的展示圖片。
同時(shí)開啟定時(shí)器,定時(shí)截圖,避免網(wǎng)絡(luò)不好,加載過慢。
渲染完成之后進(jìn)行截圖,并緩存。下面是截圖代碼
- (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);
//將當(dāng)前圖行位文進(jìn)行矩陣變換
CGContextTranslateCTM(context, -screenRect.origin.x, -screenRect.origin.y);
[view.layerrenderInContext:context];
//圖形位文退出棧
CGContextRestoreGState(context);
UIImage*image =UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
returnimage;
}
3,緩存所有的UIImage對(duì)象,通過UIPanGestureRecognizer與CATransform3D實(shí)現(xiàn)翻頁(yè)動(dòng)畫。
? ? ? ?首先,在上面兩個(gè)展示的UIImageView對(duì)象加入Pan手勢(shì),并設(shè)置其錨點(diǎn)。
self.upImageView.layer.anchorPoint=CGPointMake(0.5,1.0);
self.downImageView.layer.anchorPoint=CGPointMake(0.5,0);
? ? ? 在layer層的tranform屬性可以是CATransform3D類型的四維仿射變換矩陣,并且提供預(yù)置好的進(jìn)行旋轉(zhuǎn)、變形之后的仿射變換矩陣,我們只需改變CATransform3D的transform屬性就可以得到想要的動(dòng)畫效果。在Pan手勢(shì)上滑過程中,需要一張臨時(shí)圖片在下面,frame跟所對(duì)應(yīng)的展示ImageView一樣,同時(shí)當(dāng)前ImageView的layer的tranform屬性根據(jù)滑動(dòng)距離進(jìn)行改變。
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旋轉(zhuǎn)API。
CATransform3DCATransform3DRotate (CATransform3Dt,CGFloatangle,CGFloatx,CGFloaty,CGFloatz)
? ? ? ?第一個(gè)參數(shù)為transform對(duì)象,第二個(gè)為旋轉(zhuǎn)角度,第三,四,五個(gè)為旋轉(zhuǎn)軸。m34的只是CATransform3D結(jié)構(gòu)體中的屬性,m34屬性可以實(shí)現(xiàn)透視效果,增加翻轉(zhuǎn)的3D效果。
? ? ? ?在旋轉(zhuǎn)超過90度時(shí)候,需要替換當(dāng)前旋轉(zhuǎn)圖片,并做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();
? ? ? ? 用戶松手之后,開啟定時(shí)器,根據(jù)Pan手勢(shì)的滑動(dòng)趨勢(shì)或當(dāng)前滑動(dòng)的角度決定是否翻頁(yè)還是還原。