動(dòng)畫四

后面的東西垄琐,可能就比較繁瑣蹦肴,因?yàn)橄袂懊娴淖龇梢哉f是比較固定的,算是比較好的一個(gè)方法(當(dāng)然也有別的方法)揽涮,但是后面的做法抠藕,就是要試著來了。
我起初是想把collectionViewCell直接拉大蒋困,變成屏幕這么大的盾似,可是看著后面界面的操作一定是需要一個(gè)控制器權(quán)限的,所以就思考用導(dǎo)航控制器來銜接雪标,一方面現(xiàn)在的app也多是基于導(dǎo)航的零院,便于整合,另一方面也算對上面疑問的一個(gè)解決汰聋。门粪。。然后順著很費(fèi)事的做完了烹困,回頭想想玄妈,這樣做不見得好。因?yàn)橼s時(shí)間做別的事髓梅,只能這樣了拟蜻。

基于上面的思考,可以說會用到專場動(dòng)畫這套東西枯饿,但是我們還是從簡單的入手酝锅,先用push將就著,在push過去的控制器里先布置好我們控件的位置奢方。

AnotherController

我初步預(yù)想的是轉(zhuǎn)場用UIView的動(dòng)畫來做搔扁,所以為了便于獲取幾個(gè)大控件位置爸舒,又不會被屏幕大小影響的情況下,直接用frame去寫這些大的控件稿蹲。然后為了起初省勁扭勉,又直接用上面view,下面tableView的方式,其實(shí)現(xiàn)在覺得用個(gè)headerView也不錯(cuò)

    //topView
    self.topImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[CardModel cardModel][self.index].cardPicName]];
    self.topImageView.userInteractionEnabled = YES;
    self.topImageView.frame = CGRectMake(0, -1.5 * Marign, ScreenWidth, TopViewHeight + 1.5 * Marign);
    self.topImageView.contentMode = UIViewContentModeScaleToFill;
    [self.view addSubview:self.topImageView];
    
    self.titleView = [[UIView alloc] initWithFrame:CGRectMake(0, TopViewHeight , ScreenWidth, TitleViewHeight)];
    self.titleView.backgroundColor = [UIColor whiteColor];
    [self.view addSubview:self.titleView];

    //tabView
    self.tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, TitleViewHeight + TopViewHeight, ScreenWidth, ScreenHeight - (TitleViewHeight + TopViewHeight))];
    [self.tableView registerClass:[CardTableViewCell class] forCellReuseIdentifier:CellId];
    self.tableView.delegate = self;
    self.tableView.dataSource = self;
    
    self.tableView.rowHeight = UITableViewAutomaticDimension;
    self.tableView.estimatedRowHeight = 60;
    
    self.tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLineEtched;
    
    self.tableView.bounces = NO;
    self.tableView.showsVerticalScrollIndicator = NO;
    
    [self.view addSubview:self.tableView];

對小控件還是用masonry,可以整體移動(dòng)苛聘。

    //標(biāo)題
    UILabel *titleLabel = [UILabel cz_labelWithText:@"xxxxx * 100" fontSize:16 color:[UIColor lightGrayColor]];
    titleLabel.numberOfLines = 1;
    [self.titleView addSubview:titleLabel];
    [titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.titleView.mas_top).offset(15);
        make.left.equalTo(self.view.mas_left).offset(15);
        make.centerX.equalTo(self.view.mas_centerX);
    }];
    
    //評價(jià)
    UILabel *comment = [UILabel cz_labelWithText:@"100 comments" fontSize:14 color:[UIColor grayColor]];
    comment.textAlignment = NSTextAlignmentLeft;
    [self.titleView addSubview:comment];
    [comment mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(titleLabel.mas_bottom).offset(10);
        make.left.equalTo(self.titleView.mas_left).offset(15);
        make.height.mas_equalTo(@20);
    }];
    
    //星星
    CardStartsView *startView = [[CardStartsView alloc] init];
    startView.level = 4;
    [self.titleView addSubview:startView];
    [startView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerY.equalTo(comment.mas_centerY);
        make.left.equalTo(comment.mas_right).offset(10);
        make.width.mas_equalTo(@70);
        make.height.mas_equalTo(@20);
    }];

    //返回按鈕
    UIButton *backBtn = [[UIButton alloc] init];
    [backBtn setImage:[UIImage imageNamed:@"back"] forState:UIControlStateNormal];
    [backBtn addTarget:self action:@selector(clickBackBtn) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:backBtn];
    [backBtn mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.view.mas_top).offset(27);
        make.left.equalTo(self.view.mas_left).offset(15);
        make.width.height.mas_equalTo(@30);
    }];

然后先隨便寫一寫數(shù)據(jù)源方法涂炎,做個(gè)cell什么的,之后開始寫轉(zhuǎn)場

轉(zhuǎn)場動(dòng)畫

轉(zhuǎn)場依賴于UIViewControllerAnimatedTransitioning
我們做個(gè)繼承NSObject的類设哗,去實(shí)現(xiàn)UIViewControllerAnimatedTransitioning里面的要求就好了唱捣。
調(diào)兩個(gè)方法,一個(gè)設(shè)置動(dòng)畫時(shí)長网梢,另一個(gè)設(shè)置如何執(zhí)行轉(zhuǎn)場動(dòng)畫

//動(dòng)畫時(shí)長設(shè)置
- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext
{
    return 0.5;
}

//如何執(zhí)行轉(zhuǎn)場動(dòng)畫
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
    switch (_type) {
        case CardTransitionPush:
            [self pushAnimation:transitionContext];
            break;
        
        case CardTransitionPop:
            [self popAnimation:transitionContext];
            break;
    }
}

這上面的pushAnimation和popAnimation就是我們自己要寫的了震缭,這兩個(gè)方法看起來是差不多的,實(shí)際上也是战虏,但是因?yàn)楹芏嘈≡蛑颍环奖銓懺谝黄穑头珠_來寫了
代碼的內(nèi)容通過中轉(zhuǎn)的導(dǎo)航獲取到它上一個(gè)控制器和下一個(gè)控制器活烙,把上一個(gè)的位置通過UIView動(dòng)畫改成下一個(gè)位置,因?yàn)殚L時(shí)間沒寫遣鼓,所以實(shí)現(xiàn)起來比較費(fèi)時(shí)啸盏。主要很多方法不記得了。里面的層次還是比較重要的骑祟,如果寫亂了回懦,就會出現(xiàn)很丑的東西,在pop時(shí)候也很麻煩

//執(zhí)行push動(dòng)畫
- (void)pushAnimation:(id<UIViewControllerContextTransitioning>)transitionContext
{
    //起始頁面
    ViewController *fromVC = (ViewController *)[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    //目標(biāo)頁面
    AnotherViewController *toVC = (AnotherViewController *)[transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    
    //拿到當(dāng)前點(diǎn)擊的cell的imageView
    CardCollectionViewCell *cell;
    NSArray<CardCollectionViewCell *> *cellArray = [fromVC.cardScrollView.collectionView visibleCells];
    for (int i = 0; i < cellArray.count; i++) {
        if (fromVC.currentIndex == cellArray[i].index) {
            cell = (CardCollectionViewCell *)cellArray[i];
        }
    }
    
    UIView *containerView = [transitionContext containerView];
    
    //圖片
    UIView *imageView = [cell.coverImageView snapshotViewAfterScreenUpdates:NO];
    imageView.frame = [cell.coverImageView convertRect:cell.coverImageView.bounds toView: containerView];
    
    //titleView
    UIView *titleView = [cell.titleView snapshotViewAfterScreenUpdates:NO];
    titleView.frame = [cell.titleView convertRect:cell.titleView.bounds toView:containerView];
    
    //bgView
    UIView *bgView = [cell.bgView snapshotViewAfterScreenUpdates:NO];
    bgView.frame = [cell.bgView convertRect:cell.bgView.bounds toView:containerView];
    
    //設(shè)置動(dòng)畫前的各個(gè)控件的狀態(tài)
    cell.coverImageView.hidden = YES;
    cell.titleView.hidden = YES;
    cell.bgView.hidden = YES;
    toVC.view.alpha = 0;
    toVC.topImageView.hidden = YES;
    toVC.titleView.hidden = YES;
    toVC.tableView.hidden = YES;
    
    //注意添加的層次關(guān)系
    [containerView addSubview:toVC.view];
    [containerView addSubview:bgView];
    [containerView addSubview:titleView];
    [containerView addSubview:imageView];
    
    //開始做動(dòng)畫
    [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
        
        //titleView frame
        CGRect titleFrame = titleView.frame;
        titleFrame.origin = [toVC.titleView convertPoint:toVC.titleView.bounds.origin toView:containerView];
        titleView.frame = titleFrame;
        toVC.view.alpha = 1;
        //bgView
        bgView.frame = CGRectMake(0, 300, ScreenWidth, ScreenHeight - 300);
        //圖片frame
        imageView.frame = [toVC.topImageView convertRect:toVC.topImageView.bounds toView:containerView];
    } completion:^(BOOL finished) {
        imageView.hidden = YES;
        toVC.topImageView.hidden = NO;
        titleView.hidden = YES;
        bgView.hidden = YES;
        toVC.titleView.hidden = NO;
        toVC.tableView.hidden = NO;
        [transitionContext completeTransition:YES];
    }];
}

在pop里面我們拿出存在[transitionContext containerView]里面的控件次企,然后讓它們該顯示的顯示怯晕,該隱藏的隱藏

//執(zhí)行pop動(dòng)畫
- (void)popAnimation:(id<UIViewControllerContextTransitioning>)transitionContext
{
    //起始頁面
    AnotherViewController *fromVC = (AnotherViewController *)[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    //目標(biāo)頁面
    ViewController *toVC = (ViewController *)[transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    
    //拿到當(dāng)前點(diǎn)擊的cell的imageView
    CardCollectionViewCell *cell;
    NSArray<CardCollectionViewCell *> *cellArray = [toVC.cardScrollView.collectionView visibleCells];
    for (int i = 0; i < cellArray.count; i++) {
        if (toVC.currentIndex == cellArray[i].index) {
            cell = (CardCollectionViewCell *)cellArray[i];
        }
    }
    
    UIView *containerView = [transitionContext containerView];
    
    //這個(gè)根據(jù)之前push時(shí)添加的順序確定的
    //topImageView
    UIView *imageView = containerView.subviews.lastObject;
    //titleView
    UIView *titleView = containerView.subviews[2];
    //bgView
    UIView *bgView = containerView.subviews[1];
    
    //設(shè)置初始時(shí)的狀態(tài)
    cell.coverImageView.hidden = YES;
    cell.titleView.hidden = YES;
    fromVC.topImageView.hidden = YES;
    fromVC.titleView.hidden = YES;
    imageView.hidden = NO;
    titleView.hidden = NO;
    bgView.hidden = NO;
    [containerView insertSubview:toVC.view atIndex:0];
    
    [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
        imageView.frame = [cell.coverImageView convertRect:cell.coverImageView.bounds toView:containerView];
        titleView.frame = [cell.titleView convertRect:cell.titleView.bounds toView:containerView];
        bgView.frame = [cell.bgView convertRect:cell.bgView.bounds toView:containerView];
        fromVC.view.alpha = 0;
    } completion:^(BOOL finished) {
        cell.coverImageView.hidden = NO;
        cell.titleView.hidden = NO;
        cell.bgView.hidden = NO;
        [imageView removeFromSuperview];
        [titleView removeFromSuperview];
        [bgView removeFromSuperview];
        [transitionContext completeTransition:YES];
    }];
}

上面要說的就是我們在之前collectionViewCell里面是有個(gè)bgView做底板的,但是在下一個(gè)控制器缸棵,這個(gè)view就不用了舟茶,但是我們也是要過渡的,不然的話就會很丑堵第。
還有就是用戶視圖吧凉,那個(gè)也是要隱藏的。

這樣我們就可以回到下一個(gè)控制器里踏志,去指定一下轉(zhuǎn)場動(dòng)畫了

- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC
{
    return [CardTransition transitionWithType:operation == UINavigationControllerOperationPush ?
                          CardTransitionPush : CardTransitionPop];
}

這時(shí)候就會出現(xiàn)一個(gè)問題阀捅,就是那張圖片,圖片本來是豎為高的针余,但是轉(zhuǎn)過來的話饲鄙,我們不可能給它預(yù)留過多的高度凄诞,因?yàn)橐otableView留有空間,但是又不能讓他自適應(yīng)忍级,因?yàn)槟愕霓D(zhuǎn)場動(dòng)畫要自然帆谍,就好像真的是放大過去的,轉(zhuǎn)過去颤练,一消失再把圖片刷地自適應(yīng)一下既忆,會很丑,所以這確實(shí)是一個(gè)由之前決策引起的問題嗦玖。所以要去思考解決思路患雇,我想到的就是把圖片的高度擴(kuò)展到屏幕外,這樣行的通宇挫,但是圖片的內(nèi)容也很大程度上可能會出去苛吱。但是圖片高度出去的部分小,還是會被壓縮的很丑器瘪。所以我們想著上下各擴(kuò)大去一部分翠储,留有中間關(guān)鍵位置,但是還是有問題橡疼,在轉(zhuǎn)場的時(shí)候圖片會蓋住titleView,直到結(jié)束以后援所,才會顯現(xiàn)出來。我思前想后欣除,又想了一個(gè)方法住拭,就是通過- (void)viewDidAppear:(BOOL)animated在顯示結(jié)束以后,再使它發(fā)生一次快速位移历帚,把下部分遮掉滔岳,效果也還可以,算是告一段落這個(gè)頭疼的問題

    [super viewDidAppear:animated];
    [UIView animateWithDuration:0.3 animations:^{
        self.titleView.frame = CGRectMake(0, TopViewHeight - Marign, ScreenWidth, Marign);
        self.titleView.alpha = 0.9;
        self.tableView.frame = CGRectMake(0, TitleViewHeight + TopViewHeight - Marign - 30, ScreenWidth, ScreenHeight - (TitleViewHeight + TopViewHeight - Marign - 30));
    }];

你們肯定發(fā)現(xiàn)了挽牢,我有個(gè)兩個(gè)效果圖在轉(zhuǎn)場里的東西避而不談谱煤,一個(gè)就是那個(gè)tableView逐漸顯現(xiàn),另外一個(gè)就是用戶頭像的動(dòng)畫移動(dòng)禽拔。因?yàn)檫@兩個(gè)我是稍微試了一下刘离,在現(xiàn)有的情況下,都不大好做睹栖,所以又放了一下寥闪,還是從簡單的著手,我們?nèi)ヌ幚韈ell磨淌,這個(gè)也是必要的疲憋,因?yàn)樗g接關(guān)系著頭像動(dòng)畫移動(dòng).

TableViewCell

關(guān)于cell,昵稱梁只,頭像都是好解決的缚柳,相對來說埃脏,評論比較麻煩,因?yàn)楦叨扔赡P涂刂魄锩Γ覀冏鳇c(diǎn)數(shù)據(jù)進(jìn)去試試彩掐,然后先用UITableViewAutomaticDimension自動(dòng)計(jì)算行高,
需要注意的就是那個(gè)評論就不用指定高度了灰追,只需要指定它的底部和contentView的約束關(guān)系就好

    //用戶評論
    self.userComment = [UILabel cz_labelWithText:self.model.userComment fontSize:14 color:[UIColor darkGrayColor]];
    self.userComment.numberOfLines = 0;
    self.userComment.textAlignment = NSTextAlignmentLeft;
    [self.contentView addSubview:self.userComment];
    [self.userComment mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.userImage.mas_bottom).offset(10);
        make.left.equalTo(self.contentView.mas_left).offset(15);
        make.right.equalTo(self.contentView.mas_right).offset(-15);
        make.bottom.equalTo(self.contentView).offset(-15);
    }];

我們來看下效果圖堵幽,在過渡的時(shí)候還是有些僵硬,是因?yàn)樯厦嫣岬降膬刹糠值娜笔У臁N覀兒竺鏁f這個(gè)朴下。


3月-14-2018 16-20-45.gif
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市苦蒿,隨后出現(xiàn)的幾起案子殴胧,更是在濱河造成了極大的恐慌,老刑警劉巖佩迟,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件团滥,死亡現(xiàn)場離奇詭異,居然都是意外死亡报强,警方通過查閱死者的電腦和手機(jī)灸姊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來秉溉,“玉大人厨钻,你說我怎么就攤上這事〖崾龋” “怎么了?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵诗充,是天一觀的道長苍蔬。 經(jīng)常有香客問我,道長蝴蜓,這世上最難降的妖魔是什么碟绑? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮茎匠,結(jié)果婚禮上格仲,老公的妹妹穿的比我還像新娘。我一直安慰自己诵冒,他們只是感情好凯肋,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著汽馋,像睡著了一般侮东。 火紅的嫁衣襯著肌膚如雪圈盔。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天悄雅,我揣著相機(jī)與錄音驱敲,去河邊找鬼。 笑死宽闲,一個(gè)胖子當(dāng)著我的面吹牛众眨,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播容诬,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼娩梨,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了放案?” 一聲冷哼從身側(cè)響起姚建,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎吱殉,沒想到半個(gè)月后掸冤,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡友雳,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年稿湿,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片押赊。...
    茶點(diǎn)故事閱讀 38,161評論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡饺藤,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出流礁,到底是詐尸還是另有隱情涕俗,我是刑警寧澤,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布神帅,位于F島的核電站再姑,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏找御。R本人自食惡果不足惜元镀,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望霎桅。 院中可真熱鬧栖疑,春花似錦、人聲如沸滔驶。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至澳淑,卻和暖如春比原,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背杠巡。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工量窘, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人氢拥。 一個(gè)月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓蚌铜,卻偏偏與公主長得像,于是被迫代替她去往敵國和親嫩海。 傳聞我的和親對象是個(gè)殘疾皇子冬殃,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,527評論 25 707
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件叁怪、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,033評論 4 62
  • 昨日,北京時(shí)間2018年2月7日血柳,電視劇《戀愛先生》收官官册,相信大家都會和我有相同的感受——沒看夠,沒過癮难捌。 首先膝宁,...
    9b3632873333閱讀 650評論 0 51
  • 鐵,麻布根吁,小麥的價(jià)值员淫,雖然看不見,但卻存在于諸物自體內(nèi)击敌。必須與金相等介返,于金發(fā)生關(guān)系(只在它腦中存在的關(guān)系),它們的...
    愛吃面條不愛喝湯閱讀 175評論 0 1
  • 我是04年到深圳的愚争,跟敏的相識再簡單不過,她是公司經(jīng)理的女朋友挤聘,公司組織活動(dòng)時(shí)轰枝,能帶家屬,經(jīng)理的家屬自然能來组去。她...
    小丫屠閱讀 309評論 4 0