類似3D效果_CGAffineTransformScale

圖片來源于網(wǎng)絡(luò)

1??CGAffineTransformMakeTranslation
(相對平移)假設(shè)是一個視圖,那么它的起始位置 x 會加上tx , y 會加上 ty
2??CGAffineTransformScale
為一個Transformation再加上縮放
3??CGAffineTransformIdentity
單位矩陣變換,一般用于仿射變換的初始化或者還原。

本文將用以上方法做如下gif效果

gif有點卡頓,坑

這并不是一個真正的3D效果,但它看起來非常接近

一、創(chuàng)建變換的label

1、在storyboard創(chuàng)建一個label,text為"我是肥仔"。

2、先創(chuàng)一個動畫方向的枚舉

typedef enum _AnimationDirection {
    positive  = 1,
    negative = -1,
} AnimationDirection;

3、創(chuàng)建一個方法

- (void)cubeTransitionWithLab:(UILabel *)label text:(NSString *)text direction:(AnimationDirection)direction

方法中,先添加一下代碼

    UILabel *auxLabel = [[UILabel alloc] initWithFrame:label.frame];
    auxLabel.text = text;
    auxLabel.font = label.font;
    auxLabel.textAlignment = label.textAlignment;
    auxLabel.textColor = label.textColor;
    auxLabel.backgroundColor = label.backgroundColor;
    auxLabel.backgroundColor = [UIColor redColor];
    //offset
    CGFloat auxLabelOffset = (CGFloat)direction *
    auxLabel.frame.size.height/2.0;
    auxLabel.transform = CGAffineTransformScale(CGAffineTransformMakeTranslation(0.0, auxLabelOffset), 1.0, 0.1);
    [label.superview addSubview:auxLabel]; //在label的所在view添加auxLabel,即auxLabel在label的上面覆蓋著

上面代碼創(chuàng)建了auxLabel,以及設(shè)置一些常用屬性,auxLabel.transform = CGAffineTransformScale(CGAffineTransformMakeTranslation(0.0, auxLabelOffset), 1.0, 0.1);這句代碼是auxLabel在y軸上偏移auxLabelOffset,同時會高度縮小為原來的0.1倍。如圖:

image.png

4、在cubeTransitionWithLab繼續(xù)以下代碼:

[UIView animateWithDuration:0.5 delay:0.0 options:UIViewAnimationOptionCurveEaseOut animations:^{
    auxLabel.transform = CGAffineTransformIdentity;
    label.transform =  CGAffineTransformScale(CGAffineTransformMakeTranslation(0.0, -auxLabelOffset), 1.0, 0.1);
} completion:^(BOOL finished) {
    label.text = auxLabel.text;
    label.transform = CGAffineTransformIdentity;
    [auxLabel removeFromSuperview];
}];

把auxLabel還原成為變換之前的樣子,過渡持續(xù)時間是1.5秒,延遲0秒,效果為UIViewAnimationOptionCurveEaseOut淡出,同時把故事版中的label在y軸與auxLabel反向平移相同的距離,從而造成很微妙的效果(有點像翻頁效果)。如圖:

完成后,把label的文字設(shè)置與auxLabel一樣,把label還原為剛開始的樣子,并把auxLabel從Superview移除

現(xiàn)在從上往下翻頁的效果已經(jīng)出來了,但是看起來怪怪的,我們要做的是一個類似的3D效果,所以得做循環(huán),且一次從上往下,一次從下往上。

二、設(shè)置循環(huán)

1、在viewDidLoad中,聲明屬性_direction為positive,并調(diào)用即將創(chuàng)建的changeFlight方法

- (void)viewDidLoad {
    [super viewDidLoad];
    _direction = positive;
    [self changeFlight];
}

創(chuàng)建changeFlight方法,并添加一下代碼

_direction = (CGFloat)(_direction != positive) ? positive : negative;
CGFloat direction = _direction;
NSString *str = @"我是靚仔";
if (_direction != positive) {
    str = @"我不靚仔";
}

以上代碼用了三木運算符,控制不同的_direction,并初始化str

2、接著,調(diào)用cubeTransitionWithLab并傳所需參數(shù)

[self cubeTransitionWithLab:self.lab text:str direction: direction];

3、最后,運用GCD方法,延遲標(biāo)簽(label和auxLabel)上下變換變換的時間,并調(diào)用自身

double delayInSeconds = 3.0;
__block ViewController* bself = self;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));

dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
    [bself changeFlight];
});

這樣就搞定了!大伙可以試試。變換方法比較簡單,難的主要是里面的邏輯

10.27

添加新功能:關(guān)鍵幀動畫
之前的文章說過UIView.animate這個方法,把多個動畫鏈接在一起,可能你會想到在這方法里面嵌套多個這個方法,達(dá)到多個動畫鏈接。但是這樣復(fù)雜一點的動畫,你會崩潰。。
所以我們可以將整個動畫分成幾個不同的階段,或者關(guān)鍵幀,然后將單個的關(guān)鍵幀組合成一個關(guān)鍵幀動畫。

關(guān)鍵幀動畫
- (void)planeDepart {
    
    CGPoint originalCenter = self.planeImage.center;
    [UIView animateKeyframesWithDuration:1.5 delay:0.0 options:UIViewKeyframeAnimationOptionLayoutSubviews animations:^{
        [UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:0.25 animations:^{
            CGPoint center = self.planeImage.center;
            center.x -= 80;
            center.y += 10;
            self.planeImage.center = center;
//            self.planeImage.center.x += 80;
        }];
        
        [UIView addKeyframeWithRelativeStartTime:0.1 relativeDuration:0.4 animations:^{
            self.planeImage.transform = CGAffineTransformMakeRotation(-M_PI / 8);
        }];
        
        [UIView addKeyframeWithRelativeStartTime:0.25 relativeDuration:0.25 animations:^{
            CGPoint center = self.planeImage.center;
            center.x -= 100;
            center.y -= 50;
            self.planeImage.center = center;
            self.planeImage.alpha = 0.0;
        }];
        
        [UIView addKeyframeWithRelativeStartTime:0.51 relativeDuration:0.01 animations:^{
            self.planeImage.transform = CGAffineTransformIdentity;
            
            CGPoint center = self.planeImage.center;
            center.x = 0.0;
            center.y = originalCenter.y;
            self.planeImage.center = center;
            
        }];
        
        
        [UIView addKeyframeWithRelativeStartTime:0.55 relativeDuration:0.45 animations:^{
            self.planeImage.alpha = 1.0;
            CGPoint center = self.planeImage.center;
            center = originalCenter;
            self.planeImage.center = center;
        }];
        
    } completion:nil];
    
}

代碼解析:
開始時間和持續(xù)時間是0.0和1.0之間的值,指定時間和持續(xù)時間是相對于關(guān)鍵幀動畫的整個時間的,例如,0.1是10%,0.25是25%,而1.0是整個持續(xù)時間的100%。

效果如下:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容