项目总结4 类似网易云音乐导航栏指示器与Scrollview互动(个性推荐、歌单等)的简单实现(二)

上篇文章讲到指示器的添加,今天我们来添加一个scrollview,使得指示器能跟随scrollview变化,scrollview也能根据指示器的位置不同更改自己需要显示的view。

还是以网易音乐的界面为例,红色指示器下面对应了一个view,其它三个指示器按钮也对应了各自的view

指示器对应的view

所以,我们需要创建一个scrollview作为底层view,然后在scrollview上添加4个ViewController来对应指示器4个按钮的页面。

创建4个ViewController

创建好4个ViewController文件后,我们要实例化他们,并添加到当前view的子控制器中。

- (void)addChildViews
{
    CommendViewController *cmmVC = [[CommendViewController alloc] init];
    cmmVC.title = @"个性推荐";
    [self addChildViewController:cmmVC];

    ListViewController *listVC = [[ListViewController alloc] init];
    listVC.title = @"歌单";
    [self addChildViewController:listVC];

    RadioViewController *radioVC = [[RadioViewController alloc] init];
    radioVC.title = @"主播频道";
    [self addChildViewController:radioVC];

    LeaderBoardViewController *leaderVC = [[LeaderBoardViewController alloc] init];
    leaderVC.title = @"排行榜";
    [self addChildViewController:leaderVC];
}

记得在viewDidLoad函数中调用它!!

接下来我们添加scrollview吧

/**
 *  创建Scrollview咯~
 *
 *  @return void
 */
- (void)initScrollView
{
    //禁止系统自动调整ScrollView的布局,以免影响我们自己的布局
    self.automaticallyAdjustsScrollViewInsets = NO;

    //创建scrollview
    UIScrollView *scrollView = [[UIScrollView alloc] init];
    scrollView.frame = [UIScreen mainScreen].bounds;

    //使用scrollview的分页功能,如果拖动没到页面的一半,不会切换到下一页
    scrollView.pagingEnabled = YES;
    //设置scrollview的内容显示大小,一共有4个屏幕宽度
    scrollView.contentSize = CGSizeMake(self.view.width * 4, 0);

    scrollView.backgroundColor = [UIColor lightGrayColor];
    //设置scrollview的代理
    scrollView.delegate = self;

    //把scrollview添加到view的最底层
    [self.view insertSubview:scrollView atIndex:0];

    //保存scrollview到属性,方便后面调用
    self.contentScrollView = scrollView;

}

同样,记得在ViewDidLoad函数中调用它,并且要在addChildViews之后调用。

完成这两步,大家觉得能显示出来4个ViewController了吗?当然是不行的,因为我们还要把ViewController添加到scrollview中。但是,什么时候添加呢?如何添加?

我们发现,当我们第一次进入页面时,显示的是加载。

加载页面

也就是说,当点击指示器按钮时,才会添加页面,然后初始化页面。所以,我们在scrollview的代理函数scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView 函数中来添加ViewController。这个函数是当滑动动画结束的时候被调用,但是注意,这个滑动动画不是手动触发的滑动动画,而是setContentOffset:animated:函数调用时动画完成后调用,手动拖拽scrollview是不会调用到这个函数的。那么我们就用scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollViewsetContentOffset:animated: 来配合使用,实现指示器按钮与scrollview的互动。

我们先来完成scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView 函数。

- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
{
    //根据contentOffset的x值与scrollview的宽度的比值来确定当前滑动到了哪个view的内容范围
    NSInteger index = scrollView.contentOffset.x / scrollView.width;
    //上一步算出来的index就是我们需要显示的view的索引,从childViewControllers中取出对应的ViewController
    UIViewController *vc = self.childViewControllers[index];

    //设置取出来的vc的x和高度,填满scrollview
    vc.view.x = scrollView.contentOffset.x;
    vc.view.height = scrollView.height;

    //最后添加vc到scrollview中
    [scrollView addSubview:vc.view];
}

我们是在这个代理函数中添加的ViewController,那么如果程序刚启动,没有条件触发scrollview的动画,怎么显示第一个指示器对应的页面呢?这个简单,我们只需要在initScrollView函数中,手动调用下scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView 函数,传入创建的scrollview就好。

完成后,我们在指示器button对应的响应函数中调用setContentOffset:animated: 函数来调整scrollview的contentOffset,使scrollview滑动,触发scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView 函数 。

- (void)btnClicked:(UIButton *)btn
{
    //设置上次点击被disable的button为enable状态
    self.indicatorDisableBtn.enabled = YES;
    //当前点击的button为disable状态,好显示红色title
    btn.enabled = NO;
    //保存当前点击的button
    self.indicatorDisableBtn = btn;

    //设置红线的动画
    [UIView animateWithDuration:0.2f animations:^{
        self.indicatorLine.width = btn.titleLabel.width;
        self.indicatorLine.centerX = btn.centerX;
    }];

    //添加滑动scrollview,点击button后scrollview跟着滑动到相应位置
    //通过选中的button的tag值来判断现在选择的是第几个button,然后根据tag值决定需要滚动几个view的宽度
    CGPoint offset = self.contentScrollView.contentOffset;
    offset.x = btn.tag * self.contentScrollView.width;
    //这里设置了animated参数为YES,在自动滚动scrollview的动画完成时会调用scrollViewDidEndScrollingAnimation
    [self.contentScrollView setContentOffset:offset animated:YES];


}

这下,我们点击指示器的button时,scrollview就能改变view了。

接下来最后一步,实现手动滑动scrollview时更改scrollview内容,并且改变指示器位置。

//滑动scrollview时更改content
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    NSInteger index = scrollView.contentOffset.x / scrollView.width;
    UIButton *btn = self.indicatorView.subviews[index];
    //手动调用button的响应函数以便在拖拽scrollview时button跟着变化,以实现不同操作的相同结果
    [self btnClicked:btn];

    //当点击到的button对应的view没有添加到scrollview中时,手动调用下scrollViewDidEndScrollingAnimation函数来滚动scrollview并创建子视图。
    [self scrollViewDidEndScrollingAnimation:scrollView];
}

完成后,看看运行结果

滑动

切换

滑动scrollview后,界面切换了,并且指示器也跟着动了。

项目代码在这里,对你有帮助的话希望给个星

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值