“我的部落”多動畫APP設計與實現(xiàn)

hellow.jpg

廢話不說,先看gif效果邻奠,覺得不錯的話笤喳,就繼續(xù)看下去。

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上劫狠,然后就其中有些動畫說明一下拴疤。

動畫一:動態(tài)的UITabBar動畫

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

+ (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的數(shù)據等信息
    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的動態(tài)改變,該View的擴展和收縮晨炕。并且在收縮的時候位于中間的按鈕的圖片會發(fā)生變化衫画。

- (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是一個能讓我們以和屏幕刷新率相同的頻率將內容畫到屏幕上的定時器糙麦。我們在應用中創(chuàng)建一個新的 CADisplayLink 對象,把它添加到一個runloop中丛肮,并給它提供一個 target 和selector 在屏幕刷新的時候調用赡磅。

一但 CADisplayLink 以特定的模式注冊到runloop之后,每當屏幕需要刷新的時候宝与,runloop就會調用CADisplayLink綁定的target上的selector焚廊,這時target可以讀到 CADisplayLink 的每次調用的時間戳,用來準備下一幀顯示需要的數(shù)據习劫。例如一個視頻應用使用時間戳來計算下一幀要顯示的視頻數(shù)據咆瘟。在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動畫

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

- (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實現(xiàn)了哪些功能吧瓤逼。
1.一套完整的用戶登錄笼吟,注冊等功能库物,包括第三方登錄,在github代碼中我會屏蔽掉APPKey的贷帮,如果你需要第三方登錄戚揭,你得有自己的appkey。
2.數(shù)據撵枢,大體分為兩類民晒,一是本地數(shù)據,放在plist文件中诲侮,例如除新聞外的數(shù)據镀虐。另一個是通過免費的api,例如通過百度API沟绪,獲取新聞數(shù)據刮便。
3.地圖,采用的是百度地圖绽慈,標記用戶和目的地之間的路線恨旱,包括行車路線等信息。
4.其余的都是界面的設計坝疼,主要讓app更加好看搜贤。

說明:app中有些地方點進去后,沒有數(shù)據钝凶,這些純屬正常仪芒,是本地plist種無數(shù)據。

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

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

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

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末猾警,一起剝皮案震驚了整個濱河市建峭,隨后出現(xiàn)的幾起案子炎疆,更是在濱河造成了極大的恐慌,老刑警劉巖炒考,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件拂蝎,死亡現(xiàn)場離奇詭異雳窟,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進店門封救,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人捣作,你說我怎么就攤上這事誉结。” “怎么了券躁?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵惩坑,是天一觀的道長。 經常有香客問我也拜,道長以舒,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任慢哈,我火速辦了婚禮蔓钟,結果婚禮上,老公的妹妹穿的比我還像新娘卵贱。我一直安慰自己滥沫,他們只是感情好,可當我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布键俱。 她就那樣靜靜地躺著兰绣,像睡著了一般。 火紅的嫁衣襯著肌膚如雪编振。 梳的紋絲不亂的頭發(fā)上缀辩,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天,我揣著相機與錄音踪央,去河邊找鬼臀玄。 笑死,一個胖子當著我的面吹牛杯瞻,可吹牛的內容都是我干的镐牺。 我是一名探鬼主播,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼魁莉,長吁一口氣:“原來是場噩夢啊……” “哼睬涧!你這毒婦竟也來了?” 一聲冷哼從身側響起旗唁,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤畦浓,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后检疫,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體讶请,經...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了夺溢。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片论巍。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖风响,靈堂內的尸體忽然破棺而出嘉汰,到底是詐尸還是另有隱情,我是刑警寧澤状勤,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布鞋怀,位于F島的核電站,受9級特大地震影響持搜,放射性物質發(fā)生泄漏密似。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一葫盼、第九天 我趴在偏房一處隱蔽的房頂上張望残腌。 院中可真熱鬧,春花似錦剪返、人聲如沸废累。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽邑滨。三九已至,卻和暖如春钱反,著一層夾襖步出監(jiān)牢的瞬間掖看,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工面哥, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留哎壳,地道東北人。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓尚卫,卻偏偏與公主長得像归榕,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子吱涉,可洞房花燭夜當晚...
    茶點故事閱讀 42,792評論 2 345

推薦閱讀更多精彩內容