Permalink
Browse files

Added support for vertical paging

  • Loading branch information...
1 parent 11b2d4a commit 04c5d42dbca87ca547f3864adbd3f8f4e78cf12c @RobPearson67 RobPearson67 committed Oct 14, 2011
@@ -8,7 +8,7 @@
@protocol ATPagingViewDelegate;
-// a wrapper around UIScrollView in (horizontal) paging mode, with an API similar to UITableView
+// a wrapper around UIScrollView in paging mode, with an API similar to UITableView
@interface ATPagingView : UIView {
// subviews
UIScrollView *_scrollView;
@@ -31,6 +31,7 @@
BOOL _rotationInProgress;
BOOL _scrollViewIsMoving;
BOOL _recyclingEnabled;
+ BOOL _horizontal;
}
@property(nonatomic, assign) IBOutlet id<ATPagingViewDelegate> delegate;
@@ -52,6 +53,7 @@
@property(nonatomic, assign, readonly) BOOL moving;
@property(nonatomic, assign) BOOL recyclingEnabled;
+@property(nonatomic, assign) BOOL horizontal; // default YES
- (void)reloadData; // must be called at least once to display something
View
@@ -39,6 +39,7 @@ @implementation ATPagingView
@synthesize moving=_scrollViewIsMoving;
@synthesize previousPageIndex=_previousPageIndex;
@synthesize recyclingEnabled=_recyclingEnabled;
+@synthesize horizontal=_horizontal;
#pragma mark -
@@ -52,6 +53,7 @@ - (void)commonInit {
_pagesToPreload = 1;
_recyclingEnabled = YES;
_firstLoadedPageIndex = _lastLoadedPageIndex = -1;
+ _horizontal = YES;
// We are using an oversized UIScrollView to implement interpage gaps,
// and we need it to clipped on the sides. This is important when
@@ -100,10 +102,21 @@ - (void)setGapBetweenPages:(CGFloat)value {
}
- (void)setPagesToPreload:(NSInteger)value {
+ BOOL reconfigure = _pagesToPreload != value;
_pagesToPreload = value;
- [self configurePages];
+ if (reconfigure) {
+ [self configurePages];
+ }
}
+-(void)setHorizontal:(BOOL)value {
+ BOOL reconfigure = _horizontal != value;
+ _horizontal = value;
+ if (reconfigure) {
+ [self layoutIfNeeded]; // force call to layoutSubview to set _scrollView.frame
+ [self configurePages];
+ }
+}
#pragma mark -
#pragma mark Data
@@ -132,8 +145,11 @@ - (UIView *)viewForPageAtIndex:(NSUInteger)index {
}
- (void)configurePages {
- if (_scrollView.frame.size.width <= _gapBetweenPages + 1e-6)
+ if (_horizontal && (_scrollView.frame.size.width <= _gapBetweenPages + 1e-6)) {
return; // not our time yet
+ } else if (_scrollView.frame.size.height <= _gapBetweenPages + 1e-6) {
+ return; // not our time yet
+ }
if (_pageCount == 0 && _currentPageIndex > 0)
return; // still not our time
@@ -144,22 +160,37 @@ - (void)configurePages {
// to avoid hiccups while scrolling, do not preload invisible pages temporarily
BOOL quickMode = (_scrollViewIsMoving && _pagesToPreload > 0);
- CGSize contentSize = CGSizeMake(_scrollView.frame.size.width * _pageCount, _scrollView.frame.size.height);
+ CGSize contentSize;
+ if (_horizontal) {
+ contentSize = CGSizeMake(_scrollView.frame.size.width * _pageCount, _scrollView.frame.size.height);
+ } else {
+ contentSize = CGSizeMake(_scrollView.frame.size.width, _scrollView.frame.size.height * _pageCount);
+ }
+
if (!CGSizeEqualToSize(_scrollView.contentSize, contentSize)) {
#ifdef AT_PAGING_VIEW_TRACE_LAYOUT
NSLog(@"configurePages: _scrollView.frame == %@, setting _scrollView.contentSize = %@",
NSStringFromCGRect(_scrollView.frame), NSStringFromCGSize(contentSize));
#endif
_scrollView.contentSize = contentSize;
- _scrollView.contentOffset = CGPointMake(_scrollView.frame.size.width * _currentPageIndex, 0);
+ if (_horizontal) {
+ _scrollView.contentOffset = CGPointMake(_scrollView.frame.size.width * _currentPageIndex, 0);
+ } else {
+ _scrollView.contentOffset = CGPointMake(0, _scrollView.frame.size.height * _currentPageIndex);
+ }
} else {
#ifdef AT_PAGING_VIEW_TRACE_LAYOUT
NSLog(@"configurePages: _scrollView.frame == %@", NSStringFromCGRect(_scrollView.frame));
#endif
}
CGRect visibleBounds = _scrollView.bounds;
- NSInteger newPageIndex = MIN(MAX(floorf(CGRectGetMidX(visibleBounds) / CGRectGetWidth(visibleBounds)), 0), _pageCount - 1);
+ NSInteger newPageIndex;
+ if (_horizontal) {
+ newPageIndex = MIN(MAX(floorf(CGRectGetMidX(visibleBounds) / CGRectGetWidth(visibleBounds)), 0), _pageCount - 1);
+ } else {
+ newPageIndex = MIN(MAX(floorf(CGRectGetMidY(visibleBounds) / CGRectGetHeight(visibleBounds)), 0), _pageCount - 1);
+ }
#ifdef AT_PAGING_VIEW_TRACE_LAYOUT
NSLog(@"newPageIndex == %d", newPageIndex);
#endif
@@ -279,15 +310,24 @@ - (void)willAnimateRotation {
//
// So we set the new size, but keep the old position here.
CGSize pageSize = _scrollView.frame.size;
- [self viewForPageAtIndex:_currentPageIndex].frame = CGRectMake(_scrollView.contentOffset.x + _gapBetweenPages/2, 0, pageSize.width - _gapBetweenPages, pageSize.height);
+ if (_horizontal) {
+ [self viewForPageAtIndex:_currentPageIndex].frame = CGRectMake(_scrollView.contentOffset.x + _gapBetweenPages/2, 0, pageSize.width - _gapBetweenPages, pageSize.height);
+ } else {
+ [self viewForPageAtIndex:_currentPageIndex].frame = CGRectMake(0, _scrollView.contentOffset.y + _gapBetweenPages/2, pageSize.width, pageSize.height - _gapBetweenPages);
+ }
}
- (void)didRotate {
// Adjust frames according to the new page size - this does not cause any visible
// changes, because we move the pages and adjust contentOffset simultaneously.
for (UIView *view in _visiblePages)
[self configurePage:view forIndex:view.tag];
- _scrollView.contentOffset = CGPointMake(_currentPageIndex * _scrollView.frame.size.width, 0);
+
+ if (_horizontal) {
+ _scrollView.contentOffset = CGPointMake(_currentPageIndex * _scrollView.frame.size.width, 0);
+ } else {
+ _scrollView.contentOffset = CGPointMake(0, _currentPageIndex * _scrollView.frame.size.height);
+ }
_rotationInProgress = NO;
@@ -302,8 +342,10 @@ - (void)setCurrentPageIndex:(NSInteger)newPageIndex {
#ifdef AT_PAGING_VIEW_TRACE_LAYOUT
NSLog(@"setCurrentPageIndex(%d): _scrollView.frame == %@", newPageIndex, NSStringFromCGRect(_scrollView.frame));
#endif
- if (_scrollView.frame.size.width > 0 && fabsf(_scrollView.frame.origin.x - (-_gapBetweenPages/2)) < 1e-6) {
+ if (_horizontal && (_scrollView.frame.size.width > 0 && fabsf(_scrollView.frame.origin.x - (-_gapBetweenPages/2)) < 1e-6) ) {
_scrollView.contentOffset = CGPointMake(_scrollView.frame.size.width * newPageIndex, 0);
+ } else if (_scrollView.frame.size.height > 0 && fabsf(_scrollView.frame.origin.y - (-_gapBetweenPages/2)) < 1e-6) {
+ _scrollView.contentOffset = CGPointMake(0, _scrollView.frame.size.height * newPageIndex);
}
_currentPageIndex = newPageIndex;
}
@@ -324,23 +366,40 @@ - (void)layoutSubviews {
_scrollView.frame = newFrame;
}
- if (oldFrame.size.width != 0 && _scrollView.frame.size.width != oldFrame.size.width) {
- // rotation is in progress, don't do any adjustments just yet
- } else if (oldFrame.size.height != _scrollView.frame.size.height) {
- // some other height change (the initial change from 0 to some specific size,
- // or maybe an in-call status bar has appeared or disappeared)
- [self configurePages];
+ if (_horizontal) {
+ if (oldFrame.size.width != 0 && _scrollView.frame.size.width != oldFrame.size.width) {
+ // rotation is in progress, don't do any adjustments just yet
+ } else if (oldFrame.size.height != _scrollView.frame.size.height) {
+ // some other height change (the initial change from 0 to some specific size,
+ // or maybe an in-call status bar has appeared or disappeared)
+ [self configurePages];
+ }
+ } else {
+ if (oldFrame.size.height != 0 && _scrollView.frame.size.height != oldFrame.size.height) {
+ // rotation is in progress, don't do any adjustments just yet
+ } else if (oldFrame.size.width != _scrollView.frame.size.width) {
+ // some other width change ?
+ [self configurePages];
+ }
}
}
- (NSInteger)firstVisiblePageIndex {
CGRect visibleBounds = _scrollView.bounds;
- return MAX(floorf(CGRectGetMinX(visibleBounds) / CGRectGetWidth(visibleBounds)), 0);
+ if (_horizontal) {
+ return MAX(floorf(CGRectGetMinX(visibleBounds) / CGRectGetWidth(visibleBounds)), 0);
+ } else {
+ return MAX(floorf(CGRectGetMinY(visibleBounds) / CGRectGetHeight(visibleBounds)), 0);
+ }
}
- (NSInteger)lastVisiblePageIndex {
CGRect visibleBounds = _scrollView.bounds;
- return MIN(floorf((CGRectGetMaxX(visibleBounds)-1) / CGRectGetWidth(visibleBounds)), _pageCount - 1);
+ if (_horizontal) {
+ return MIN(floorf((CGRectGetMaxX(visibleBounds)-1) / CGRectGetWidth(visibleBounds)), _pageCount - 1);
+ } else {
+ return MIN(floorf((CGRectGetMaxY(visibleBounds)-1) / CGRectGetHeight(visibleBounds)), _pageCount - 1);
+ }
}
- (NSInteger)firstLoadedPageIndex {
@@ -353,16 +412,24 @@ - (NSInteger)lastLoadedPageIndex {
- (CGRect)frameForScrollView {
CGSize size = self.bounds.size;
- return CGRectMake(-_gapBetweenPages/2, 0, size.width + _gapBetweenPages, size.height);
+ if (_horizontal) {
+ return CGRectMake(-_gapBetweenPages/2, 0, size.width + _gapBetweenPages, size.height);
+ } else {
+ return CGRectMake(0, -_gapBetweenPages/2, size.width, size.height + _gapBetweenPages);
+ }
}
// not public because this is in scroll view coordinates
- (CGRect)frameForPageAtIndex:(NSUInteger)index {
CGFloat pageWidthWithGap = _scrollView.frame.size.width;
+ CGFloat pageHeightWithGap = _scrollView.frame.size.height;
CGSize pageSize = self.bounds.size;
- return CGRectMake(pageWidthWithGap * index + _gapBetweenPages/2,
- 0, pageSize.width, pageSize.height);
+ if (_horizontal) {
+ return CGRectMake(pageWidthWithGap * index + _gapBetweenPages/2, 0, pageSize.width, pageSize.height);
+ } else {
+ return CGRectMake(0, pageHeightWithGap * index + _gapBetweenPages/2, pageSize.width, pageSize.height);
+ }
}
@@ -14,6 +14,7 @@ - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interface
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
+ self.pagingView.horizontal = NO;
self.pagingView.currentPageIndex = 3;
[self currentPageDidChangeInPagingView:self.pagingView];
}

0 comments on commit 04c5d42

Please sign in to comment.