高仿Boss直聘招聘詳情頁面上拉返回效果

先上效果圖:


bossDemo錄屏.gif

代碼地址:https://github.com/huisaziru/BossHireDemo

最近正在找工作,然后用Boss直聘這個(gè)軟件試了下,發(fā)現(xiàn)招聘詳情頁面上拉挺有意思的,很容易被迷惑;上拉時(shí),拉到底再往上拉時(shí)能看到首頁的view,而且滾動(dòng)條好像是在下面那個(gè)view上;

一開始以為上面那個(gè)只是一個(gè)tableview添加在首頁的那個(gè)view上,后面發(fā)現(xiàn)下面那個(gè)tabbarcontroller縮小了,并且返回的時(shí)候,和dissmiss一樣,基本確定是首頁present出來這個(gè)詳情頁;

分析上拉返回實(shí)現(xiàn)

詳情頁有一個(gè)tableview,tableview需要加在scrollview上,scrollview是橫向滾動(dòng),用來獲取其他招聘詳情;
要實(shí)現(xiàn)這個(gè)效果,以下條件可以滿足:

  • scrollview在拖動(dòng)的時(shí)候是透明,不拖動(dòng)時(shí)為不透明,因?yàn)樾枰獧M向滾動(dòng)
  • tableview什么時(shí)候都透明,拉到底再往上拉的時(shí)候,如果不透明,就會(huì)出現(xiàn)tableview的背景色,就擋住了下面;
  • menuview是和tableview同一級(jí),一開始是不透明的,需要一個(gè)containerview包含它們,然后containerview加在scrollview上;因?yàn)閠ableview動(dòng)的時(shí)候menuview不動(dòng),拉到底再往上拉時(shí)候才跟著動(dòng);所以menuview不在tableview上;

看上去這些就能實(shí)現(xiàn)這個(gè)功能,但是有個(gè)細(xì)節(jié)很重要,就是滾動(dòng)條滾到menuview下面的時(shí)候,只有滾動(dòng)條透過menuview

當(dāng)時(shí)看到這個(gè)效果的時(shí)候有點(diǎn)懵,為什么只有滾動(dòng)條可以透過menuview;按理講要透明的話,應(yīng)該全部都會(huì)透過去,看得到下面;這個(gè)是最難的地方;

后面想到了局部透明,隨著往上拉,menuview慢慢的從上往下透明,剛好讓進(jìn)來的滾動(dòng)條透出來,但是有個(gè)問題:透明出來的部分還是會(huì)把下面的東西透出來,不單單只透明滾動(dòng)條;

這時(shí)我想到找一個(gè)背景view放在menuview局部透明位置的底下,讓上面的透明區(qū)域被下面擋?。贿@里注意不能是menuview大小,要不然擋住了下面,但是這時(shí)會(huì)將滾動(dòng)條擋住,真是糾結(jié);

現(xiàn)在的問題是:底下的那個(gè)背景view怎么不擋住滾動(dòng)條?

分析:滾動(dòng)條是在tableview 上面的,所以可以從tableview入手,將背景view加到tableview底部:contentsize底部下面--因?yàn)橹挥欣降走@個(gè)背景view才能出來;

驗(yàn)證一下:當(dāng)拉倒底,再往上拉時(shí),menuview慢慢透出上面,這時(shí)候背景view慢慢出來,剛好擋住透明部分,這時(shí)滾動(dòng)條被menuview可以透過;到這里基本宣告成功!

menuview透出來

還有一個(gè)點(diǎn)沒說:就是menuview怎么慢慢透出來,我想的辦法是,menuview底下有一個(gè)白色不透明的maskview,上面就是放按鈕的containerView,這個(gè)view的背景顏色帶透明;

  • 初始狀態(tài):上面透明部分被下面maskview擋住
  • 拉到底往上拉時(shí):maskview的y慢慢變大,高變成maskview.height - y,這樣就能將上面的containerView慢慢透出來
  • 當(dāng)maskview的y等于maskview.height時(shí),等于全透了,這時(shí)tableview的背景view剛好全出來了,完全擋住menu view;

我發(fā)現(xiàn)Boss直聘有一個(gè)bug,正是這個(gè)bug論證了我的猜想;當(dāng)拉到底時(shí),再往上拉一段距離,這時(shí)快速拉下來,神奇的現(xiàn)象就發(fā)生了:menuview已經(jīng)不在底下了,最重要的是,它上部分是透明的,可以透過看到tableview的字;這個(gè)bug很好解決,就是突然下來導(dǎo)致的,沒有過渡,只需在當(dāng)前offset沒有到底的時(shí),將menuview的坐標(biāo)復(fù)原就可以;

到這里終于是搞定了?。?!


以下是上面主要的實(shí)現(xiàn)代碼

背景view:這里要注意的是,因?yàn)閎oss直聘的詳情頁支持scrollview切換,這里只用一個(gè)tableview,當(dāng)數(shù)據(jù)變化時(shí),contentsize就會(huì)變,這時(shí)候需要更新背景view的frame,這里用kvo檢測(cè)tableview的content size就可以實(shí)現(xiàn)這個(gè);

    //tableFooterBackGroundView作用:當(dāng)tableview拉到底,再往上拉時(shí),menuview 慢慢透出來的部分,如果底下沒有view,會(huì)看到下面,所以添加此view,位置在tableview底部下面
    self.tableFooterBackGroundView = [[UIView alloc] initWithFrame:CGRectMake(0, self.tableView.contentSize.height, frame.size.width, MenuHeight)];
    self.tableFooterBackGroundView.backgroundColor = [UIColor whiteColor];
    [self.tableView addSubview:self.tableFooterBackGroundView];
    
    // 對(duì)tableView的contentSize 進(jìn)行kvo,因?yàn)槊看握?qǐng)求的數(shù)據(jù)不一樣,conentSize不一樣,更新tableFootBackGroundView的top
    [self.tableView addObserver:self forKeyPath:@"contentSize" options:NSKeyValueObservingOptionNew context:nil];

menuview:

/** 菜單view,和tableview同一級(jí)*/
- (UIView *)createMenuView:(CGRect)frame {
    UIView *containerView = [[UIView alloc] initWithFrame:frame];
    
    //遮罩view的作用:tableview上升時(shí),遮罩view慢慢變小,讓menuview透出來 tableFooterBackGroundView慢慢出來,剛好擋住了透明的部分,滾動(dòng)條在tableview之上,所以可以透過menuview
    self.contentMenuMaskView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)];
    self.contentMenuMaskView.backgroundColor = [UIColor whiteColor];
    [containerView addSubview:self.contentMenuMaskView];
    
    UIView *menuView = [[[NSBundle mainBundle] loadNibNamed:@"MenuView" owner:self options:nil] firstObject];
    menuView.frame = CGRectMake(0, 0, frame.size.width, frame.size.height);
    menuView.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0.8];
    [containerView addSubview:menuView];
    
    return containerView;
}

滾動(dòng)處理:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    if (scrollView.contentSize.height > 0 && scrollView.tag == 0) {//拉到底
        if (scrollView.contentOffset.y + scrollView.height > scrollView.contentSize.height) {
            self.scrollView.backgroundColor = [UIColor clearColor];
            CGFloat dy = scrollView.contentOffset.y + scrollView.height - scrollView.contentSize.height;
            self.contentMenuView.y = self.view.height - self.contentMenuView.height - dy;
            if (dy <= self.contentMenuView.height) {
                self.contentMenuMaskView.y = dy;
                self.contentMenuMaskView.height = self.contentMenuView.height - dy;
            } else {
                //防止menuview上升一部分后突然往上拉,上升高度大于menuview的高度,height還沒變成0,所以需要設(shè)成0;
                if (self.contentMenuMaskView.height != 0) {
                    self.contentMenuMaskView.height = 0;
                }
            }

        } else {
            self.scrollView.backgroundColor = [UIColor groupTableViewBackgroundColor];
            //這個(gè)是boss直聘的bug
            //防止從底下往上拉時(shí),突然一下下來,因?yàn)闆]有過渡,所以contentMenuView的坐標(biāo)還在上面,所以需要重置下
            CGFloat originContentMenuY = self.view.height - self.contentMenuView.height;
            if (self.contentMenuView.y != originContentMenuY) {
                self.contentMenuView.y = originContentMenuY;
                self.contentMenuMaskView.y = 0;
                self.contentMenuMaskView.height = self.contentMenuView.height;
            }
        }
        
    }
}

這個(gè)demo還有一些比如

  • UIViewControllerAnimatedTransitioning的用法,用來定制轉(zhuǎn)場(chǎng)效果,實(shí)現(xiàn)demo中縮小tabbarcontroller的效果;
  • 還有一些keyframe動(dòng)畫,組合動(dòng)畫的應(yīng)用;
  • 還有scrollview的用法,只用一個(gè)tableview進(jìn)行切換;

以上這些就不在這里講了,可以直接看代碼,注釋很詳細(xì);

如果覺得寫的還可以,幫忙star一下,謝謝~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,639評(píng)論 4 61
  • 丁小強(qiáng)閱讀 184評(píng)論 0 0
  • 1.每個(gè)網(wǎng)站的請(qǐng)求數(shù)據(jù)的格式基本一致,不可能一會(huì)json格式,一會(huì)xml格式。所以可以通過這點(diǎn)固定每個(gè)爬蟲的請(qǐng)求格...
    薛云龍閱讀 216評(píng)論 0 0
  • 突然想去一個(gè)陌生的地方。誰也不認(rèn)識(shí)誰。一切空白。如果可以放下所有包袱。所有人都是新面孔。依然可以懵懂無知,帶著好奇...
    趕風(fēng)閱讀 362評(píng)論 0 0
  • 感覺全都是變量,實(shí)驗(yàn)陷入泥潭。抓不住主要矛盾。 勸自己要有耐心,相信沒有解決不了的問題。
    ritaxqzhang閱讀 215評(píng)論 0 0

友情鏈接更多精彩內(nèi)容