仿淘寶上拉進(jìn)入詳情頁交互的實(shí)現(xiàn)

前言

項(xiàng)目某個新需求的交互要求仿照淘寶上拉從下網(wǎng)上彈出寶貝詳情。今天打開淘寶APP仔細(xì)看了看截粗,然后自己寫了寫信姓,現(xiàn)在感覺效果差不多了,記錄一下绸罗。


分析

可以看到意推,該頁面是分為兩部分的,一部分是一開始就能看到的商品信息珊蟀,然后我們上拉屏幕菊值,屏幕不斷往上滾動,滾動到第一部分結(jié)束時可以看到底部有“繼續(xù)拖動育灸,查看圖文詳情”一行文本出現(xiàn)腻窒。繼續(xù)上拉到一個臨界點(diǎn)便觸發(fā)了翻頁,此時第二部分以動畫的形式從底部涌出占滿整個屏幕描扯。而且效果是該頁面整體上移了定页,即第一部分和第二部分都是上移的。
此時绽诚,第二部分占滿著整個屏幕典徊,若我們下拉屏幕,則在屏幕頂部淡出“下拉恩够,返回寶貝詳情”的文本提示卒落,并且達(dá)到一個臨界值后文本變?yōu)椤搬尫牛祷貙氊愒斍椤狈渫埃藭r松開手指儡毕,頁面又滾動到第一部分的尾部。

taobao.gif

實(shí)現(xiàn)

在自己寫的demo中扑媚,第一部分是個tableView腰湾,展示商品基本信息。第二部分是個webView疆股,展示商品圖文詳情费坊。
第一步首先加載需要的視圖。主要是第一部分的tableView和第二部分的webView旬痹,還有第二部分頂部顯示上拉返回文本提示的headLab附井。為了節(jié)省資源讨越,其實(shí)可以在上拉觸發(fā)時再加載第二部分視圖的,但是這里僅作示例永毅,所以并沒有懶加載把跨。

- (void)loadContentView
{
    // first view
    [self.contentView addSubview:self.tableView];
    
    // second view
    [self.contentView addSubview:self.webView];
    
    UILabel *hv = self.headLab;
    // headLab
    [self.webView addSubview:hv];
    [self.headLab bringSubviewToFront:self.contentView];
}


- (UILabel *)headLab
{
    if(!_headLab){
        _headLab = [[UILabel alloc] init];
        _headLab.text = @"上拉,返回詳情";
        _headLab.textAlignment = NSTextAlignmentCenter;
        _headLab.font = FONT(13);
        
    }
    
    _headLab.frame = CGRectMake(0, 0, PDWidth_mainScreen, 40.f);
    _headLab.alpha = 0.f;
    _headLab.textColor = PDColor_button_Gray;

    
    return _headLab;
}


- (UITableView *)tableView
{
    if(!_tableView){
        _tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, PDWidth_mainScreen, self.contentView.bounds.size.height) style:UITableViewStylePlain];
        //    _tableView.contentSize = CGSizeMake(PDWidth_mainScreen, 800);
        _tableView.dataSource = self;
        _tableView.delegate = self;
        _tableView.rowHeight = 40.f;
        UILabel *tabFootLab = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, PDWidth_mainScreen, 60)];
        tabFootLab.text = @"繼續(xù)拖動沼死,查看圖文詳情";
        tabFootLab.font = FONT(13);
        tabFootLab.textAlignment = NSTextAlignmentCenter;
//        tabFootLab.backgroundColor = PDColor_Orange;
        _tableView.tableFooterView = tabFootLab;
    }
    
    return _tableView;
}


- (UIWebView *)webView
{
    if(!_webView){
        _webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, _tableView.contentSize.height, PDWidth_mainScreen, PDHeight_mainScreen)];
        _webView.delegate = self;
        _webView.scrollView.delegate = self;
        [_webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"https://www.baidu.com"]]];
    }
    
    return _webView;
}

然后實(shí)現(xiàn)滾動視圖UIScrollView的代理方法着逐,在里面完成滾動到達(dá)臨界值后,觸發(fā)翻頁動畫的處理漫雕。包括了上拉翻到第二頁和下拉翻回第一頁兩部分滨嘱,即要在該方法里通過判斷scrollView的類型做相應(yīng)的處理。

#pragma mark ---- scrollView delegate

-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
    CGFloat offsetY = scrollView.contentOffset.y;
    
    if([scrollView isKindOfClass:[UITableView class]]) // tableView界面上的滾動
    {
        // 能觸發(fā)翻頁的理想值:tableView整體的高度減去屏幕本省的高度
        CGFloat valueNum = _tableView.contentSize.height -PDHeight_mainScreen;
        if ((offsetY - valueNum) > _maxContentOffSet_Y)
        {
            [self goToDetailAnimation]; // 進(jìn)入圖文詳情的動畫
        }
    }
    
    else // webView頁面上的滾動
    {
        NSLog(@"-----webView-------");
        if(offsetY<0 && -offsetY>_maxContentOffSet_Y)
        {
            [self backToFirstPageAnimation]; // 返回基本詳情界面的動畫
        }
    }
}

再看看兩個翻頁的動畫浸间,其實(shí)很簡單太雨,就是移動它們的位置。

// 進(jìn)入詳情的動畫
- (void)goToDetailAnimation
{
    [UIView animateWithDuration:0.3 delay:0.0 options:UIViewAnimationOptionLayoutSubviews animations:^{
        _webView.frame = CGRectMake(0, 0, PDWidth_mainScreen, PDHeight_mainScreen);
        _tableView.frame = CGRectMake(0, -self.contentView.bounds.size.height, PDWidth_mainScreen, self.contentView.bounds.size.height);
    } completion:^(BOOL finished) {
        
    }];
}


// 返回第一個界面的動畫
- (void)backToFirstPageAnimation
{
    [UIView animateWithDuration:0.3 delay:0.0 options:UIViewAnimationOptionLayoutSubviews animations:^{
        _tableView.frame = CGRectMake(0, 0, PDWidth_mainScreen, self.contentView.bounds.size.height);
        _webView.frame = CGRectMake(0, _tableView.contentSize.height, PDWidth_mainScreen, PDHeight_mainScreen);
        
    } completion:^(BOOL finished) {
        
    }];
}

然后還有個在第二頁下拉時屏幕頂部的文本提示的動畫呢魁蒜。這個我我們通過KVO來監(jiān)聽webViewscrollView的偏移量囊扳,只要其偏移量發(fā)生變化,便會實(shí)時執(zhí)行KVO的代理方法兜看,然后我們在方法內(nèi)根據(jù)其偏移量的變動完成動畫即可(隨著偏移量變大字體變得非透明锥咸,達(dá)到某個臨界點(diǎn)后,字體變?yōu)榧t色细移,文本內(nèi)容也變?yōu)椤搬尫挪瑁祷卦斍椤保?/p>

開始監(jiān)聽webView滾動的偏移量

    // 開始監(jiān)聽_webView.scrollView的偏移量
    [_webView.scrollView addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];

在KVO的代理方法里,根據(jù)偏移量完成提示文本的動畫

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
{
    if(object == _webView.scrollView && [keyPath isEqualToString:@"contentOffset"])
    {
        NSLog(@"----old:%@----new:%@",change[@"old"],change[@"new"]);
        [self headLabAnimation:[change[@"new"] CGPointValue].y];
    }else
    {
        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
    }
    
}

提示文本的動畫的實(shí)現(xiàn)代碼:

// 頭部提示文本動畫
- (void)headLabAnimation:(CGFloat)offsetY
{
    _headLab.alpha = -offsetY/60;
    _headLab.center = CGPointMake(PDWidth_mainScreen/2, -offsetY/2.f);
    // 圖標(biāo)翻轉(zhuǎn)弧轧,表示已超過臨界值雪侥,松手就會返回上頁
    if(-offsetY>_maxContentOffSet_Y){
        _headLab.textColor = [UIColor redColor];
        _headLab.text = @"釋放,返回詳情";
    }else{
        _headLab.textColor = PDColor_button_Gray;
        _headLab.text = @"上拉精绎,返回詳情";
    }
}

demo的最終效果:

taobaoDemo.gif
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末速缨,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子代乃,更是在濱河造成了極大的恐慌旬牲,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件搁吓,死亡現(xiàn)場離奇詭異原茅,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)堕仔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進(jìn)店門擂橘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人贮预,你說我怎么就攤上這事贝室。” “怎么了仿吞?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵滑频,是天一觀的道長。 經(jīng)常有香客問我唤冈,道長峡迷,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任你虹,我火速辦了婚禮绘搞,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘傅物。我一直安慰自己夯辖,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布董饰。 她就那樣靜靜地躺著蒿褂,像睡著了一般。 火紅的嫁衣襯著肌膚如雪卒暂。 梳的紋絲不亂的頭發(fā)上啄栓,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天,我揣著相機(jī)與錄音也祠,去河邊找鬼昙楚。 笑死,一個胖子當(dāng)著我的面吹牛诈嘿,可吹牛的內(nèi)容都是我干的堪旧。 我是一名探鬼主播,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼永淌,長吁一口氣:“原來是場噩夢啊……” “哼崎场!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起遂蛀,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤谭跨,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后李滴,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體螃宙,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年所坯,在試婚紗的時候發(fā)現(xiàn)自己被綠了谆扎。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡芹助,死狀恐怖堂湖,靈堂內(nèi)的尸體忽然破棺而出闲先,到底是詐尸還是另有隱情,我是刑警寧澤无蜂,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布伺糠,位于F島的核電站,受9級特大地震影響斥季,放射性物質(zhì)發(fā)生泄漏训桶。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一酣倾、第九天 我趴在偏房一處隱蔽的房頂上張望舵揭。 院中可真熱鬧,春花似錦躁锡、人聲如沸午绳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽箱叁。三九已至,卻和暖如春惕医,著一層夾襖步出監(jiān)牢的瞬間耕漱,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工抬伺, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留螟够,地道東北人。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓峡钓,卻偏偏與公主長得像妓笙,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子能岩,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評論 2 348

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