你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發基礎 >> 怎樣做一個iOS App的啟動分層引導動畫?

怎樣做一個iOS App的啟動分層引導動畫?

編輯:IOS開發基礎

一. 為什麼要寫這篇文章?

這是一個很古老的話題,從兩年前新浪微博開始使用多層動畫制作iOS App的啟動引導頁讓人眼前一亮(當然,微博是不是歷史第一個這個問題值得商榷)之後,各種類型的引導頁層出不窮,到如今,github上也有了各種的成型的library存在供選擇,同時不少app也已經慢慢的開始返璞歸真回歸單一靜態引導頁。雖然時尚的潮流不停的在變化,但是我一直在思索,這種多圖層的啟動引導動畫到底是什麼個結構?實現起來究竟有多難?本文,將試圖探尋這個話題。

二. 我們要做成什麼樣子的?

首先定下目標,我們要實現的是啟動引導畫面中的一種——多層次動畫。然後我們需要設定一個動畫的主題,我們需要表達我們的情感,或者抒情~或者動人~或者逗比~。當然這大部分是設計師的工作。
好吧,既然是demo,而我又不懂設計又不懂美學又不懂PS大法,那麼,就大概也許做成一個這樣子的把~~~

20141211120555828 (1).jpg

總結一下最終目標要有幾個要點:
1、4個頁。
2、每個頁都可能有若干分層,動畫速度不同。
3、整個滑動的手感應該是順滑並且是頁面式的。

三. 用什麼控件做?

開頭我講過,這是要探索,而不是為了實現,所以絕對不能借助任何3rd的library來完成。最大限度的利用apple的原生控件,是解決問題之道。

So,我們當然選用UIScrollView咯~~~除非你是個手工控。。。就要用最基本的UIView實現一個類似的滑動效果的UIScrollView。

啥?你問我UIScrollView是啥?

。。。。。。

下面是UIScrollView的幾個關鍵屬性,我相信你是明白的。需要注意的是,伴隨著scrollview的左右拖動,contentOffset是在一直變換的。數值范圍:(0,0) – (320 * 3, 0)。而這個屬性,是我們需要使用的關鍵數值。

uiscrollview_callouts_2x.png

四. 怎麼做?

上面我啰嗦了半天,最後告訴大家要用UIScrollView做,那麼問題來了,挖掘機技術哪家強?啊不,到底應該怎麼做?下面是干貨~

1. 首先我們要把我們承載整個動畫場面的scrollView造出來

如下,需要設置scrollView的幾個關鍵屬性:frame, contentSize, alwaysBounceHorizontal, paginEnabled(這個如果是NO,那麼頁面間的彈性效果就沒了), delegate(需要設置從而獲取scrollview的滾動狀態)等等。

//初始化 scrollview
- (void)initScrollView
{
    CGSize screenSize = [UIScreen mainScreen].bounds.size;
 
    _scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, screenSize.width, screenSize.height)];
//我們的scrollView的frame應該是屏幕大小
    _scrollView.contentSize = CGSizeMake(screenSize.width * 4, screenSize.height);
//但是我們希望我們scrollView的可被展現區域是4個屏幕橫排那麼大
    _scrollView.alwaysBounceHorizontal = YES;//橫向一直可拖動
    _scrollView.pagingEnabled = YES;//關鍵屬性,打開page模式。
    _scrollView.delegate = self;
    _scrollView.showsHorizontalScrollIndicator = NO;//不要顯示滾動條~
    
    [self.view addSubview:_scrollView];
}

現在我們已經准備好了動畫的畫布,下面開始將每一頁的元素加上去。

2. 加入頁面元素

還是不要全篇幅貼代碼了,以第一頁為例把。
前面掉渣天的蛇雞屎(我)的demo圖已經表明,第一頁,我們要有3個UILabel,一個UIImageView。
那麼好,這些元素我們就給他聲明出來。

@interface ViewController () 
@property (strong, nonatomic) UIScrollView *scrollView;//這是基本!
 
@property (strong, nonatomic) UIImageView *girlImageView;
@property (strong, nonatomic) UILabel *label_page1_1;
@property (strong, nonatomic) UILabel *label_page1_2;
@property (strong, nonatomic) UILabel *label_page1_3;
 
@end

然後把第一頁的元素,加進來~

//為了更方便的初始化UILabel,我為UILabel增加了一個簡易的類方法。是為了讓代碼更簡潔可讀。
+ (instancetype)labelWithText:(NSString *)text font:(UIFont *)font color:(UIColor *)color origin:(CGPoint)origin
{
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(origin.x, origin.y, 1000, 20)];
    label.text = text;
    label.font = font;
    label.textColor = color;
    [label sizeToFit];
    return label;
}
 
//然後我們將第一頁的元素加進來。
 
    self.label_page1_1 = [UILabel labelWithText:@"我要買iPhone6!" font:[UIFont systemFontOfSize:18.0f] color:[UIColor redColor] origin:CGPointMake(140, 200)];
    [self.scrollView addSubview:self.label_page1_1];
 
    self.label_page1_2 = [UILabel labelWithText:@"我要看醫生演唱會~~~~" font:[UIFont systemFontOfSize:18.0f] color:[UIColor blackColor] origin:CGPointMake(140, 240)];
    [self.scrollView addSubview:self.label_page1_2];
 
    self.label_page1_3 = [UILabel labelWithText:@"我要去大理!" font:[UIFont systemFontOfSize:18.0f] color:[UIColor orangeColor] origin:CGPointMake(140, 280)];
    [self.scrollView addSubview:self.label_page1_3];
    
    self.girlImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"image_girl"]];
    self.girlImageView.frame = CGRectMake(100, kScreenHeight - 200 - 50, 100, 200);
   [self.scrollView addSubview:self.girlImageView];

3. 讓第一頁動起來~~

在第一頁剛剛顯示的時候,我們就希望第一頁的元素能夠有一個動起來的效果。那我們在上面剛剛加入第一頁元素之後,可以緊接著做下面的事情:

    self.girlImageView.transform = CGAffineTransformMakeTranslation(-200, 0);
    self.label_page1_1.transform = CGAffineTransformMakeTranslation(- 100, 0);
    self.label_page1_2.transform = CGAffineTransformMakeTranslation(100, 0);
    self.label_page1_3.transform = CGAffineTransformMakeTranslation(- 120, 0);
    
    [UIView animateWithDuration:0.7
                     animations:^{
                         self.girlImageView.transform = CGAffineTransformMakeTranslation(0, 0);
                         self.label_page1_1.transform = CGAffineTransformMakeTranslation(0, 0);
                         self.label_page1_2.transform = CGAffineTransformMakeTranslation(0, 0);
                         self.label_page1_3.transform = CGAffineTransformMakeTranslation(0, 0);
                     }];

可以看到,我們分別給第一頁的四個元素不同的水平位移,然後希望它用0.7秒的時間,移動到之前init他們時候的位置。這樣就完成了第一個4層的錯位動畫。

然後,我們希望在手指滑動scrollview 的時候,第一頁的四個元素可以有相應的分層錯位動畫,那麼我們第一需要拿到當前scrollView的位移量,也就是前面提到的很重要的contentOffset。這個值,在:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView

中,可以實時的獲取。

具體來看,怎麼做。

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    CGFloat currentX = scrollView.contentOffset.x;
    
    if (currentX <= kScreenWidth)
    {
        self.girlImageView.transform = CGAffineTransformMakeTranslation((kScreenWidth + 100.0f) * currentX / kScreenWidth, 0);
        self.label_page1_2.transform = CGAffineTransformMakeTranslation(- 200 * currentX / kScreenWidth, 0);
    }
}

呵呵,是不是看不懂,那就對了。。。

下面解釋下,首先拋出兩個定理:

定理一:在scrollview的滑動過程中,視覺上看,scrollview上的元素的移動方向與手指滑動方向相反,並且移動的距離與手指滑動的距離相等。但所有元素在scrollview上的物理位置並未改變。

定理二:在scrollview的滑動過程中,當且僅當scrollview上的元素的物理移動距離與手指滑動距離相等並且移動方向相反時,scrollview的元素視覺位置保持不變。

然後我們有兩個需求:

第一,希望那個小女孩跟隨手指滑動的時候,視覺上不是向左移動一直到消失,而是向右移動,待滑動到第二頁的時候,小女孩出現在屏幕右側。

我們應該明確,小女孩的移動,只能是在scrollview上位置的移動。根據定理二,我們知道,如果保持視覺上小女孩位置不變,小女孩在scrollView上的實際物理位移應該是:

公式 4.3.1 baseDistance = kScreenWidth 屏幕寬度

那麼如果我們希望在移動到第二頁之後,小女孩的視覺位置右移了100像素,那麼小女孩在scrollView上的實際物理位移應該是:

公式 4.3.2 distance = baseDistance + 100

第一頁到第二頁,scrollView一共位移是 kScreenWidth ,當前scrollView位移是 contentOffset.x ,可以得出,當前位移的比例:

公式 4.3.3 status = scrollView.contentOffest.x / distance

由 4.3.1 4.3.2 4.3.3可得,我們設置小女孩位移的方式:

self.girlImageView.transform = CGAffineTransformMakeTranslation((kScreenWidth + 100.0f) * currentX / kScreenWidth, 0);

第二個需求,希望第一頁中,第二個label的向左移動速度快於其他兩個label。

根據定理二,和類似於上面的推倒(推導)方式,也易得第二個label的位移方式:

self.label_page1_2.transform = CGAffineTransformMakeTranslation(- 200 * currentX / kScreenWidth, 0);

五. 總結

綜上所述,我們知道了分層動畫的基本原理。如果使用更多的圖層,更多的位移或者角度變化,就能組合出更加復雜的分層動畫。

可以看到,分層動畫的基本原理並不復雜,但是為什麼那麼多人傾向於借助3rd的library來實現呢?一個字,懶。

現如今移動開發領域對於美感和交互的要求越來越高,而開發出一款精美的app,設計師所需要付出的靈感和努力也越發顯得重要。作為一個不怎麼有美感的iOS工程師,想要在移動浪潮中立於不敗之地,不斷嘗試更多新的可能遠比實現更多的功能更加重要。

最後的最後,附一個demo運行效果:

點擊查看demo

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved