美文网首页
iOS横向滚动视图自定义封装

iOS横向滚动视图自定义封装

作者: 朝阳小麦 | 来源:发表于2018-08-24 15:48 被阅读99次

    适用人群:iOS开发人员。
    本文内容:iOS横向滚动视图自定义封装。

    备注:纵向动态文本的滚动示例:https://www.jianshu.com/p/05a2e42acded

    视图内容如下图:

    record.gif

    代码展示&使用举例:

    1.ScrollPageView.h代码如下:
    
    #import <UIKit/UIKit.h>
    
    @interface ScrollPageView : UIView
    
    /** 总页数 */
    @property (nonatomic, assign) NSInteger pageNum;
    /** YES 还有上一页 */
    @property (nonatomic, assign, readonly) BOOL hasLastPage;
    /** YES 还有下一页 */
    @property (nonatomic, assign, readonly) BOOL hasNextPage;
    
    /** 自定义pageView */
    @property (nonatomic, strong) void(^addScrollPageView)(UIView *pageView, NSInteger currentIndex);
    /** pageView点击事件 */
    @property (nonatomic, strong) void(^pageViewDidClicked)(UIView *pageView, NSInteger currentIndex);
    /** pageView滚动事件 */
    @property (nonatomic, strong) void(^pageViewDidScroll)(UIView *pageView, NSInteger currentIndex);
    
    /** 调用show显示视图 */
    - (void)show;
    
    /** 滚动到上一页 */
    - (void)scrollToLastPage;
    
    /** 滚动到下一页 */
    - (void)scrollToNextPage;
    
    @end
    
    2.ScrollPageView.m代码如下:
    #import "ScrollPageView.h"
    
    static NSInteger const BasePageViewTag = 100;
    
    @interface ScrollPageView()<UIScrollViewDelegate>
    
    @property (nonatomic, assign) NSInteger currentIndex;
    
    @property (nonatomic, assign) CGFloat spacing;
    @property (nonatomic, assign) CGFloat pageWidth;
    @property (nonatomic, assign) CGFloat pageHeight;
    
    @property (nonatomic, strong) UIScrollView *scrollView;
    
    @end
    
    @implementation ScrollPageView
    
    - (instancetype)initWithFrame:(CGRect)frame
    {
        self = [super initWithFrame:frame];
        if (self) {
            self.backgroundColor = [UIColor whiteColor];
            [self addSubview:self.scrollView];
            
            self.pageNum = 0;
            self.currentIndex = 0;
            self.spacing = 10;
            self.pageWidth = self.frame.size.width-_spacing*4;
            self.pageHeight = self.frame.size.height;
        }
        return self;
    }
    
    - (void)show {
        CGFloat spacing = _spacing;
        CGFloat pageWidth = _pageWidth;
        CGFloat pageHeight = _pageHeight;
        for (int i=0; i<self.pageNum; i++) {
            UIView *pageView = [[UIView alloc] initWithFrame:CGRectMake(pageWidth*i+spacing*2+spacing*i, 0, pageWidth, pageHeight)];
            pageView.tag = BasePageViewTag+i;
            UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(pageViewClicked:)];
            [pageView addGestureRecognizer:tap];
            if (self.addScrollPageView) {
                self.addScrollPageView(pageView, i);
            }
            [self.scrollView addSubview:pageView];
        }
        
        CGFloat scrollViewContentWidth = spacing*2*2+pageWidth*self.pageNum+spacing*(self.pageNum-1);
        [self.scrollView setContentSize:CGSizeMake(scrollViewContentWidth, pageHeight)];
    }
    
    - (BOOL)hasLastPage {
        return self.currentIndex>0;
    }
    
    - (BOOL)hasNextPage {
        return self.currentIndex<self.pageNum-1;
    }
    
    - (void)scrollToLastPage {
        if (self.hasLastPage) {
            CGFloat offsetX = self.scrollView.contentOffset.x - (_pageWidth+_spacing);
            [self.scrollView setContentOffset:CGPointMake(offsetX, 0) animated:YES];
            self.currentIndex --;
            if (self.pageViewDidScroll) {
                self.pageViewDidScroll(self.scrollView.subviews[self.currentIndex], self.currentIndex);
            }
        }
    }
    
    - (void)scrollToNextPage {
        if (self.hasNextPage) {
            CGFloat offsetX = self.scrollView.contentOffset.x + (_pageWidth+_spacing);
            [self.scrollView setContentOffset:CGPointMake(offsetX, 0) animated:YES];
            self.currentIndex ++;
            if (self.pageViewDidScroll) {
                self.pageViewDidScroll(self.scrollView.subviews[self.currentIndex], self.currentIndex);
            }
        }
    }
    
    #pragma mark - action
    
    - (void)pageViewClicked:(UITapGestureRecognizer *)sender {
        if (self.pageViewDidClicked) {
            self.pageViewDidClicked(sender.view, sender.view.tag-BasePageViewTag);
        }
    }
    
    #pragma mark - scrollViewDelegate
    
    - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
        [self updateScrollViewContentOffset:scrollView];
    }
    
    - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
        [self updateScrollViewContentOffset:scrollView];
    }
    
    #pragma mark - privite method
    
    - (void)updateScrollViewContentOffset:(UIScrollView *)scrollView {
        CGFloat offsetX = scrollView.contentOffset.x;
        
        CGFloat spacing = _spacing;
        CGFloat pageWidth = _pageWidth;
        
        CGFloat lastPageCenterX = 0;
        for (int i=0; i<self.pageNum; i++) {
            CGFloat pageCenterX = spacing*2+pageWidth/2.0+pageWidth*i+spacing*i;
            if (lastPageCenterX < offsetX && offsetX <= pageCenterX) {
                [scrollView setContentOffset:CGPointMake(pageCenterX-pageWidth/2.0-spacing*2, 0) animated:YES];
                self.currentIndex = i;
                if (self.pageViewDidScroll) {
                    self.pageViewDidScroll(self.scrollView.subviews[self.currentIndex], self.currentIndex);
                }
                break;
            } else {
                lastPageCenterX = pageCenterX;
            }
        }
    }
    
    #pragma mark - lazy load
    
    - (UIScrollView *)scrollView {
        if (!_scrollView) {
            _scrollView = [[UIScrollView alloc] initWithFrame:self.bounds];
            _scrollView.delegate = self;
            _scrollView.backgroundColor = [UIColor clearColor];
            _scrollView.showsHorizontalScrollIndicator = NO;
            //UIScrollViewDecelerationRateNormal:正常减速(默认值)
            //UIScrollViewDecelerationRateFast:快速减速
            _scrollView.decelerationRate = UIScrollViewDecelerationRateFast;//快速减速
        }
        return _scrollView;
    }
    

    3.使用举例如下:

    在新建工程自带ViewController界面更改:

    #import "ViewController.h"
    #import "ScrollPageView.h"
    
    @interface ViewController ()
    
    @property (nonatomic, strong) ScrollPageView *scrollPageView;
    
    @property (nonatomic, strong) UIButton *lastPageButton;
    @property (nonatomic, strong) UIButton *nextPageButton;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        ScrollPageView *view = [[ScrollPageView alloc] initWithFrame:CGRectMake(0, 200, self.view.frame.size.width, 150)];
        view.pageNum = 4;
        view.addScrollPageView = ^(UIView *pageView, NSInteger currentIndex) {
            NSArray *colors = @[[UIColor redColor], [UIColor yellowColor], [UIColor blueColor], [UIColor greenColor]];
            pageView.backgroundColor = colors[currentIndex];
        };
        view.pageViewDidClicked = ^(UIView *pageView, NSInteger currentIndex) {
            NSLog(@"page view did clicked at index : %ld", currentIndex);
        };
        __weak typeof (ViewController *) _self = self;
        view.pageViewDidScroll = ^(UIView *pageView, NSInteger currentIndex) {
            [_self pageViewDidScroll];
        };
        [view show];
        self.scrollPageView = view;
        [self.view addSubview:_scrollPageView];
        
        UIButton *lastPageButton = [UIButton buttonWithType:UIButtonTypeCustom];
        lastPageButton.frame = CGRectMake(100, 400, 100, 50);
        [lastPageButton setTitle:@"上一页" forState:UIControlStateNormal];
        [lastPageButton setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
        [lastPageButton setTitleColor:[UIColor grayColor] forState:UIControlStateDisabled];
        [lastPageButton addTarget:self action:@selector(lastPageButtonAction:) forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview:lastPageButton];
        self.lastPageButton = lastPageButton;
        lastPageButton.enabled = NO;
        
        UIButton *nextPageButton = [UIButton buttonWithType:UIButtonTypeCustom];
        nextPageButton.frame = CGRectMake(200, 400, 100, 50);
        [nextPageButton setTitle:@"下一页" forState:UIControlStateNormal];
        [nextPageButton setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
        [nextPageButton setTitleColor:[UIColor grayColor] forState:UIControlStateDisabled];
        [nextPageButton addTarget:self action:@selector(nextPageButtonAction:) forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview:nextPageButton];
        self.nextPageButton = nextPageButton;
    }
    
    - (void)lastPageButtonAction:(UIButton *)sender {
        [_scrollPageView scrollToLastPage];
    }
    
    - (void)nextPageButtonAction:(UIButton *)sender {
        [_scrollPageView scrollToNextPage];
    }
    
    - (void)pageViewDidScroll {
        self.lastPageButton.enabled = self.scrollPageView.hasLastPage;
        self.nextPageButton.enabled = self.scrollPageView.hasNextPage;
    }
    

    相关文章

      网友评论

          本文标题:iOS横向滚动视图自定义封装

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