【iOS】彩色TabBar切換動畫實現

來源:互聯網
上載者:User

標籤:

無意間看到一個彩色TabBar切換的設計圖,感覺很不錯,有空就把他實現了。

環境資訊

Mac OS X 10.10.4

Xcode 6.4

iOS 8.4

源碼:

https://github.com/saitjr/STColorfulTabBar.git

 

本文

一、實現分析

看到這個彩色轉場效果的時候,我第一個反應就是在TabBar上有一個彩色的View,然後每個色塊的顯示都是通過mask來顯示的。最終,我的具體實現也是根據這個思路來的。

1. 設計思想

為了減少侵入性(耦合),我採取的是繼承UITabBar來實現,所以要整合的時候,只需要將系統的TabBar換成我寫的TColorfulTabBar就可以了。

2. 視圖層級圖

視圖層級圖

二、效果實現1. 添加彩色視圖colorfulView

TColorfulTabBar.m

- (void)setupColorView {        // 初始化彩色視圖,並將它加在tabbar上    UIView *colorView = [[UIView alloc] initWithFrame:self.bounds];    [self addSubview:colorView];    self.colorfulView = colorView;        // 彩色視圖的五種顏色,這是一個UIColor數組,    NSArray *colors = self.itemColors;    CGFloat itemWidth = self.bounds.size.width / self.itemCount;        for (int i = 0; i < self.itemCount; i ++) {                UIView *view = [[UIView alloc] initWithFrame:CGRectMake(itemWidth * i, 0, itemWidth, self.bounds.size.height)];         view.backgroundColor = colors[i];         [self.colorfulView addSubview:view];     } }
2. 添加彩色視圖的遮罩colorfulMaskView

之所以這裡的遮罩使用的是UIView而不是CAShapeLayer或者CALayer,原因如下:

  • 遮罩是矩形,沒必要使用路徑,所以不用CAShapeLayer
  • 通過設計圖可以看到,在位移動畫之前,有一個遮罩單向變寬(向左或向右)的效果。如果使用CALayer,那麼改變bounds的時候,是雙向改變,想要單向就必須加錨點,太麻煩
  • 如果使用UIView,那麼向右變寬只需要x不變,width變長就行;向左變寬只需要x-value,width+value就行,要方便的多
  • 最後一點就是在做動畫的時候,Layer要用到CABasicAnimation(CABaseAnimation之前寫錯了,已修正),然而UIView使用UIView的Animation就行

在設定遮罩的時候,將colorfulMaskView的layer設定為colorfulView的mask就可以了。

代碼實現如下:

TColorfulTabBar.m

- (void)setupMaskLayer {        // 擷取每個item的寬度    CGFloat itemWidth = self.bounds.size.width / self.itemCount;        // 初始化colorMaskView,並將colorMaskView的layer設定成彩色視圖的遮罩    UIView *colorMaskView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, itemWidth, self.bounds.size.height)];    colorMaskView.backgroundColor = [UIColor blackColor];    self.colorfulMaskView = colorMaskView;    self.colorfulView.layer.mask = self.colorfulMaskView.layer;}
3. 設定代理,擷取當前點擊的下標

UITabBar並沒有擷取點擊下標的介面,但是UITabBarDelegate有,這個協議預設被UITabBarController遵守。為了降低耦合性,採用UITabBar自己擷取下標,所以,需要UITabBar自己實現自己的delegate。

值得注意的是,不能在UITabBar的初始化方法中去設定self.delegate = self,因為即使設定了,也會被UITabBarController覆蓋。最終解決方案是當UITabBar載入到父視圖上是,在修改delegate為self。

- (void)didMoveToSuperview {    [super didMoveToSuperview];    self.delegate = self;}

因為每次的移動位置與方向都和上次的下標與這次的下標有關,所以需要使用到屬性來記錄這兩個下標的值。

- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item {        NSInteger index = [self.items indexOfObject:item];    self.fromeIndex = self.toIndex;    self.toIndex = index;    // 拿到下標以後執行動畫    [self animation];}
4. 移動遮罩,顯示不同的色塊

在做動畫的時候,需要考慮到效果的平滑性。整個動畫有兩個動畫組成,一個是寬度放大的動畫,一個是縮小到原來大小和位移動畫。整個動畫是EaseInOut的效果,所以拆開來看,就應該第一個動畫EaseIn,第二個動畫EaseOut。

一圖勝千言:

動畫線性圖

- (void)animation {        CGFloat itemWidth = self.bounds.size.width / self.itemCount;    // 為了效果看起來更平滑,所以根據兩次下標的差值來計算需要放大的距離    CGFloat extraWidth = ABS(self.toIndex - self.fromeIndex) * itemWidth / 4;        // 放大的大小    CGRect scaleFrame = CGRectMake(self.colorfulMaskView.x, 0, itemWidth + extraWidth, self.bounds.size.height);    // 最終大的大小與位置    CGRect toFrame = CGRectMake(self.toIndex * itemWidth, 0, itemWidth, self.bounds.size.height);        // 如果是向左移動,那修改x軸的座標    if (self.fromeIndex > self.toIndex) {                scaleFrame = CGRectMake(self.colorfulMaskView.x - extraWidth, 0, itemWidth + extraWidth, self.bounds.size.height);    }        // 兩個動畫加起來是一個EaseInOut的效果,所以第一個動畫就應該是EaseIn,第二個動畫是EaseOut    // 先進行放大    [UIView animateWithDuration:ANIMATION_DURATION delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{                self.colorfulMaskView.frame = scaleFrame;    } completion:^(BOOL finished) {                // 再進行縮小和位移        [UIView animateWithDuration:ANIMATION_DURATION delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{                        self.colorfulMaskView.frame = toFrame;        } completion:NULL];    }];}

【iOS】彩色TabBar切換動畫實現

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.