123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313 |
- //
- // NIMInputPageView.m
- // NIMKit
- //
- // Created by chris.
- // Copyright (c) 2015年 NetEase. All rights reserved.
- //
- #import "NIMPageView.h"
- @interface NIMPageView ()
- {
- NSInteger _currentPage;
- NSInteger _currentPageForRotation;
- }
- @property (nonatomic,strong) NSMutableArray *pages;
- - (void)setupControls;
- //重新载入的流程
- - (void)calculatePageNumbers;
- - (void)reloadPage;
- - (void)raisePageIndexChangedDelegate;
- @end
- @implementation NIMPageView
- - (id)initWithFrame:(CGRect)frame
- {
- self = [super initWithFrame:frame];
- if (self)
- {
- [self setupControls];
- }
- return self;
- }
- - (id)initWithCoder:(NSCoder *)aDecoder
- {
- if (self = [super initWithCoder:aDecoder])
- {
- [self setupControls];
- }
- return self;
- }
- - (void)setFrame:(CGRect)frame{
- CGFloat originalWidth = self.frame.size.width;
- [super setFrame:frame];
- if (originalWidth != frame.size.width) {
- [self reloadData];
- }
- }
- - (void)dealloc
- {
- _scrollView.delegate = nil;
- }
- - (void)layoutSubviews
- {
- [super layoutSubviews];
- [_scrollView setFrame:self.bounds];
-
- CGSize size = self.bounds.size;
- [self.scrollView setContentSize:CGSizeMake(size.width * [self.pages count], size.height)];
- for (NSInteger i = 0; i < [self.pages count]; i++)
- {
- id obj = [self.pages objectAtIndex:i];
- if ([obj isKindOfClass:[UIView class]])
- {
- [(UIView *)obj setFrame:CGRectMake(size.width * i, 0, size.width, size.height)];
- }
- }
-
- //CGSize size = self.bounds.size;
- BOOL animation = NO;
- if (self.pageViewDelegate && [self.pageViewDelegate respondsToSelector:@selector(needScrollAnimation)])
- {
- animation = [self.pageViewDelegate needScrollAnimation];
- }
- [self.scrollView scrollRectToVisible:CGRectMake(_currentPage * size.width, 0, size.width, size.height)
- animated:animation];
-
- }
- - (void)setupControls
- {
- if (_scrollView == nil)
- {
- _scrollView = [[UIScrollView alloc]initWithFrame:self.bounds];
- _scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
- [self addSubview:_scrollView];
- _scrollView.pagingEnabled = YES;
- _scrollView.showsVerticalScrollIndicator = NO;
- _scrollView.showsHorizontalScrollIndicator = NO;
- _scrollView.delegate = self;
- _scrollView.scrollsToTop = NO;
- }
- }
- #pragma mark - 对外接口
- - (void)scrollToPage: (NSInteger)page
- {
- if (_currentPage != page || page == 0)
- {
- _currentPage = page;
- [self reloadData];
- }
-
- }
- - (void)reloadData
- {
- [self calculatePageNumbers];
- [self reloadPage];
- }
- - (UIView *)viewAtIndex: (NSInteger)index
- {
- UIView *view = nil;
- if (index >= 0 && index < [_pages count])
- {
- id obj = [_pages objectAtIndex:index];
- if ([obj isKindOfClass:[UIView class]])
- {
- view = obj;
- }
- }
- return view;
- }
- - (NSInteger)currentPage
- {
- return _currentPage;
- }
- - (NSInteger)pageInBound:(NSInteger)value min:(NSInteger)min max:(NSInteger)max{
- if (max < min) {
- max = min;
- }
- NSInteger bounded = value;
- if (bounded > max) {
- bounded = max;
- }
- if (bounded < min) {
- bounded = min;
- }
- return bounded;
- }
- #pragma mark - Page载入和销毁
- - (void)loadPagesForCurrentPage:(NSInteger)currentPage
- {
- NSUInteger count = [_pages count];
- if (count == 0)
- {
- return;
- }
- NSInteger first = [self pageInBound:currentPage - 1 min:0 max:count - 1];
- NSInteger last = [self pageInBound:currentPage + 1 min:0 max:count - 1];
- NSRange range = NSMakeRange(first, last - first + 1);
-
- for (NSUInteger index = 0; index < count; index++)
- {
- if (NSLocationInRange(index, range))
- {
- id obj = [_pages objectAtIndex:index];
- if (![obj isKindOfClass:[UIView class]])
- {
- if (_dataSource && [_dataSource respondsToSelector:@selector(pageView:viewInPage:)])
- {
- UIView *view = [_dataSource pageView:self viewInPage:index];
- [_pages replaceObjectAtIndex:index withObject:view];
- [self.scrollView addSubview:view];
- CGSize size = self.bounds.size;
- [view setFrame:CGRectMake(size.width * index, 0, size.width, size.height)];
- }
- else
- {
- assert(0);
- }
- }
-
- }
- else
- {
- id obj = [_pages objectAtIndex:index];
- if ([obj isKindOfClass:[UIView class]])
- {
- [obj removeFromSuperview];
- [_pages replaceObjectAtIndex:index withObject:[NSNull null]];
- }
- }
- }
- }
- - (void)calculatePageNumbers
- {
- NSInteger numberOfPages = 0;
- for (id obj in _pages)
- {
- if ([obj isKindOfClass:[UIView class]])
- {
- [(UIView *)obj removeFromSuperview];
- }
- }
- if(_dataSource && [_dataSource respondsToSelector:@selector(numberOfPages:)])
- {
- numberOfPages = [_dataSource numberOfPages:self];
- }
- self.pages = [NSMutableArray arrayWithCapacity:numberOfPages];
- for (NSInteger i = 0; i < numberOfPages; i ++)
- {
- [_pages addObject:[NSNull null]];
- }
- //注意,这里设置delegate是因为计算contentsize的时候会引起scrollViewDidScroll执行,修改currentpage的值,这样在贴图(举个例子)前面的分类页数比后面的分类页数多,前面的分类滚动到最后面一页后,再显示后面的分类,会显示不正确
- self.scrollView.delegate = nil;
- CGSize size = self.bounds.size;
- [self.scrollView setContentSize:CGSizeMake(size.width * numberOfPages, size.height)];
- self.scrollView.delegate = self;
- }
- - (void)reloadPage
- {
- //reload的时候尽量记住上次的位置
- if (_currentPage >= [_pages count])
- {
- _currentPage = [_pages count] - 1;
- }
- if (_currentPage < 0)
- {
- _currentPage = 0;
- }
-
- [self loadPagesForCurrentPage:_currentPage];
- [self raisePageIndexChangedDelegate];
- [self setNeedsLayout];
- }
- #pragma mark - ScrollView Delegate
- - (void)scrollViewDidScroll:(UIScrollView *)scrollView
- {
- CGFloat width = scrollView.bounds.size.width;
- CGFloat offsetX = scrollView.contentOffset.x;
- NSInteger page = (NSInteger)(fabs(offsetX / width));
- if (page >= 0 && page < [_pages count])
- {
- if (_currentPage == page) {
- return;
- }
- _currentPage = page;
- [self loadPagesForCurrentPage:_currentPage];
- }
-
- if (_pageViewDelegate && [_pageViewDelegate respondsToSelector:@selector(pageViewDidScroll:)])
- {
- [_pageViewDelegate pageViewDidScroll:self];
- }
- }
- - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
- {
- [self raisePageIndexChangedDelegate];
- }
- #pragma mark - 辅助方法
- - (void)raisePageIndexChangedDelegate
- {
- if (_pageViewDelegate && [_pageViewDelegate respondsToSelector:@selector(pageViewScrollEnd:currentIndex:totolPages:)])
- {
- [_pageViewDelegate pageViewScrollEnd:self
- currentIndex:_currentPage
- totolPages:[_pages count]];
- }
- }
- - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
- duration:(NSTimeInterval)duration
- {
- _scrollView.delegate = nil;
- _currentPageForRotation = _currentPage;
- }
- - (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
- duration:(NSTimeInterval)duration
- {
- CGSize size = self.bounds.size;
- _scrollView.contentSize = CGSizeMake(size.width * [_pages count], size.height);
- for (NSUInteger i = 0; i < [_pages count]; i++)
- {
- id obj = [_pages objectAtIndex:i];
- if ([obj isKindOfClass:[UIView class]])
- {
- [(UIView *)obj setFrame:CGRectMake(size.width * i, 0, size.width, size.height)];
-
- /*
- //这里有点ugly,先这样吧...
- if ([obj respondsToSelector:@selector(reset)])
- {
- [obj performSelector:@selector(reset)];
- }*/
- }
- }
- _scrollView.contentOffset = CGPointMake(_currentPageForRotation * self.bounds.size.width, 0);
- _scrollView.delegate = self;
-
- }
- @end
|