Warning: This is my first iPhone Application so there's a lot of cargo cult programming going on here.
I've googled, searched stackoverflow, read books, and changed code over and over in an attempt to fix this and I can't. I'm using the PageScrollView class found in "iPhone SDK Application Development" by Jonathan Zdziarski. It is a class that provides a view of 5 images (or more), loading 3 into memory at one time. I want 3 of these PageScrollViews on the screen at once stacked on top of each other. A top row of 5 images to scroll horizontally through, a middle row of images to scroll horizontally through, and a bottom row of images to scroll horizontally through all while the phone is held in portrait position, I'm completely switching views in landscape mode.
PageScrollView as modified by me, anything commented out was at one point uncommented in an attempt to make this work. I tried to comment out as much as I could to isolate the problem:
#import "PageScrollView.h"
@implementation PageScrollView
-(id)initWithFrame:(CGRect)frame {
self = [ super initWithFrame: frame ];
if (self != nil) {
_pages = nil;
_zeroPage = 0;
_pageRegion = CGRectMake(frame.origin.x, frame.origin.y, frame.size.width, frame.size.height);
//_controlRegion = CGRectMake(frame.origin.x,frame.size.height/2, frame.size.width, 0);
self.delegate = nil;
scrollView = [ [ UIScrollView alloc ] initWithFrame: _pageRegion ];
scrollView.pagingEnabled = YES;
scrollView.delegate = self;
[ scrollView setContentOffset: CGPointMake(frame.origin.x, frame.origin.y) ];
[ scrollView setContentSize: CGSizeMake(_pageRegion.size.width,_pageRegion.size.height) ];
[ scrollView setContentInset : UIEdgeInsetsMake(0.0,80.0,0,0) ];
[ self addSubview: scrollView ];
//pageControl = [ [ UIPageControl alloc ] initWithFrame: _controlRegion ];
//[ pageControl addTarget: self action: @selector(pageControlDidChange:) forControlEvents: UIControlEventValueChanged ];
//[ self addSubview: pageControl ];
}
return self;
}
-(void)setPages:(NSMutableArray *)pages {
if (pages != nil) {
for(int i=0;i<[_pages count];i++) {
[ [ _pages objectAtIndex: i ] removeFromSuperview ];
}
}
_pages = pages;
//scrollView.contentOffset = CGPointMake(0.0, 0.0);
scrollView.contentOffset = CGPointMake(0.0, _pageRegion.origin.y);
if ([ _pages count] < 3) {
scrollView.contentSize = CGSizeMake(_pageRegion.size.width * [ _pages count ], _pageRegion.size.height);
} else {
scrollView.contentSize = CGSizeMake(_pageRegion.size.width * 3, _pageRegion.size.height);
scrollView.showsHorizontalScrollIndicator = NO;
}
pageControl.numberOfPages = [ _pages count ];
pageControl.currentPage = 0;
[ self layoutViews ];
}
- (void)layoutViews {
if ([ _pages count ] <= 3) {
for(int i=0;i<[ _pages count];i++) {
UIView *page = [ _pages objectAtIndex: i ];
//CGRect bounds = page.bounds;
//CGRect frame = CGRectMake(_pageRegion.size.width * i, 0.0, _pageRegion.size.width, _pageRegion.size.height);
//CGRect frame = CGRectMake(_pageRegion.size.width * i, _pageRegion.origin.y+_pageRegion.size.height , _pageRegion.size.width, _pageRegion.size.height);
//page.frame = frame;
//page.bounds = bounds;
[ scrollView addSubview: page ];
}
return;
}
/* For more than 3 views, add them all hidden, layout according to page */
for(int i=0;i<[ _pages count];i++) {
UIView *page = [ _pages objectAtIndex: i ];
//CGRect bounds = page.bounds;
//CGRect frame = CGRectMake(0.0, 0.0, _pageRegion.size.width, _pageRegion.size.height);
//CGRect frame = CGRectMake(0.0, _pageRegion.origin.y+_pageRegion.size.height, _pageRegion.size.width, _pageRegion.size.height);
//page.frame = frame;
//page.bounds = bounds;
page.hidden = YES;
[ scrollView addSubview: page ];
}
[ self layoutScroller ];
}
- (void)layoutScroller {
UIView *page;
CGRect bounds, frame;
int pageNum = [ self getCurrentPage ];
if ([ _pages count ] <= 3)
return;
NSLog(@"Laying out scroller for page %d\n", pageNum);
/* Left boundary */
if (pageNum == 0) {
for(int i=0;i<3;i++) {
page = [ _pages objectAtIndex: i ];
bounds = page.bounds;
//frame = CGRectMake(_pageRegion.size.width * i, 0.0, _pageRegion.size.width, _pageRegion.size.height);
frame = CGRectMake(_pageRegion.size.width * i, 0.0, _pageRegion.size.width, _pageRegion.size.height);
NSLog(@"\tOffset for Page %d = %f\n", i, frame.origin.x);
page.frame = frame;
page.bounds = bounds;
page.hidden = NO;
}
page = [ _pages objectAtIndex: 3 ];
page.hidden = YES;
_zeroPage = 0;
}
/* Right boundary */
else if (pageNum == [ _pages count ] -1) {
for(int i=pageNum-2;i<=pageNum;i++) {
page = [ _pages objectAtIndex: i ];
bounds = page.bounds;
frame = CGRectMake(_pageRegion.size.width * (2-(pageNum-i)), 0.0, _pageRegion.size.width, _pageRegion.size.height);
NSLog(@"\tOffset for Page %d = %f\n", i, frame.origin.x);
page.frame = frame;
page.bounds = bounds;
page.hidden = NO;
}
page = [ _pages objectAtIndex: [ _pages count ]-3 ];
page.hidden = YES;
_zeroPage = pageNum - 2;
}
/* All middle pages */
else {
for(int i=pageNum-1; i<=pageNum+1; i++) {
page = [ _pages objectAtIndex: i ];
bounds = page.bounds;
frame = CGRectMake(_pageRegion.size.width * (i-(pageNum-1)), 0.0, _pageRegion.size.width, _pageRegion.size.height);
NSLog(@"\tOffset for Page %d = %f\n", i, frame.origin.x);
page.frame = frame;
page.bounds = bounds;
page.hidden = NO;
}
for(int i=0; i< [ _pages count ]; i++) {
if (i < pageNum-1 || i > pageNum + 1) {
page = [ _pages objectAtIndex: i ];
page.hidden = YES;
}
}
//scrollView.contentOffset = CGPointMake(_pageRegion.size.width, 0.0);
scrollView.contentOffset = CGPointMake(_pageRegion.size.width, 0.0);
_zeroPage = pageNum-1;
}
}
-(id)getDelegate {
return _delegate;
}
- (void)setDelegate:(id)delegate {
_delegate = delegate;
}
-(BOOL)getShowsPageControl {
return _showsPageControl;
}
-(void)setShowsPageControl:(BOOL)showsPageControl {
_showsPageControl = showsPageControl;
if (_showsPageControl == NO) {
//_pageRegion = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, self.frame.size.height);
pageControl.hidden = YES;
scrollView.frame = _pageRegion;
} else {
//_pageRegion = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, self.frame.size.height - 60.0);
//_pageRegion = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, self.frame.size.height);
pageControl.hidden = NO;
scrollView.frame = _pageRegion;
}
}
-(NSMutableArray *)getPages {
return _pages;
}
-(void)setCurrentPage:(int)page {
// [ scrollView setContentOffset: CGPointMake(0.0, 0.0) ];
[ scrollView setContentOffset: CGPointMake(0.0,_pageRegion.origin.y) ];
_zeroPage = page;
[ self layoutScroller ];
pageControl.currentPage = page;
}
-(int)getCurrentPage {
return (int) (scrollView.contentOffset.x / _pageRegion.size.width) + _zeroPage;
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
pageControl.currentPage = self.currentPage;
[ self layoutScroller ];
[ self notifyPageChange ];
}
-(void) pageControlDidChange: (id)sender
{
UIPageControl *control = (UIPageControl *) sender;
if (control == pageControl) {
//[ scrollView setContentOffset: CGPointMake(_pageRegion.size.width * (control.currentPage - _zeroPage), 0.0) animated: YES ];
[ scrollView setContentOffset: CGPointMake(_pageRegion.size.width * (control.currentPage - _zeroPage), 0.0) animated: YES ];
}
}
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView {
[ self layoutScroller ];
[ self notifyPageChange ];
}
-(void) notifyPageChange {
if (self.delegate != nil) {
// if ([ _delegate conformsToProtocol:@protocol(PageScrollViewDelegate) ]) {
if ([ _delegate respondsToSelector:@selector(pageScrollViewDidChangeCurrentPage:currentPage:) ]) {
[ self.delegate pageScrollViewDidChangeCurrentPage: (PageScrollView *)self currentPage: self.currentPage ];
}
// }
}
}
@end
Here is my loadview method from my ViewController class:
- (void)loadView {
[ super loadView ];
/* Load demo images for pages */
topPages = [ [ NSMutableArray alloc ] init ];
for(int i = 0; i < 5; i++) {
UIImage *image = [ [ UIImage alloc ] initWithData: [ NSData dataWithContentsOfURL: [ NSURL URLWithString: [ NSString stringWithFormat: @"http://www.zdziarski.com/demo/%d.png", i+1 ] ] ] ];
UIImageView *page = [ [ UIImageView alloc ] initWithFrame: CGRectMake(0,0,320,160) ] ;
page.image = image;
//page.bounds = CGRectMake(0.0, 0.0, 320, 160);
[ topPages addObject: page ];
}
CGRect viewBounds = [ [ UIScreen mainScreen ] applicationFrame ];
viewBounds.origin.y = 0.0;
portraitTopView = [ [ PageScrollView alloc ] initWithFrame: CGRectMake(0,0,320,160) ];
portraitTopView.pages = topPages;
portraitTopView.delegate = self;
//portraitTopView.showsPageControl = NO;
middlePages = [ [ NSMutableArray alloc ] init ];
for(int i = 0; i < 5; i++) {
UIImage *image = [ [ UIImage alloc ] initWithData: [ NSData dataWithContentsOfURL: [ NSURL URLWithString: [ NSString stringWithFormat: @"http://www.zdziarski.com/demo/%d.png", i+1 ] ] ] ];
UIImageView *page = [ [ UIImageView alloc ] initWithFrame: CGRectMake(0,0,320,160) ] ;
page.image = image;
//page.bounds = CGRectMake(0.0, 0.0, 320, 160);
[ middlePages addObject: page ];
}
portraitMiddleView = [ [ PageScrollView alloc ] initWithFrame: CGRectMake(0,80,320,160) ];
portraitMiddleView.pages = middlePages;
portraitMiddleView.delegate = self;
//portraitMiddleView.showsPageControl = NO;
bottomPages = [ [ NSMutableArray alloc ] init ];
for(int i = 0; i < 5; i++) {
UIImage *image = [ [ UIImage alloc ] initWithData: [ NSData dataWithContentsOfURL: [ NSURL URLWithString: [ NSString stringWithFormat: @"http://www.zdziarski.com/demo/%d.png", i+1 ] ] ] ];
UIImageView *page = [ [ UIImageView alloc ] initWithFrame: CGRectMake(0,0,320,160) ] ;
page.image = image;
//page.bounds = CGRectMake(0.0, 0.0, 320, 160);
[ bottomPages addObject: page ];
}
portraitBottomView = [ [ PageScrollView alloc ] initWithFrame: CGRectMake(0,160,320,160) ];
portraitBottomView.pages = bottomPages;
portraitBottomView.delegate = self;
//portraitBottomView.showsPageControl = NO;
portraitView = [ [ UIView alloc ] initWithFrame: viewBounds ];
[ portraitView addSubview: portraitTopView ];
[ portraitView addSubview: portraitMiddleView ];
[ portraitView addSubview: portraitBottomView ];
landscapeTextView = [ [ UITextView alloc ] initWithFrame: viewBounds ];
landscapeTextView.text = woahDizzy;
self.view = portraitView;
}
My problem is that the scroll areas (the parts of the screen I touch) don't seem to match up with the images. To get the images to display correctly, I'm using:
portraitTopView = [ [ PageScrollView alloc ] initWithFrame: CGRectMake(0,0,320,160) ];
portraitMiddleView = [ [ PageScrollView alloc ] initWithFrame: CGRectMake(0,80,320,160) ];
portraitBottomView = [ [ PageScrollView alloc ] initWithFrame: CGRectMake(0,160,320,160) ];
However, those numbers don't seem right to me. I feel the y values should be 0,160, and 320 respectively because I have 3 images that are each 160 pixels tall and (3x160=480), but when I set the y values to 0,160, and 320 the top image is at the top of the screen, the middle image is where the bottom image should be and the bottom image is way off the screen. But when I have the y values set to 0,80, and 160 the images display correctly, but the scroll areas do work (I have a gut feeling that scroll areas or touch areas whatever they are called are being set above the images).
Does anyone have any ideas?