白酒清茶无别事
我在等风也等你

iOS新闻资讯/订单等包含多个TableView页面的优化

最近一个项目,因为有商城和资讯,所以肯定有页面包含多个tableview,左右滑动展示的

类似今日头条的资讯导航

那今天就来看看怎么去优化,复用这个tableview

大佬看到勿笑哈,我也就瞎写写。

GIF抖动有点厉害,凑合看,嘿嘿。

我先说下需求吧,

头部导航栏根据后台返回数据加载多少个

然后底下就是嵌套的tableview展示的内容了

我主要使用2个tableview,分页展示不同的数据,下面就简单说逻辑吧

页面搭建

  1. 顶部导航栏直接自定义View,根据传进来的数据个数,去创建多少个按钮
  2. 中间底层是一个scrollview,然后根据后台返回数据创建scrollview的contentSize的宽度。
  3. 然后for循环,创建两个tableview,放在一个数组里面
  4. 根据当前点击或者滑动的页面标签除以2取余数,在根据余数从上面的数组里面取tableview展示在主界面并刷新数据

大致逻辑就是我上面说的几点,其中比较重要的就是几个页面的数据和当前页面page的存取刷新

@interface HotViewController ()<UITableViewDelegate,UITableViewDataSource,UIScrollViewDelegate>
{
NSInteger _itemCount;//顶部导航栏item总个数,主要在懒加载的时候设置scrollview的内容宽度
NSArray *_indexArray;//这个是存储导航栏对应的model数据,用来获取不同类型数据
NSInteger currentIndex;//当前页面的标签,例如是0,1,2等
NSInteger _currentPage;//当前页面数据的当前page,比如第三个页面的当前page和第一个都不一样
NSArray *_currentArray;//当前请求的数据,用来判断是否加载到最后一个,或者当前类型没有数据,加载空视图
}
@property (nonatomic ,strong)UIScrollView *scrollview;
@property (nonatomic ,strong)NSMutableArray *dataSource;//存储不同页面的不同数据,也就是这个数组包含了多个页面数据(数组包含数组)
@property (nonatomic ,strong)NSMutableArray *pageArray;//专门用来装不同页面的当前page(数组包含int对象)
@property (nonatomic ,strong)CategoryItemsControllView *itemView;//顶部自定义导航栏
@property (nonatomic ,strong)NSMutableArray *tableviewArray;//存储for循环创建的2个tableview
@property (nonatomic ,strong)UIView *defaultView;//无数据加载的空视图
@end

这是整个声明的属性情况,有点乱,不过我看多了,习惯了,有大佬有好点的建议可以提出来,我尝试修改下。

//根据返回的数据,for循环创建tableview和page,page默认=1,后台从的page是从1开始的。算初始化页面吧。

    for (int i = 0; i < array.count; i++) {

        NSInteger page = 1;

        [self.pageArray addObject:@(page)];

        NSMutableArray *temArray = @[].mutableCopy;

        [self.dataSource addObject:temArray];

    }

下面就是创建两个tableview,存在数组里面,以及配置下tableview数据,设置代理啊

for (int i = 0; i < 2; i++) {

        UITableView *tableview = [[UITableView alloc] initWithFrame:CGRectMake(i * WidthOfScreen, 0, WidthOfScreen, self.scrollview.frame.size.height) style:UITableViewStylePlain];

        tableview.backgroundColor = CellDeafultColor;

        tableview.showsVerticalScrollIndicator = NO;

        tableview.separatorStyle = UITableViewCellSeparatorStyleNone;

        tableview.delegate = self;

        tableview.dataSource = self;

        WEAK

        [MethodTools footerRefreshWithTableView:tableview completion:^{

            //加载更多

            STRONG

            [self loadMoreData];

        }];

        [MethodTools headerRefreshWithTableView:tableview withAnimation:YES completion:^{

            //下拉刷新

            STRONG

            [self getNewData];

        }];

        [self.tableviewArray addObject:tableview];

        [self.scrollview addSubview:tableview];

    }

下面就是数据请求和处理数据,也还算简单的

//网络请求,包含了一个刷新状态, RefreshState: HeaderRefresh,FooterRefresh,NoHeaderFooter,方便获得数据之后结束刷新。

- (void)getArticleListDataWithIndex:(NSString *)index WithState:(RefreshState)state{

    NSLog(@"*****currentPage = %ld",_currentPage);

    NSString *user_id =@"";

    if ([UD objectForKey:@"member_info"]) {

        user_id = [UD objectForKey:@"member_info"][@"user_id"];

    }

    NSString *url = [NSString stringWithFormat:@"%@?&page=%@&id=%@&user_id=%@",ARTICLELIST,@(_currentPage),index,user_id];

    NSLog(@"***url = %@",url);

    [[GLHttpManager ShareManage] GetRequestURL:url

                                        params:nil

                                       success:^(id data) {

                                           //YYModel 解析数据

                                           NSArray *modelArray =[NSArray yy_modelArrayWithClass:[HotListModel class] json:data[@"data"]];

                                           //处理获得的数据数组

                                           [self handelModelArrayWithArray:modelArray WithIndex:[index integerValue] WithState:state];

                                       }

                                          fail:^(NSError *error) {

                                          }];

}

- (void)handelModelArrayWithArray:(NSArray *)array WithIndex:(NSInteger)index WithState:(RefreshState)state{

    _currentArray = array;//主要在刷新标的时候,选择结束状态,是endRefreshing,还是endRefreshingWithNoMoreData

    NSMutableArray *temDataArray = self.dataSource[currentIndex];

    //如果是下拉刷新,清空当前页面数组的model。

    if (state == HeaderRefresh) {

        [temDataArray removeAllObjects];

    }

    //判断请求的数据是否为空,不为空正常处理

    if (array.count > 0) {

        _currentPage++;//当前页面的page+1

        [array enumerateObjectsUsingBlock:^(HotListModel *model, NSUInteger idx, BOOL * _Nonnull stop) {

            [temDataArray addObject:model];

        }];

        //更新对应位置的数据数组

        [self.dataSource replaceObjectAtIndex:currentIndex withObject:temDataArray];

        //更新对应位置的页面page

        [self.pageArray replaceObjectAtIndex:currentIndex withObject:@(_currentPage)];

        //更新tableview的位置,并刷新tableview

        [self updateTableWithPageNumber:currentIndex WithState:state];

    }

}

下面这个是在请求数据结束,更新tableview位置

#pragma mark --根据scrollView的滚动位置复用tableView,减少内存开支

-(void) updateTableWithPageNumber: (NSUInteger) pageNumber WithState:(RefreshState)state{

    int tabviewTag = pageNumber % 2;

    CGRect tableviewNewFrame = CGRectMake(pageNumber * WidthOfScreen, 0, WidthOfScreen, self.scrollview.frame.size.height);

    UITableView *reusetableView = self.tableviewArray[tabviewTag];

    reusetableView.frame = tableviewNewFrame;

    if (state == 0) {

        [reusetableView.mj_header endRefreshing];

    }else if (state == 1){

        if (_currentArray.count > 0) {

            [reusetableView.mj_footer endRefreshing];

        }else{

            [reusetableView.mj_footer endRefreshingWithNoMoreData];

        }

    }else{

    }

    [reusetableView reloadData];

}

以及下面这个优化,就是没数据的时候,再去请求数据,有数据就不去请求,除非用户上拉,或者下拉了再去请求

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView

{

    if (scrollView == self.scrollview) {

        float offset = scrollView.contentOffset.x;

        offset = offset/CGRectGetWidth(scrollView.frame);

        [_itemView endMoveToIndex:offset];

        //根据滑动偏移量,计算出当前是第几个tableview

        currentIndex = scrollView.contentOffset.x/WidthOfScreen ;

        NSLog(@"self.dataSource.count - currentIndex = %ld",self.dataSource.count - currentIndex);

        //这个地方是为了优化的,当当前tableview有数据的时候,切换到它的时候,不在请求数据,当没有数据的时候,再去请求新数据

        if (self.dataSource.count - currentIndex == 0) {

            _currentPage = 1;

            [self getArticleListDataWithIndex:_indexArray[currentIndex][@"type_id"] WithState:NoHeaderFooter];

        }else{

            if ([self.dataSource[currentIndex] count] > 0) {

                [self updateTableWithPageNumber:currentIndex WithState:NoHeaderFooter];

            }else{

                _currentPage = [self.pageArray[currentIndex] integerValue];

                [self getArticleListDataWithIndex:_indexArray[currentIndex][@"type_id"] WithState:NoHeaderFooter];

            }

        }

    }

}

别的地方就没啥重要的了,就不贴出来了,反正大致逻辑是这样的,有大佬有好的方法可以提出来,小弟想学习学习,嘿嘿,别吝啬哈

赞(0) 打赏
未经允许不得转载:十一同学 » iOS新闻资讯/订单等包含多个TableView页面的优化
分享到: 更多 (0)

评论 3

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
  1. #1

    有demo吗?

    WenJim10个月前 (09-06)回复
    • 这个是当时做项目记录的,没有单独写demo。

      十一10个月前 (09-07)回复
      • 额,刚好我也需要用到这个效果,但是自己写的和网上找的多多少少都有点BUG,然后看到你这个效果感觉没有问题,所以想看一下demo,不过没有那就有点麻烦了,能单独把这2个类抽出来吗?

        Wenjim10个月前 (09-10)回复

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏