搜索
您的当前位置:首页正文

自定义滑动控制器

来源:二三娱乐

界面逻辑

  • 首页控制器--->scollerview ---> 5个tableVIew控制器-->管理5个title按钮对应的view

代码逻辑

  • 初始化子控制器
  • 首页控制器添加5个对应的子控制器
  • 首页控制器view添加scrollview
  • 设置scrollview的内容大小contentsize为子控制器的个数乘scrollview自身的宽度
  • 添加标题栏view
  • 标题栏上加标题按钮btn和下划线
  • 设置标题按钮btn的点击事件
  • 记录点击的按钮,取消记录点击按钮的选中状态,新点击的按钮设置为选中状态,把心点击的按钮赋值给记录选中的按钮
  • 点击按钮时,下划线滚动到相应的按钮下方,下划线的宽度为按钮的titllable的宽度,中心点为相应按钮的中心点
  • 按钮点击时,对应的scrollview偏移到按钮相对应的位置
  • 当用户点击对应的btn时,才去加载对用的控制器view

代码实现


#import "SHOneViewController.h"

#import "SHTopicOneTBController.h"

#import "SHTopicTwoViewController.h"

#import "SHTopicThreeViewController.h"

#import "SHTopicFourViewController.h"

#import "SHTopicFiveViewController.h"

@interface SHOneViewController ()<UIScrollViewDelegate>

/** 标题栏 */

@property (nonatomic, weak) UIView *titlesView;

/** 标题下划线 */

@property (nonatomic, weak) UIView *titleUnderline;

/** 上一次点击的标题按钮 */

@property (nonatomic, weak) SHTitleBtn *previousClickedTitleBtn;

/** 用来存放所有子控制器view的scrollView */

@property (nonatomic, weak) UIScrollView *scrollView;

@end

@implementation SHOneViewController

- (void)viewDidLoad {

    

    [super viewDidLoad];

    self.view.backgroundColor = kOrangeMainColor;

    // 初始化子控制器

    [self setupAllChildVcs];

    

    // 设置导航条

    [self setupNavBar];

    

    // scrollView

    [self setupScrollView];

    // 标题栏

    [self setupTitlesView];

    

    // 添加第0个子控制器的view

    [self addChildVcViewIntoScrollView:0];

    

}

#pragma mark - Private&Public Methods

/**

 *  设置导航条

 */

- (void)setupNavBar

{

    // 左边按钮

    // 把UIButton包装成UIBarButtonItem.就导致按钮点击区域扩大

    self.navigationItem.leftBarButtonItem = [UIBarButtonItem itemWithimage:[UIImage imageNamed:@"MainTagSubIcon"] highImage:[UIImage imageNamed:@"MainTagSubIconClick"] target:self action:@selector(game)];

    

    // 右边按钮

    self.navigationItem.rightBarButtonItem = [UIBarButtonItem itemWithimage:[UIImage imageNamed:@"friendsRecommentIcon"] highImage:[UIImage imageNamed:@"friendsRecommentIcon-click"] target:nil action:nil];

    

    // titleView,cellmorebtnclick,MainTitle

    self.navigationItem.titleView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"cellmorebtnclick"]];

}

/**

 *  标题栏

 */

- (void)setupTitlesView

{

    

    [self setupTitleButtons];

    [self setupTitleUnderline];

    

}

/**

 *  标题栏按钮

 */

- (void)setupTitleButtons

{

    // 文字

    NSArray *titlesArr = @[@"第一个",@"第二个的",@"三个",@"四",@"第五个"];

    NSUInteger count = titlesArr.count;

    

    // 标题按钮的尺寸

    CGFloat titleBtnW = self.titlesView.sh_width / count;

    CGFloat titleBtnH = self.titlesView.sh_height;

    

    // 创建5个标题按钮

    for (NSInteger i = 0; i < count; i++) {

        SHTitleBtn *titleBtn = [[SHTitleBtn alloc] init];

        titleBtn.tag = i;

        [titleBtn addTarget:self action:@selector(titleBtnClick:) forControlEvents:UIControlEventTouchUpInside];

        [self.titlesView addSubview:titleBtn];

        titleBtn.frame = CGRectMake(i *titleBtnW, 0, titleBtnW, titleBtnH);

        [titleBtn setTitle:titlesArr[i] forState:UIControlStateNormal];

    }

    

}

/*

*  标题下划线

*/

- (void)setupTitleUnderline

{

    //标题按钮

    SHTitleBtn *firstTitleBtn = self.titlesView.subviews.firstObject;

    self.titleUnderline.backgroundColor = [firstTitleBtn titleColorForState:UIControlStateSelected];

 

    // 切换按钮状态

    firstTitleBtn.selected = YES;

    self.previousClickedTitleBtn = firstTitleBtn;

    [firstTitleBtn.titleLabel sizeToFit]; // 让label根据文字内容计算尺寸

    

    self.titleUnderline.sh_width = firstTitleBtn.titleLabel.sh_width + SHMarin;

    self.titleUnderline.sh_centerX = firstTitleBtn.sh_centerX;

}

//初始化子控制器

- (void)setupAllChildVcs

{

    

    [self addChildViewController:[[SHTopicOneTBController alloc] init]];

    [self addChildViewController:[[SHTopicTwoViewController alloc] init]];

    [self addChildViewController:[[SHTopicThreeViewController alloc] init]];

    [self addChildViewController:[[SHTopicFourViewController alloc] init]];

    [self addChildViewController:[[SHTopicFiveViewController alloc] init]];

    

}

// scrollView

- (void)setupScrollView

{

    // 不允许自动修改UIScrollView的内边距

    self.automaticallyAdjustsScrollViewInsets = NO;

    NSUInteger count = self.childViewControllers.count;

    CGFloat scrollViewW = self.scrollView.sh_width;

    self.scrollView.contentSize = CGSizeMake(scrollViewW *count, 0);

    

}

/**

 *  添加第index个子控制器的view到scrollView中

 */

- (void)addChildVcViewIntoScrollView:(NSUInteger)index

{

    UIViewController *childVc = self.childViewControllers[index];

    // 如果view已经被加载过,就直接返回

    if (childVc.isViewLoaded) return;

    // 取出index位置对应的子控制器view

    UIView *childVcView = childVc.view;

    

    //设置子控制器view的frame

    CGFloat scroollViewW = self.scrollView.sh_width;

    childVcView.frame = CGRectMake(index *scroollViewW, 0, scroollViewW, self.scrollView.sh_height);

    //添加子控制器的view到scrollview中

    [self.scrollView addSubview:childVcView];

}

#pragma mark - 按钮点击

/**

 *  点击标题按钮

 */

- (void)titleBtnClick:(SHTitleBtn *)titleButton

{

    // 重复点击了标题按钮

    if (self.previousClickedTitleBtn == titleButton) {

        [[NSNotificationCenter defaultCenter] postNotificationName:SHTitleButtonDidRepeatClickNotification object:nil];

    }

    

    

    // 处理标题按钮点击

    [self dealTitleButtonClick:titleButton];

}

- (void)dealTitleButtonClick:(SHTitleBtn *)titleButton

{

    // 切换按钮状态

    self.previousClickedTitleBtn.selected = NO;

    titleButton.selected = YES;

    self.previousClickedTitleBtn = titleButton;

    

    NSUInteger index = titleButton.tag;

    [UIView animateWithDuration:0.25 animations:^{

       

        //处理下划线

        self.titleUnderline.sh_width = titleButton.titleLabel.sh_width + SHMarin;

        self.titleUnderline.sh_centerX = titleButton.sh_centerX;

        

        //滚蛋scrollview

        CGFloat offsetX = self.scrollView.sh_width *index;

        self.scrollView.contentOffset = CGPointMake(offsetX, self.scrollView.contentOffset.y);

        

    } completion:^(BOOL finished) {

        // 添加子控制器的view

        [self addChildVcViewIntoScrollView:index];

    }];

    

    // 设置index位置对应的tableView.scrollsToTop = YES, 其他都设置为NO

    for (NSUInteger i = 0; i < self.childViewControllers.count; i++) {

        UIViewController *childVc = self.childViewControllers[i];

        // 如果view还没有被创建,就不用去处理

        if (!childVc.isViewLoaded) continue;

        

        UIScrollView *scrollView = (UIScrollView *)childVc.view;

        if (![scrollView isKindOfClass:[UIScrollView class]]) continue;

        

        scrollView.scrollsToTop = (i == index);

    }

    

}

- (void)game

{

    SHFunc;

}

#pragma mark - <UIScrollViewDelegate>

/**

 *  当用户松开scrollView并且滑动结束时调用这个代理方法(scrollView停止滚动的时候)

 */

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView

{

    //求出标题按钮的索引

    NSUInteger index = scrollView.contentOffset.x / scrollView.sh_width;

    //点击对应的标题按钮

    SHTitleBtn *titleBtn = self.titlesView.subviews[index];

    [self dealTitleButtonClick:titleBtn];

    

}

#pragma mark - Getters

- (UIScrollView *)scrollView

{

    if (!_scrollView) {

        UIScrollView *scrollView = [[UIScrollView alloc] init];

        scrollView.backgroundColor = [UIColor blueColor];

        scrollView.frame = self.view.bounds;

        scrollView.delegate = self;

        scrollView.showsHorizontalScrollIndicator = NO;

        scrollView.showsVerticalScrollIndicator = NO;

        scrollView.pagingEnabled = YES;

        scrollView.scrollsToTop = NO; // 点击状态栏的时候,这个scrollView不会滚动到最顶部

        [self.view addSubview:scrollView];

        _scrollView = scrollView;

    }

    return _scrollView;

}

- (UIView *)titlesView

{

    if (!_titlesView) {

        UIView *titlesView = [[UIView alloc] init];

        titlesView.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0.5];

        titlesView.frame = CGRectMake(0, SHNavMaxY, self.view.sh_width, SHTitlesViewH);

        [self.view addSubview:titlesView];

        _titlesView = titlesView;

    }

    return _titlesView;

}

- (UIView *)titleUnderline

{

    if (!_titleUnderline) {

        

        UIView *titleUnderLine = [[UIView alloc] init];

        titleUnderLine.sh_height = 2;

        titleUnderLine.sh_y = self.titlesView.sh_height - titleUnderLine.sh_height;

        [self.titlesView addSubview:titleUnderLine];

        _titleUnderline = titleUnderLine;

        

    }

    return _titleUnderline;

}

@end


#import "SHTopicBaseTableViewController.h"

@interface SHTopicBaseTableViewController ()

@property (nonatomic, strong) NSMutableArray *topicArr;

@end

@implementation SHTopicBaseTableViewController

- (void)viewDidLoad {

    [super viewDidLoad];

    self.view.backgroundColor = SHRandomColor;

    self.tableView.contentInset = UIEdgeInsetsMake(SHNavMaxY + SHTitlesViewH, 0, SHTabBarH, 0);

    self.tableView.scrollIndicatorInsets = self.tableView.contentInset;

    self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;

    

    [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:NSStringFromClass([SHTopicBaseTableViewController class])];

    

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(titleButtonDidRepeatClick) name:SHTitleButtonDidRepeatClickNotification object:nil];

}

/*

 [[SHVideoViewController alloc] init]

 1.SHVideoViewController.xib

 2.SHVideoView.xib

 

 报错信息:-[UIViewController _loadViewFromNibNamed:bundle:] loaded the "SHVideoView" nib but the view outlet was not set.

 错误原因:在使用xib创建控制器view时,并没有通过File's Owner设置控制器的view属性

 解决方案:通过File's Owner设置控制器的view属性为某一个view

 

 报错信息:-[UITableViewController loadView] loaded the "SHVideoView" nib but didn't get a UITableView.

 错误原因:在使用xib创建UITableViewController的view时,并没有设置控制器的view为一个UITableView

 解决方案:通过File's Owner设置控制器的view属性为一个UITableView

 */

#pragma mark - Table view data source

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    return 15;

 //   return self.topicArr.count;

}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

{

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([SHTopicBaseTableViewController class]) forIndexPath:indexPath];

    cell.textLabel.text = kFormat(@"%ld", indexPath.row);

    return cell;

}

#pragma mark - 监听

/**

 *  监听titleButton重复点击

 */

- (void)titleButtonDidRepeatClick

{

    [self tabBarButtonDidRepeatClick];

}

/**

 *  监听tabBarButton重复点击

 */

- (void)tabBarButtonDidRepeatClick

{

    // 重复点击的不是首页按钮

    if (self.view.window == nil) return;

    

    // 显示在正中间的不是VideoViewController

    if (self.tableView.scrollsToTop == NO) return;

    

    // 进入下拉刷新

    [self.tableView.mj_header beginRefreshing];

}

- (void)dealloc

{

    [[NSNotificationCenter defaultCenter] removeObserver:self];

}

#pragma mark - Getters

- (NSMutableArray *)topicArr

{

    if (!_topicArr) {

        _topicArr = [NSMutableArray array];

    }

    return _topicArr;

}

@end

效果图

图片.png
Top