UIScrollView频道滑动(授人以鱼,不如授人以渔)

        内容型APP(比如新闻,视频),通常采用多个页面(频道)滑动;另外,自动滚动的焦点图用到比较多的。本文简单介绍使用UIScrollView实现上述功能的原理,并附部分代码。无论是频道的滑动,还是焦点图自动滑动,都是基于UIScrollView的特性,viewController 实现UIScrollView的代理,并做一些控制即可。
核心思想:
    ★使用UIScrollerview作为承载view。各个频道添加到UIScrollerview上。注意:UIScrollerview需要提前知道频道数量,进而确定UIScrollerview的frame.width
    ★当滑动屏幕一半儿的时候,调用UIScrollView 的- (void)scrollRectToVisible:(CGRect) animated:(BOOL)方法,实现整页滚动。
    ★当滑动屏幕不到一半儿的时候,由于启用了UIScrollView的pagingEnabled属性,所以,UIScrollView会自动弹回原位置。

关键代码:

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.scrollView = [[UIScrollView alloc] initWithFrame:self.bounds];   /*创建scrollerview*/
    self.scrollView.pagingEnabled = YES; /*scroller 一页页滑动,而不是一直滑下去*/
    self.scrollView.scrollsToTop = NO;       /*点击状态栏,是否滚到顶部。不*/
    self.scrollView.bounces = YES;           /*到达边界回弹*/
    self.scrollView.alwaysBounceHorizontal = YES;   /*如果水平方向,内容宽度小于bound,仍可以滑动回弹*/
    self.scrollView.alwaysBounceVertical = NO;         /*如果垂直方向,内容高度小于bound,不让滑动回弹*/
    self.scrollView.showsHorizontalScrollIndicator = NO;/*横向滚动条,不显示*/
    self.scrollView.showsVerticalScrollIndicator = NO;    /*纵向滚动条,不显示*/
    
    /*添加到viewController中的view之上*/
    [self.view addSubview:self.scrollView];
}
========================================================================
//内存警告的时候,卸载多余的page。保留current前后两个page
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    
    for (NSInteger i = 0; i < [self.viewControllers count]; i++) {
        if (i < self.currentPage - 1 || i > self.currentPage + 1) {
            [self unloadViewControllerByPage:i];
        }
    }
}
========================================================================
- (void)willScrollToPage:(NSInteger)page animated:(BOOL)animated {
    //在滑动到page时候,处理逻辑。子类可重写该方法
}


- (void)didScrollToPage:(NSInteger)page animated:(BOOL)animated {
    //在滑动到page时候,处理逻辑。子类可重写该方法
    [self scrollToPage:index animated:YES];
}

========================================================================

//跳转任意频道。
- (void)scrollToPage:(NSInteger)page animated:(BOOL)animated {
    NSInteger lastPage = self.currentPage;
    [self setCurrentPage:page animated:animated];
    if (self.currentPage != lastPage) {
        [self removeViewControllerByPage:lastPage];
    }
    
        CGRect bounds = UIEdgeInsetsInsetRect(self.scrollView.bounds, self.scrollView.contentInset);
        bounds.origin.x = CGRectGetWidth(bounds) * page;
        bounds.origin.y = 0;
    /* animated参数,一定要NO,不然滑动时候产生抖动 */
    [self.scrollView scrollRectToVisible:bounds animated:NO];
}

========================================================================
#pragma mark - UIScrollViewDelegate

/*手指开始拖拽*/
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
    if (scrollView != self.scrollView) {
        return;
    }

    //加载后一个,前一个page
    [self addViewControllerByPage:self.currentPage - 1];
    [self addViewControllerByPage:self.currentPage + 1];
}

- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView {
    if (scrollView != self.scrollView) {
        return;
    }

    //加载后一个,前一个page
    [self addViewControllerByPage:self.currentPage - 1];
    [self addViewControllerByPage:self.currentPage + 1];
}


- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
    if (scrollView != self.scrollView) {
        return;
    }
    
    if (decelerate) {
        return;
    }
    
    CGFloat width = CGRectGetWidth(scrollView.bounds);
    CGFloat position = self.scrollView.contentOffset.x;
    [self setCurrentPage:round(position / width) animated:YES];
    
    if (!decelerate) {
        for (NSInteger i = 0; i < self.numberOfPages; i++) {
            if (i != self.currentPage) {
                [self removeViewControllerByPage:i];
            }
        }
    }
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    if (scrollView != self.scrollView) {
        return;
    }
    
    CGFloat width = CGRectGetWidth(scrollView.bounds);
    CGFloat position = self.scrollView.contentOffset.x;
    [self setCurrentPage:round(position / width) animated:YES];
    
    for (NSInteger i = 0; i < self.numberOfPages; i++) {
        if (i != self.currentPage) {
	    //非移除currentPage
            [self removeViewControllerByPage:i];
        }
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值