“我的部落”多動畫APP設計與實現

hellow.jpg

廢話不說,先看gif效果,覺得不錯的話,就繼續看下去。

los_pro1.gif
los_pro2.gif
los_pro3.gif
los_pro4.gif
los_pro5.gif
los_pro6.gif
los_pro7.gif
los_pro8.gif

該APP起初是參考城覓這個app(界面),之后加了些自己的設計想法,例如底部的ControlTabBar點擊動畫,登錄界面的動畫,電影界面的動畫,控制器轉場動畫,物體下落碰撞動畫,樹葉飄落動畫,新聞界面cell動畫。當然這些動畫的原型是我在cocoaChina上看到的動畫,覺得不錯,然后移植到自己設計的app中,并在大神們的基礎之上改成自己想要的動畫。

當然這個項目我會放在Github上,然后就其中有些動畫說明一下。

動畫一:動態的UITabBar動畫

自定義TaBaController把需要的參數傳入到YALFoldingTabBarController中,這樣的好處是我們只是需要給定參數,其余的操作,例如點擊后的操作只需要在底層寫好就可以了。

+ (void)showMainTabBarViewController {
    
    YALFoldingTabBarController *tabBarController = [[YALFoldingTabBarController alloc]
                                                        initWithViewControllers:[self getRootViewController]];

    //prepare leftBarItems
    YALTabBarItem *item1                         = [[YALTabBarItem alloc] initWithItemImage:[UIImage imageNamed:@"nearby_icon"]
                                                      leftItemImage:nil
                                                     rightItemImage:nil];

    //prepare rightBarItems
    YALTabBarItem *item2                         = [[YALTabBarItem alloc] initWithItemImage:[UIImage imageNamed:@"meishi"]
                                                      leftItemImage:nil
                                                     rightItemImage:nil];

    YALTabBarItem *item3                         = [[YALTabBarItem alloc] initWithItemImage:[UIImage imageNamed:@"plus_icon"]
                                                      leftItemImage:nil
                                             
        rightItemImage:[UIImage imageNamed:@"profile_icon"]];
    
    tabBarController.leftBarItems = @[item1];
    tabBarController.rightBarItems = @[item2];
    tabBarController.centerBarItems = @[item3];
    
    tabBarController.centerButtonImage = [UIImage imageNamed:@"plus_icon"];
    
    tabBarController.selectedIndex = 1;
    
    //customize tabBarView,設置底部View的高度,item的數據等信息
    tabBarController.tabBarView.extraTabBarItemHeight = YALExtraTabBarItemsDefaultHeight;
    tabBarController.tabBarView.offsetForExtraTabBarItems = YALForExtraTabBarItemsDefaultOffset;
    tabBarController.tabBarView.backgroundColor = [UIColor colorWithRed:94.0/255.0 green:91.0/255.0 blue:149.0/255.0 alpha:1];
    tabBarController.tabBarView.tabBarColor = [UIColor colorWithRed:72.0/255.0 green:211.0/255.0 blue:178.0/255.0 alpha:1];
    tabBarController.tabBarViewHeight = YALTabBarViewDefaultHeight;
    tabBarController.tabBarView.tabBarViewEdgeInsets = YALTabBarViewHDefaultEdgeInsets;
    tabBarController.tabBarView.tabBarItemsEdgeInsets = YALTabBarViewItemsDefaultEdgeInsets;
    
    UIWindow *window = [UIApplication sharedApplication].delegate.window;
    window.backgroundColor = [UIColor whiteColor];
    window.rootViewController = tabBarController;
    [window makeKeyAndVisible];
}

自己app中的根控制器,對應的是幾個按鈕點擊的時候進入該控制器中。

+ (NSArray *)getRootViewController{
    UIWindow *window = [UIApplication sharedApplication].delegate.window;
    window.backgroundColor = [UIColor whiteColor];
    
    GPFirstController *firstViewController = [[GPFirstController alloc] init];
    UINavigationController *oneNavigationController = [[UINavigationController alloc] initWithRootViewController:firstViewController];
    oneNavigationController.navigationBar.barStyle = UIBarStyleDefault;
    
    
    GPSecondController *secondViewController = [[GPSecondController alloc] init];
    UINavigationController *secondNavigationController = [[UINavigationController alloc] initWithRootViewController:secondViewController];
    [secondNavigationController setNavigationBarHidden:YES];
    
    GPThirdController *thirdViewController = [[GPThirdController alloc] init];
    UINavigationController *thirdNavigationController = [[UINavigationController alloc] initWithRootViewController:thirdViewController];
    thirdNavigationController.navigationBar.barStyle = UIBarStyleDefault;
    
    NSArray *ctrlArr = [NSArray arrayWithObjects:oneNavigationController,secondNavigationController,thirdNavigationController,nil];
    
    return ctrlArr;
}

該控件的動畫主要是在點擊的時候,自定義TabBar中有顏色的View的動態改變,該View的擴展和收縮。并且在收縮的時候位于中間的按鈕的圖片會發生變化。

- (void)animateTabBarViewExpand {
    CAAnimation *animation = [CAAnimation animationForTabBarExpandFromRect:self.collapsedBounds toRect:self.expandedBounds];
    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    [self.mainView.layer.mask addAnimation:animation forKey:nil];
}

- (void)animateTabBarViewCollapse {
    CAAnimation *animation = [CAAnimation animationForTabBarCollapseFromRect:self.expandedBounds toRect:self.collapsedBounds];
    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
    [self.mainView.layer.mask addAnimation:animation forKey:nil];
}

當然這些動畫是原來大神封裝好了的,你如果有興趣可以到底層看看。

動畫二:登錄界面動畫

//用手擋住眼睛的動畫
[UIView animateWithDuration:0.5 animations:^{
        self.imgLeftHand.frame = CGRectMake(self.imgLeftHand.frame.origin.x - offsetLeftHand, self.imgLeftHand.frame.origin.y + 30, self.imgLeftHand.frame.size.width, self.imgLeftHand.frame.size.height);
        
        self.imgRightHand.frame = CGRectMake(self.imgRightHand.frame.origin.x + 52, self.imgRightHand.frame.origin.y + 30, self.imgRightHand.frame.size.width, self.imgRightHand.frame.size.height);
        
        self.imgLeftHandGone.frame = CGRectMake(self.imgLeftHandGone.frame.origin.x - 70, self.imgLeftHandGone.frame.origin.y, 40, 40);
        
        self.imgRightHandGone.frame = CGRectMake(self.imgRightHandGone.frame.origin.x + 30, self.imgRightHandGone.frame.origin.y, 40, 40);

    } completion:^(BOOL b) {
    }];

該動畫其實就是View的frame動畫,只需要設置View的起終點的frame,然后放在UIView的animation中。

對于物體下落和碰撞動畫,控制器轉場動畫,cell的動畫可以參考我在簡書上之前寫的文章中,那些都是一個又一個的demo,如果你想把那些動畫運用到自己的代碼中,你得反復的代碼調試。

背景樹葉飄落動畫

這個動畫我們需要用到CADisplayLink,CADisplayLink是一個能讓我們以和屏幕刷新率相同的頻率將內容畫到屏幕上的定時器。我們在應用中創建一個新的 CADisplayLink 對象,把它添加到一個runloop中,并給它提供一個 target 和selector 在屏幕刷新的時候調用。

一但 CADisplayLink 以特定的模式注冊到runloop之后,每當屏幕需要刷新的時候,runloop就會調用CADisplayLink綁定的target上的selector,這時target可以讀到 CADisplayLink 的每次調用的時間戳,用來準備下一幀顯示需要的數據。例如一個視頻應用使用時間戳來計算下一幀要顯示的視頻數據。在UI做動畫的過程中,需要通過時間戳來計算UI對象在動畫的下一幀要更新的大小等等。
例如代碼:

self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(handleAction:)];
    self.displayLink.frameInterval = 3;
    [self.displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];

frameInterval
屬性是可讀可寫的NSInteger
型值,標識間隔多少幀調用一次selector
方法,默認值是1,即每幀都調用一次。如果每幀都調用一次的話,對于iOS設備來說那刷新頻率就是60HZ也就是每秒60次,如果將frameInterval
設為2 那么就會兩幀調用一次,也就是變成了每秒刷新30次。

同時需要注意的是:
在控制器dealloc時

[self.displayLink invalidate];
  self.displayLink = nil;

如果不這樣做的話,就會造成內存泄漏。
而在@selector中的方法是3幀調用一次方法,該方法是一片樹葉的飄落效果。

- (void)handleAction:(CADisplayLink *)displayLink {
    
    UIImage *image = [UIImage imageNamed:@"leaf"];
    UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
    CGFloat scale = arc4random_uniform(70) / 100.0;
    imageView.transform = CGAffineTransformMakeScale(scale, scale);
    CGSize winSize = self.logoView.bounds.size;
    CGFloat x = arc4random_uniform(winSize.width);
    CGFloat y = - imageView.frame.size.height;
    imageView.center = CGPointMake(x, y);
    
    [self.view addSubview:imageView];
    [UIView animateWithDuration:arc4random_uniform(5) animations:^{
        CGFloat toX = arc4random_uniform(winSize.width);
        CGFloat toY = winSize.height - 10;
        
        imageView.center = CGPointMake(toX, toY);
        imageView.transform = CGAffineTransformRotate(imageView.transform, arc4random_uniform(M_PI * 2));
        
        imageView.alpha = 0.2;
    } completion:^(BOOL finished) {
        [imageView removeFromSuperview];
    }];
}

選取logo動畫

該動畫只需要封裝好視圖,其動畫在創建的時候就可以做相應的處理。
對外只需要創建和設置屬性即可:

- (DisperseBtn *)disperseBtn {
    
    if (!_disperseBtn) {
        _disperseBtn = [[DisperseBtn alloc] initWithFrame:CGRectMake(0, 0, 45, 45)];
        _disperseBtn.borderRect = self.view.frame;
        _disperseBtn.layer.cornerRadius = _disperseBtn.height/2.0;
        _disperseBtn.closeImage = [UIImage imageNamed:@"changImage"];
        _disperseBtn.openImage = [UIImage imageNamed:@"changImage"];
        _disperseBtn.right = SCREEN_WIDTH - 10;
        _disperseBtn.centerY = 42;
    }
    return _disperseBtn;
}

//####################################################################
self.logoImageArr = @[@"mylogo1.jpg",@"mylogo2.jpg",@"mylogo3.jpg",@"mylogo4.jpg",@"mylogo5.jpg",];
    NSMutableArray *marr = [NSMutableArray array];
    for (int i = 0; i< self.logoImageArr.count; i++) {
        UIButton *btn = [UIButton new];
        [btn setBackgroundImage:[UIImage imageNamed:self.logoImageArr[i]] forState:UIControlStateNormal];
        [marr addObject:btn];
        btn.tag = i;
        [btn addTarget:self action:@selector(buttonTagget:) forControlEvents:UIControlEventTouchUpInside];
    }
    self.disperseBtn.btns = [marr copy];
//#####################################################################

其余的動畫封裝時寫進去即可。

如果說亮點的話,我覺得主要有很多動畫,讓app靈動起來。

下面我就歸納一下這個app實現了哪些功能吧。
1.一套完整的用戶登錄,注冊等功能,包括第三方登錄,在github代碼中我會屏蔽掉APPKey的,如果你需要第三方登錄,你得有自己的appkey。
2.數據,大體分為兩類,一是本地數據,放在plist文件中,例如除新聞外的數據。另一個是通過免費的api,例如通過百度API,獲取新聞數據。
3.地圖,采用的是百度地圖,標記用戶和目的地之間的路線,包括行車路線等信息。
4.其余的都是界面的設計,主要讓app更加好看。

說明:app中有些地方點進去后,沒有數據,這些純屬正常,是本地plist種無數據。

如果您看到這兒來了,并且你覺得這些動畫還不錯的話,麻煩點擊一下下面的喜歡就可以了。當然下幾篇文章也是關于個人對于app的設計和實現,喜歡的話可以點擊關注哦~~~。

最后附上github上的地址:https://github.com/CoDancer/Github_proj.

PS:如果畢業設計是IOS的,有什么地方需要幫助的話可以加QQ:2150393078。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,578評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,701評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,691評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,974評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,694評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,026評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,015評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,193評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,719評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,442評論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,668評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,151評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,846評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,255評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,592評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,394評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,635評論 2 380

推薦閱讀更多精彩內容