iOS開發之多表視圖滑動切換示例(仿"頭條"客戶端)

jopen 9年前發布 | 11K 次閱讀 IOS iOS開發 移動開發

好長時間沒為大家帶來iOS開發干貨的東西了,今天給大家分享一個頭條新聞客戶端各個類別進行切換的一個示例。在Demo中對所需的組件進行的簡單封裝,在封裝的組件中使用的是純代碼的形式,如果想要在項目中進行使用,稍微進行修改即可。

廢話少說,先介紹一下功能點,下圖是整個Demo的功能點,最上面左邊的TabBarButtonItem是用來減少條目的,比如下圖有三個按鈕,點擊減號會減少一個條目。右邊的為增加一個條目。點擊相應的按鈕是切換到對應的表視圖上,下方紅色的是滑動的指示器,同時支持手勢滑動。運行具體效果如下圖所示。

'iOS開發之多表視圖滑動切換示例(仿

一:實現方案

最上方是一個View, View上面實例化了一些按鈕,平分屏幕的寬度,下方是一個ScrollView, ScrollView上面放了一些表視圖,點擊不同的Button, 滑動到對應的表示圖上。除了點擊按鈕,還可以進行滑動切換,切換時,紅色的指示器也會隨之滑動。

主要的技術點就是通過ScrollView的回調,通過事件的響應來改變ScrollView的ContentOffset的值。在回調中根據ContentOffset的值來計算紅色指示器的偏移量。

二:核心代碼

1.組件中的主要屬性

把上面整個視圖進行了封裝,命名為SlideTabBarView,下面的代碼是主要屬性:

@interface SlideTabBarView()///@brife 整個視圖的大小
@property (assign) CGRect mViewFrame;
///@brife 下方的ScrollView
@property (strong, nonatomic) UIScrollView *scrollView;
///@brife 上方的按鈕數組
@property (strong, nonatomic) NSMutableArray *topViews;
///@brife 下方的表格數組
@property (strong, nonatomic) NSMutableArray *scrollTableViews;
///@brife TableViews的數據源
@property (strong, nonatomic) NSMutableArray *dataSource;
///@brife 當前選中頁數
@property (assign) NSInteger currentPage;
///@brife 下面滑動的View
@property (strong, nonatomic) UIView *slideView;
@end

2.初始化方法如下,在調用初始化方法時需要傳入SlideTabBarView的frame和選項卡的個數,初始化函數會調用一系列的初始化方法對組件進行初始化,代碼如下:

-(instancetype)initWithFrame:(CGRect)frame WithCount: (NSInteger) count{
    self = [super initWithFrame:frame];
    
    if (self) {
        _mViewFrame = frame;
        _tabCount = count;
        _topViews = [[NSMutableArray alloc] init];
        _scrollTableViews = [[NSMutableArray alloc] init];
        
        [self initDataSource];
        
        [self initScrollView];
        
        [self initTopTabs];
        
        [self initDownTables];
        
        [self initDataSource];
        
        [self initSlideView];
        
    }
    
    return self;
}

3.initDataSource方法主要負責模擬生成下方TableView要顯示的數據。代碼如下:

#pragma mark -- 初始化表格的數據源
-(void) initDataSource{
    _dataSource = [[NSMutableArray alloc] initWithCapacity:_tabCount];
    
    for (int i = 1; i <= _tabCount; i ++) {                  NSMutableArray *tempArray  = [[NSMutableArray alloc] initWithCapacity:20];                  for (int j = 1; j <= 20; j ++) {                          NSString *tempStr = [NSString stringWithFormat:@"我是第%d個TableView的第%d條數據。", i, j];             [tempArray addObject:tempStr];         }                  [_dataSource addObject:tempArray];     } }

4.紅色滑動指示器的初始化代碼如下所示:

#pragma mark -- 初始化滑動的指示View
-(void) initSlideView{
     CGFloat width = _mViewFrame.size.width / _tabCount;
    _slideView = [[UIView alloc] initWithFrame:CGRectMake(0, TOPHEIGHT - 5, width, 5)];
    [_slideView setBackgroundColor:[UIColor redColor]];
    [self addSubview:_slideView];
}

5.ScrollView的初始化代碼如下, 指定ScrollView的大小位置以及背景顏色,并且設置分頁可用并添加代理。

#pragma mark -- 實例化ScrollView
-(void) initScrollView{
    _scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, _mViewFrame.origin.y, _mViewFrame.size.width, _mViewFrame.size.height - TOPHEIGHT)];
    _scrollView.contentSize = CGSizeMake(_mViewFrame.size.width * _tabCount, _mViewFrame.size.height - 60);
    _scrollView.backgroundColor = [UIColor grayColor];
    
    _scrollView.pagingEnabled = YES;
    
    _scrollView.delegate = self;
    [self addSubview:_scrollView];
}

6.添加上方的按鈕,根據傳入的個數來實例化多個按鈕。

#pragma mark -- 實例化頂部的tab
-(void) initTopTabs{
    CGFloat width = _mViewFrame.size.width / _tabCount;
    
    for (int i = 0; i < _tabCount; i ++) {                  UIView *view = [[UIView alloc] initWithFrame:CGRectMake(i * width, 0, width, TOPHEIGHT)];                  view.backgroundColor = [UIColor lightGrayColor];                  if (i % 2) {             view.backgroundColor = [UIColor grayColor];         }                  UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, width, TOPHEIGHT)];         button.tag = i;         [button setTitle:[NSString stringWithFormat:@"按鈕%d", i+1] forState:UIControlStateNormal];         [button addTarget:self action:@selector(tabButton:) forControlEvents:UIControlEventTouchUpInside];         [view addSubview:button];                           [_topViews addObject:view];         [self addSubview:view];     } }

7.點擊按鈕觸發的方法如下:

#pragma mark --點擊頂部的按鈕所觸發的方法
-(void) tabButton: (id) sender{
    UIButton *button = sender;
    [_scrollView setContentOffset:CGPointMake(button.tag * _mViewFrame.size.width, 0) animated:YES];
}

8.初始化下方的多個表視圖:實例化表視圖,并指定委托回調。

#pragma mark --初始化下方的TableViews
-(void) initDownTables{
    
    for (int i = 0; i < _tabCount; i ++) {                  UITableView *tableView = [[UITableView alloc] initWithFrame:CGRectMake(i * _mViewFrame.size.width, 0, _mViewFrame.size.width, _mViewFrame.size.height - TOPHEIGHT)];         tableView.delegate = self;         tableView.dataSource = self;                  [_scrollTableViews addObject:tableView];         [_scrollView addSubview:tableView];     } }

9.ScrollView的回調方法如下,下面最后一個代理方法是根據ScrollView的偏移量來計算紅色指示器的偏移量,第二個是滑動到哪個tableView,然后進行哪個TableView的數據加載。

#pragma mark -- scrollView的代理方法
-(void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView{
    [self scrollViewDidEndDecelerating:scrollView];
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    _currentPage = _scrollView.contentOffset.x/_mViewFrame.size.width;
    
    UITableView *currentTable = _scrollTableViews[_currentPage];
    [currentTable reloadData];
    
}
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
    if ([_scrollView isEqual:scrollView]) {
        CGRect frame = _slideView.frame;
        frame.origin.x = scrollView.contentOffset.x/_tabCount;
        _slideView.frame = frame;
    }
}

10.TableView的代理方法如下,數據源就是我們剛才做的假數據,Cell是由Xib實現的,使用的時候注冊一下就可用了。

#pragma mark -- talbeView的代理方法
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
    return 1;
}
-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    NSMutableArray *tempArray = _dataSource[_currentPage];
    return tempArray.count;
}
-(CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    return 60;
}
-(UITableViewCell *)tableView:tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    
    BOOL nibsRegistered=NO;
    if (!nibsRegistered) {
        UINib *nib=[UINib nibWithNibName:@"SlideBarCell" bundle:nil];
        [tableView registerNib:nib forCellReuseIdentifier:@"SlideBarCell"];
        nibsRegistered=YES;
    }
    
    
    SlideBarCell *cell = [tableView dequeueReusableCellWithIdentifier:@"SlideBarCell"];
    if ([tableView isEqual:_scrollTableViews[_currentPage]]) {
         cell.tipTitle.text = _dataSource[_currentPage][indexPath.row];
    }
   
    return cell;
}

Demo在GitHub上的分享地址:https://github.com/lizelu/SliderTabBar

作者:青玉伏案 
出處:http://www.cnblogs.com/ludashi/ 
 

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!