美文网首页
自定义滑动控制器

自定义滑动控制器

作者: CoderLNHui | 来源:发表于2017-02-21 11:03 被阅读29次

    界面逻辑

    • 首页控制器--->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

    相关文章

      网友评论

          本文标题:自定义滑动控制器

          本文链接:https://www.haomeiwen.com/subject/icwywttx.html