UITableview嵌套UITableView案例實踐(仿淘寶商品詳情頁實現(xiàn))

一妻导、案例演示

IOS中提供的UITableView功能非常強大嗤瞎,section提供分組山橄,cell提供顯示垮媒,幾乎可以應(yīng)付絕大部分場景。最近想模仿舊版的淘寶的商品詳情頁(最新的淘寶詳情頁商品詳情和圖文詳情是兩個頁面)寫一個Demo航棱,后來發(fā)現(xiàn)單純使用UITableView來布局是比較困難的睡雇。因為舊版的淘寶詳情頁中,最外層的View肯定是一個UITableView饮醇,但是內(nèi)層的Tab中它抱,圖文介紹、商品詳情和評價三個Tab對應(yīng)的內(nèi)容非常豐富朴艰,如果你把這三塊內(nèi)容放在一個section中的話观蓄,將導(dǎo)致數(shù)據(jù)組織非常困難,并且UI的靈活度也大大降低祠墅。所以最后準(zhǔn)備嘗試使用UITableView嵌套UITableView的方式來組織UI侮穿,最外層是一個UITableView,三個Tab其實是一個橫向ScrollView,這個ScrollView里面包含三個UITableView毁嗦。并且Tab中的內(nèi)容采用動態(tài)可配置話的方式生成(下面詳解)亲茅。實現(xiàn)的效果如下:

仿造淘寶詳情頁

二、項目詳解

2.1狗准、大體思路

使內(nèi)層的UITableView(TAB欄里面)和外層的UITableView同時響應(yīng)用戶的手勢滑動事件克锣。當(dāng)用戶從頁面頂端從下往上滑動到TAB欄的過程中,使外層的UITableView跟隨用戶手勢滑動腔长,內(nèi)層的UITableView不跟隨手勢滑動袭祟。當(dāng)用戶繼續(xù)往上滑動的時候,讓外層的UITableView不跟隨手勢滑動饼酿,讓內(nèi)層的UITableView跟隨手勢滑動榕酒。反之從下往上滑動也一樣。

如上圖所示故俐,外層的section0為價格區(qū)想鹰,可以自定義。section1為sku區(qū)药版,也可以自定義辑舷。section2為TAB區(qū)域,該區(qū)域采用Runtime反射機制槽片,動態(tài)配置完成何缓。

2.2肢础、具體實現(xiàn)

2.2.1、YXIgnoreHeaderTouchTableView

我們頂部的圖片其實是覆蓋在外層UITableView的tableHeaderView的下面碌廓,我們把tableHeaderView設(shè)置為透明传轰。這樣實現(xiàn)是為了方便我們在滑動的時候,動態(tài)的改變圖片的寬高谷婆,實現(xiàn)列表頭部能夠動態(tài)拉伸的效果慨蛙。但是我們對于UITableView不做處理的時候,該圖片是無法響應(yīng)點擊事件的纪挎,因為被tableHeaderView提前消費了期贫。所以我們要不讓tableHeaderView不響應(yīng)點擊事件。我們在YXIgnoreHeaderTouchTableView的實現(xiàn)文件中重寫以下方法异袄。

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    if (self.tableHeaderView && CGRectContainsPoint(self.tableHeaderView.frame, point)) {
        return NO;
    }
    return [super pointInside:point withEvent:event];
}

2.2.2通砍、 YXIgnoreHeaderTouchAndRecognizeSimultaneousTableView

該文件繼承于YXIgnoreHeaderTouchTableView,除此之外烤蜕,主要是為了讓外層的UITableView能夠顯示外層UITableView的滑動事件封孙。我們需要實現(xiàn)以下代理方法。

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    return YES;
}

2.2.3玖绿、YXTabView

該文件是TAB區(qū)域主文件敛瓷,顯示的標(biāo)題的內(nèi)容都是通過以下字典動態(tài)生成。

if(section==2){
        NSArray *tabConfigArray = @[@{
            @"title":@"圖文介紹",
            @"view":@"PicAndTextIntroduceView",
            @"data":@"圖文介紹的數(shù)據(jù)",
            @"position":@0
        },@{
            @"title":@"商品詳情",
            @"view":@"ItemDetailView",
            @"data":@"商品詳情的數(shù)據(jù)",
            @"position":@1
        },@{
            @"title":@"評價(273)",
            @"view":@"CommentView",
            @"data":@"評價的數(shù)據(jù)",
            @"position":@2
        }];
        YXTabView *tabView = [[YXTabView alloc] initWithTabConfigArray:tabConfigArray];
        [cell.contentView addSubview:tabView];
}

title:TAB每個Item的標(biāo)題斑匪。

view:TAB每個Item的內(nèi)容呐籽。

data:TAB每個Item內(nèi)容渲染需要的數(shù)據(jù)。

position:TAB的位置蚀瘸。從0開始狡蝶。

該TAB其實是有YXTabTitleView(標(biāo)題欄)和一個橫向的ScrollView(內(nèi)層多個UITableView的容器)構(gòu)成。內(nèi)層多個UITableView通過以上配置文件動態(tài)生成贮勃。如下如示:

for (int i=0; i<tabConfigArray.count; i++) {
     NSDictionary *info = tabConfigArray[i];
     NSString *clazzName = info[@"view"];
     Class clazz = NSClassFromString(clazzName);
     YXTabItemBaseView *itemBaseView = [[clazz alloc] init];
     [itemBaseView renderUIWithInfo:tabConfigArray[i]];
     [_tabContentView addSubview:itemBaseView];
}

2.2.4贪惹、YXTabItemBaseView

該文件是內(nèi)層UITableView都應(yīng)該繼承的BaseView,在該View中我們設(shè)置了內(nèi)層UITableView具體在什么時機不響應(yīng)用戶滑動事件寂嘉,什么時機應(yīng)該響應(yīng)用戶滑動事件奏瞬,什么時間通知外層UITableView響應(yīng)滑動事件等等功能。

- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
    if (!self.canScroll) {
        [scrollView setContentOffset:CGPointZero];
    }
    CGFloat offsetY = scrollView.contentOffset.y;
    if (offsetY<0) {
        [[NSNotificationCenter defaultCenter] postNotificationName:kLeaveTopNotificationName object:nil userInfo:@{@"canScroll":@"1"}];
        [scrollView setContentOffset:CGPointZero];
        self.canScroll = NO;
        self.tableView.showsVerticalScrollIndicator = NO;
    }
}

2.2.5泉孩、PicAndTextIntroduceView硼端、ItemDetailView、CommentView

這三個文件都繼承于YXTabItemBaseView寓搬,但是在該文件中我們只需要注意UI的渲染就可以了珍昨。響應(yīng)事件的管理都在YXTabItemBaseView做好了。

就拿PicAndTextIntroduceView.m來看,基本上都是UI代碼:

@implementation PicAndTextIntroduceView

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return 30;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    return 50.;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    static NSString *cellId = @"cellId";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];
    if (!cell) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId];
    }
    cell.textLabel.text = self.info[@"data"];
    return cell;
}

@end

2.2.6、內(nèi)外層滑動事件的響應(yīng)和傳遞

外層UITableView在初始化的時候 需要監(jiān)聽一個NSNotification镣典,該通知是內(nèi)層UITableView傳遞給外層的兔毙,傳遞時機為從上往下活動,當(dāng)TAB欄取消置頂?shù)臅r候兄春。通知外層UITableView可以開始滾動了澎剥。

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(acceptMsg:) name:kLeaveTopNotificationName object:nil];

-(void)acceptMsg : (NSNotification *)notification{
    //NSLog(@"%@",notification);
    NSDictionary *userInfo = notification.userInfo;
    NSString *canScroll = userInfo[@"canScroll"];
    if ([canScroll isEqualToString:@"1"]) {
        _canScroll = YES;
    }
}

在scrollViewDidScroll方法中,需要實時監(jiān)控外層UItableView的滑動時機赶舆。也要在適當(dāng)時機發(fā)送NSNotification給內(nèi)層UItableView肴裙,通知內(nèi)層UITableView是否可以滑動。

-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
    CGFloat tabOffsetY = [_tableView rectForSection:2].origin.y-kTopBarHeight;
    CGFloat offsetY = scrollView.contentOffset.y;
    _isTopIsCanNotMoveTabViewPre = _isTopIsCanNotMoveTabView;
    if (offsetY>=tabOffsetY) {
        scrollView.contentOffset = CGPointMake(0, tabOffsetY);
        _isTopIsCanNotMoveTabView = YES;
    }else{
        _isTopIsCanNotMoveTabView = NO;
    }
    if (_isTopIsCanNotMoveTabView != _isTopIsCanNotMoveTabViewPre) {
        if (!_isTopIsCanNotMoveTabViewPre && _isTopIsCanNotMoveTabView) {
            //NSLog(@"滑動到頂端");
            [[NSNotificationCenter defaultCenter] postNotificationName:kGoTopNotificationName object:nil userInfo:@{@"canScroll":@"1"}];
            _canScroll = NO;
        }
        if(_isTopIsCanNotMoveTabViewPre && !_isTopIsCanNotMoveTabView){
            //NSLog(@"離開頂端");
            if (!_canScroll) {
                scrollView.contentOffset = CGPointMake(0, tabOffsetY);
            }
        }
    }
}

三涌乳、完整源碼下載地址

github下載地址:https://github.com/yixiangboy/YX_UITableView_IN_UITableView
如果對你有用,star一下吧甜癞。

四夕晓、聯(lián)系方式

新浪微博
github
簡書首頁

歡迎加好友、一起交流悠咱。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蒸辆,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子析既,更是在濱河造成了極大的恐慌躬贡,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件眼坏,死亡現(xiàn)場離奇詭異拂玻,居然都是意外死亡,警方通過查閱死者的電腦和手機宰译,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進店門檐蚜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人沿侈,你說我怎么就攤上這事闯第。” “怎么了缀拭?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵咳短,是天一觀的道長。 經(jīng)常有香客問我蛛淋,道長咙好,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任铣鹏,我火速辦了婚禮敷扫,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己葵第,他們只是感情好绘迁,可當(dāng)我...
    茶點故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著卒密,像睡著了一般缀台。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上哮奇,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天膛腐,我揣著相機與錄音,去河邊找鬼鼎俘。 笑死哲身,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的贸伐。 我是一名探鬼主播勘天,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼捉邢!你這毒婦竟也來了脯丝?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤伏伐,失蹤者是張志新(化名)和其女友劉穎宠进,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體藐翎,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡材蹬,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了吝镣。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片赚导。...
    茶點故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖赤惊,靈堂內(nèi)的尸體忽然破棺而出吼旧,到底是詐尸還是另有隱情,我是刑警寧澤未舟,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布圈暗,位于F島的核電站,受9級特大地震影響裕膀,放射性物質(zhì)發(fā)生泄漏墓阀。R本人自食惡果不足惜脖咐,卻給世界環(huán)境...
    茶點故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧臣淤,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至毅厚,卻和暖如春塞颁,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背吸耿。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工祠锣, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人咽安。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓伴网,卻偏偏與公主長得像,于是被迫代替她去往敵國和親妆棒。 傳聞我的和親對象是個殘疾皇子是偷,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,592評論 2 353

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