Advertise Mobile SDKs Books Events Forum News Social Networking Support Us
Follow @iphonedevsdk on Twitter

Interface 2, Advanced iOS
Mockup & Code Gen
($9.99)

Make your own iPhone apps
and run them live!
(free)

Pic Frame Dynamo: Photo Editing
($0.99)

Abiliator
($1.99)

Want your application or service advertised on iPhone Dev SDK?

Go Back   iPhone Dev SDK Forum > iPhone SDK Development Forums > iPhone SDK Development

Reply
 
LinkBack Thread Tools Display Modes
Old 07-03-2011, 05:33 PM   #1 (permalink)
Registered Member
 
Join Date: Jul 2011
Posts: 3
Drwall is on a distinguished road
Question UIScrollView - making a interactive book

Hello,

I'm making a interactive book that consists of about 30 pages, each being represented by a separate UIViewController subclass with a XIB for user interface. There are animations, sounds and interactive elements on most of the pages. I'd like to know what is the best practise in making a interactive application like this.

My PageController class is responsible for all the initialization and handling page changes. It creates a UIScrollView that displays the pages. In order to use as less memory as needed, I decided to store in memory a maximum amount of 3 pages at a time. I'm using 3 UIViewControllers - pagePrevious, pageCurrent and pageNext. Here is my code for the UIScrollView's scrolling part:

Code:
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
	int newPage = scrollView.contentOffset.x / self.view.frame.size.height + 1;
	
	if(newPage > currentPage) {
		if(pagePrevious != nil) {
			[pagePrevious.view removeFromSuperview];
			[pagePrevious release];
		}
		
		pagePrevious = pageCurrent;
		pageCurrent = pageNext;
		
		if(newPage < PAGE_COUNT) {
			NSString *pageClass;
			
			if(newPage < 9) {
				pageClass = [NSString stringWithFormat:@"Page0%d", (newPage + 1)];
			} else {
				pageClass = [NSString stringWithFormat:@"Page%d", (newPage + 1)];
			}
			
			pageNext = [[NSClassFromString(pageClass) alloc] init];
			pageNext.view.frame = CGRectMake(self.view.frame.size.height * newPage, 0, self.view.frame.size.height, self.view.frame.size.width);
			[scrollView addSubview:pageNext.view];
		}
	} else if(newPage < currentPage) {
		if(pageNext != nil) {
			[pageNext.view removeFromSuperview];
			[pageNext release];
		}
		
		pageNext = pageCurrent;
		pageCurrent = pagePrevious;
		
		if(newPage > 1) {
			NSString *pageClass;
			
			if(newPage < 11) {
				pageClass = [NSString stringWithFormat:@"Page0%d", (newPage - 1)];
			} else {
				pageClass = [NSString stringWithFormat:@"Page%d", (newPage - 1)];
			}
			
			pagePrevious = [[NSClassFromString(pageClass) alloc] init];
			pagePrevious.view.frame = CGRectMake(self.view.frame.size.height * (newPage - 2), 0, self.view.frame.size.height, self.view.frame.size.width);
			[scrollView addSubview:pagePrevious.view];
		}
	}
	
	currentPage = newPage;
}
Unfortunately, this code gives me some bad access issues. For example, when I change pages like this: 1 -> 2 -> 1 -> 2 -> 1, I get a blank screen instead of page 1 and then, when I slide to page 2, the application crashes (EXC_BAD_ACCESS). Having "[pagePrevious release]" and "[pageNext release]" removed solves the problem with the crashes but not with the blank screens. Having removed removeFromSuperview lines solves it entirely, but I'm aware of the fact that those viewControllers still reside in memory which was clearly not my point.

I don't really know what exactly is wrong with this code. My initialization method of PageController looks like:
Code:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
	self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
	
	if(self) {
		pageScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.height, self.view.frame.size.width)];
		pageScrollView.pagingEnabled = YES;
		pageScrollView.scrollEnabled = YES;
		pageScrollView.showsVerticalScrollIndicator = NO;
		pageScrollView.showsHorizontalScrollIndicator = NO;
		pageScrollView.bounces = NO;
		
		pagePrevious = nil;
		pageCurrent = [[Page01 alloc] init];
		pageNext = [[Page02 alloc] init];
		
		[pageCurrent.view setFrame:CGRectMake(0, 0, self.view.frame.size.height, self.view.frame.size.width)];
		[pageNext.view setFrame:CGRectMake(self.view.frame.size.height, 0, self.view.frame.size.height, self.view.frame.size.width)];
		
		[pageScrollView addSubview:pageCurrent.view];
		[pageScrollView addSubview:pageNext.view];
		
		pageScrollView.contentSize = CGSizeMake(self.view.frame.size.height * PAGE_COUNT, self.view.frame.size.width);
		
		[pageScrollView setDelegate:self];
		
		[self.view addSubview:pageScrollView];
		
		currentPage = 1;
	}
    
	return self;
}
By the way: should I use a different UIScrollView delegate method for handling page changes? And should I store more pages (like 2 previous and 2 next) at a time?

I hope you can help me out

Regards,
Drwall
Drwall is offline   Reply With Quote
Old 07-03-2011, 06:46 PM   #2 (permalink)
Registered Member
 
Join Date: Jul 2011
Posts: 3
Drwall is on a distinguished road
Default

Shame on me... This slightly altered code works just fine:

Code:
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
	if(scrollView != pageScrollView) return;
	
	int newPage = floor(scrollView.contentOffset.x / self.view.frame.size.height) + 1;
	
	if(newPage > currentPage) {
		if(pagePrevious != nil) {
			[pagePrevious.view removeFromSuperview];
			[pagePrevious release];
		}
		
		pagePrevious = pageCurrent;
		pageCurrent = pageNext;
		
		if(newPage < PAGE_COUNT) {
			NSString *pageClass;
			
			if(newPage < 9) {
				pageClass = [NSString stringWithFormat:@"Page0%d", (newPage + 1)];
			} else {
				pageClass = [NSString stringWithFormat:@"Page%d", (newPage + 1)];
			}
			
			pageNext = [[NSClassFromString(pageClass) alloc] initWithNibName:pageClass bundle:nil];
			pageNext.view.frame = CGRectMake(self.view.frame.size.height * newPage, 0, self.view.frame.size.height, self.view.frame.size.width);
			[scrollView addSubview:pageNext.view];
		} else {
			if(pageNext != nil) {
				pageNext = nil;
			}
		}
	} else if(newPage < currentPage) {
		if(pageNext != nil) {
			[pageNext.view removeFromSuperview];
			[pageNext release];
		}
		
		pageNext = pageCurrent;
		pageCurrent = pagePrevious;
		
		if(newPage > 1) {
			NSString *pageClass;
			
			if(newPage < 11) {
				pageClass = [NSString stringWithFormat:@"Page0%d", (newPage - 1)];
			} else {
				pageClass = [NSString stringWithFormat:@"Page%d", (newPage - 1)];
			}
			
			pagePrevious = [[NSClassFromString(pageClass) alloc] initWithNibName:pageClass bundle:nil];
			pagePrevious.view.frame = CGRectMake(self.view.frame.size.height * (newPage - 2), 0, self.view.frame.size.height, self.view.frame.size.width);
			[scrollView addSubview:pagePrevious.view];
		} else {
			if(pagePrevious != nil) {
				pagePrevious = nil;
			}
		}
	}
	
	currentPage = newPage;
}
But another question came to my mind - how could I prevent UIScrollView from scrolling "too fast"? When I swipe really quickly scrollViewDidEndDecelerating doesn't get called so pages don't get loaded and I end up getting blank screens. Should I change the delegate method or think about limiting the contentSize of UIScrollView?

Last edited by Drwall; 07-03-2011 at 06:47 PM. Reason: Typo
Drwall is offline   Reply With Quote
Old 07-03-2011, 07:07 PM   #3 (permalink)
Registered Member
 
Join Date: Jul 2011
Posts: 3
Drwall is on a distinguished road
Default

Alright... Never mind :O I feel really stupid but I solved that myself as well.

I simply used scrollViewDidScroll instead of scrollViewDidEndDecelerating.

Sorry for this mess. I hope I will at least help someone in the future...

Regards,
Drwall
Drwall is offline   Reply With Quote
Old 02-06-2012, 03:14 AM   #4 (permalink)
Registered Member
 
Join Date: Feb 2012
Posts: 2
Bhanu Birani is on a distinguished road
Default UIScrollView

Hi, I am also having the same piece of problem, but the difference is i am having the web views in place of views, so can u please attach a sample code of yours. So that i can figure out my error.
Bhanu Birani is offline   Reply With Quote
Old 02-06-2012, 07:13 AM   #5 (permalink)
Registered Member
 
Join Date: Feb 2012
Posts: 2
Bhanu Birani is on a distinguished road
Default UIScrollView

Thanks for your posts. I got the solution. Thanks a lot...
Bhanu Birani is offline   Reply With Quote
Reply

Bookmarks

Tags
interactive book, ipad, uiscrollview

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



» Advertisements
» Online Users: 349
9 members and 340 guests
apatsufas, chemistry, lendo, leostc, Leslie80, lzwasyc, MarkC, SamorodovAlex, VinceYuan
Most users ever online was 1,387, 04-10-2012 at 04:21 AM.
» Stats
Members: 175,664
Threads: 94,120
Posts: 402,898
Top Poster: BrianSlick (7,990)
Welcome to our newest member, Leslie80
Powered by vBadvanced CMPS v3.1.0

All times are GMT -5. The time now is 02:33 AM.
Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.0