Your interface.
#import <UIKit/UIKit.h>
@interface ViewSlider : UIViewController {
NSMutableArray *_pageViews;
UIScrollView *_scrollView;
NSUInteger _currentPageIndex;
BOOL _rotationInProgress;
int m_itotalPages;
}
-(void)unloadPages;
- (CGSize)pageSize;
- (void)loadScrollView;
- (NSUInteger)numberOfPages;
- (void)currentPageIndexDidChange;
- (void)layoutPage:(NSUInteger)pageIndex;
- (BOOL)isPageLoaded:(NSUInteger)pageIndex;
- (UIView *)viewForPage:(NSUInteger)pageIndex;
- (UIView *)loadViewForPage:(NSUInteger)pageIndex;
- (CGRect)alignView:(UIView *)view forPage:(NSUInteger)pageIndex;
@end
Here is the implementation
pragma mark -
@interface ViewSlider () <UIScrollViewDelegate>
@property (nonatomic, retain) NSMutableArray *pageViews;
@property (nonatomic, retain) UIScrollView *scrollView;
@property (nonatomic, readonly) NSUInteger currentPageIndex;
@end
#pragma mark -
@implementation ViewSlider
#pragma mark -
@synthesize pageViews=_pageViews, scrollView=_scrollView, currentPageIndex=_currentPageIndex;
#pragma mark -
- (void)viewDidLoad {
m_itotalPages=//set number of views ;
//to initialize Scrollview
[self loadScrollView];
self.pageViews = [NSMutableArray array];
// to save time and memory, we won't load the page views immediately
for (NSUInteger i = 0; i < m_itotalPages; ++i)
[self.pageViews addObject:[NSNull null]];
}
- (void)viewWillAppear:(BOOL)animated {
if(m_itotalPages !=0) {
_currentPageIndex=0;
[self currentPageIndexDidChange];
self.scrollView.contentOffset = CGPointMake(_currentPageIndex * [self pageSize].width, 0);
}
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return UIDeviceOrientationIsPortrait(interfaceOrientation)||UIDeviceOrientationIsLandscape(interfaceOrientation);
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
_rotationInProgress = YES;
//to remove all views for memory managment
[self unloadPages];
[[self.scrollView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];
[[self.scrollView subviews] makeObjectsPerformSelector:@selector(release)];
[self.pageViews removeAllObjects];
for (NSUInteger i = 0; i < m_itotalPages; ++i)
[self.pageViews addObject:[NSNull null]];
//to load page views
[self currentPageIndexDidChange];
// hide other page views because they may overlap the current page during animation
for (NSUInteger pageIndex = 0; pageIndex < [self numberOfPages]; ++pageIndex)
if ([self isPageLoaded:pageIndex])
[self viewForPage:pageIndex].hidden = (pageIndex != _currentPageIndex);
}
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
// resize and reposition the page view, but use the current contentOffset as page origin
// (note that the scrollview has already been resized by the time this method is called)
UIView *pageView = [self viewForPage:_currentPageIndex];
[self viewForPage:_currentPageIndex].frame = [self alignView:pageView forPage:_currentPageIndex];
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
self.scrollView.contentMode=UIViewContentModeScaleAspectFill;
self.scrollView.contentOffset = CGPointMake(_currentPageIndex * [self pageSize].width,0);
// unhide
for (NSUInteger pageIndex = 0; pageIndex < [self numberOfPages]; ++pageIndex)
if ([self isPageLoaded:pageIndex])
[self viewForPage:pageIndex].hidden = NO;
_rotationInProgress = NO;
}
#pragma mark -
#pragma mark View methods
/**************************************************************************************
/* Method Name : loadScrollView
/* Purpose : to load Scrollview
/* Parameters : nil
/* Return Value : void
/***************************************************************************************/
- (void)loadScrollView {
self.scrollView = [[[UIScrollView alloc] init] autorelease];
self.scrollView.delegate = self;
self.scrollView.pagingEnabled = YES;
self.scrollView.showsHorizontalScrollIndicator = NO;
self.scrollView.showsVerticalScrollIndicator = NO;
self.scrollView.bounces=NO;
self.scrollView.frame=self.view.frame;
self.scrollView.contentMode=UIViewContentModeScaleAspectFill;
self.view = self.scrollView;
}
#pragma mark -
- (void)layoutPage:(NSUInteger)pageIndex {
@try {
UIView *pageView = [self viewForPage:pageIndex];
pageView.contentMode=UIViewContentModeScaleAspectFill;
pageView.frame = [self alignView:pageView forPage:pageIndex];
}
@catch (NSException *e) {
//NSLog(@"layoutPages");
}
}
- (CGRect)alignView:(UIView *)view forPage:(NSUInteger)pageIndex {
CGSize pageSize = [self pageSize];
self.scrollView.frame=CGRectMake(0, 0, pageSize.width,pageSize.height);
self.scrollView.contentSize=CGSizeMake(([self numberOfPages]*pageSize.width), pageSize.height);
return CGRectMake(pageIndex * pageSize.width,0,pageSize.width,pageSize.height);
}
#pragma mark -
- (NSUInteger)numberOfPages {
return m_itotalPages;
}
- (CGSize)pageSize {
return CGSizeMake(768,1024);
}
- (BOOL)isPageLoaded:(NSUInteger)pageIndex {
return [self.pageViews objectAtIndex:pageIndex] != [NSNull null];
}
- (UIView *)loadViewForPage:(NSUInteger)pageIndex {
UIView *controller=[[UIView alloc] init];
controller.backgroundColor=[UIColor blueColor];
return controller;
}
- (UIView *)viewForPage:(NSUInteger)pageIndex {
NSParameterAssert(pageIndex >= 0);
NSParameterAssert(pageIndex < [self numberOfPages]);
UIView *pageView;
@try{
if ([self.pageViews objectAtIndex:pageIndex] == [NSNull null]) {
pageView = [self loadViewForPage:pageIndex];
[self.pageViews replaceObjectAtIndex:pageIndex withObject:pageView];
[self.scrollView addSubview:pageView];
[pageView release];
} else {
pageView = [self.pageViews objectAtIndex:pageIndex];
}
}
@catch (NSException *e) {
//NSLog(@"Exception viewForPage");
}
return pageView;
}
- (void)currentPageIndexDidChange {
@try{
[self layoutPage:_currentPageIndex];
if (_currentPageIndex+1 < [self numberOfPages])
[self layoutPage:_currentPageIndex+1];
if (_currentPageIndex > 0)
[self layoutPage:_currentPageIndex-1];
[self unloadPages];
self.navigationItem.title = [NSString stringWithFormat:@"Page %d of %d", 1+_currentPageIndex, [self numberOfPages]];
}
@catch (NSException * e) {
//NSLog(@"currentPageIndexDidChange");
}
}
-(void)unloadPages {
@try {
if (self.pageViews) {
// unload non-visible pages in case the memory is scarse
for (NSUInteger pageIndex = 0; pageIndex < [self numberOfPages]; ++pageIndex) {
if (pageIndex < _currentPageIndex-1 || pageIndex > _currentPageIndex+1)
if ([self isPageLoaded:pageIndex]) {
if(pageIndex==0 || pageIndex ==1)
continue;
UIView *pageView = [self.pageViews objectAtIndex:pageIndex];
[[pageView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];
[pageView removeFromSuperview];
if(pageView)
pageView=nil;
[self.pageViews replaceObjectAtIndex:pageIndex withObject:[NSNull null]];
}
}
}
}
@catch (NSException * e) {
//NSLog(@"Exception Unload");
}
@finally {
}
}
#pragma mark -
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
@try {
if (_rotationInProgress)
return; // UIScrollView layoutSubviews code adjusts contentOffset, breaking our logic
CGSize pageSize = [self pageSize];
NSUInteger newPageIndex = (self.scrollView.contentOffset.x + pageSize.width / 2) / pageSize.width;
if (newPageIndex == _currentPageIndex) return;
// could happen when scrolling fast
if (newPageIndex < 0)
newPageIndex = 0;
else if (newPageIndex >= [self numberOfPages])
newPageIndex = [self numberOfPages] - 1;
_currentPageIndex = newPageIndex;
[self currentPageIndexDidChange];
}
@catch (NSException * e) {
//NSLog(@"DIDSCROLL");
}
}
#pragma mark -
#pragma mark View Destructors
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
[self unloadPages];
}
- (void)viewDidUnload {
self.pageViews = nil;
self.scrollView = nil;
}
- (void)dealloc {
[[self.scrollView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];
self.scrollView=nil;
[self.pageViews removeAllObjects];
[self.pageViews release];
self.pageViews=nil;
[self viewDidUnload];
[super dealloc];
}
@end
#import <UIKit/UIKit.h>
@interface ViewSlider : UIViewController {
NSMutableArray *_pageViews;
UIScrollView *_scrollView;
NSUInteger _currentPageIndex;
BOOL _rotationInProgress;
int m_itotalPages;
}
-(void)unloadPages;
- (CGSize)pageSize;
- (void)loadScrollView;
- (NSUInteger)numberOfPages;
- (void)currentPageIndexDidChange;
- (void)layoutPage:(NSUInteger)pageIndex;
- (BOOL)isPageLoaded:(NSUInteger)pageIndex;
- (UIView *)viewForPage:(NSUInteger)pageIndex;
- (UIView *)loadViewForPage:(NSUInteger)pageIndex;
- (CGRect)alignView:(UIView *)view forPage:(NSUInteger)pageIndex;
@end
Here is the implementation
pragma mark -
@interface ViewSlider () <UIScrollViewDelegate>
@property (nonatomic, retain) NSMutableArray *pageViews;
@property (nonatomic, retain) UIScrollView *scrollView;
@property (nonatomic, readonly) NSUInteger currentPageIndex;
@end
#pragma mark -
@implementation ViewSlider
#pragma mark -
@synthesize pageViews=_pageViews, scrollView=_scrollView, currentPageIndex=_currentPageIndex;
#pragma mark -
- (void)viewDidLoad {
m_itotalPages=//set number of views ;
//to initialize Scrollview
[self loadScrollView];
self.pageViews = [NSMutableArray array];
// to save time and memory, we won't load the page views immediately
for (NSUInteger i = 0; i < m_itotalPages; ++i)
[self.pageViews addObject:[NSNull null]];
}
- (void)viewWillAppear:(BOOL)animated {
if(m_itotalPages !=0) {
_currentPageIndex=0;
[self currentPageIndexDidChange];
self.scrollView.contentOffset = CGPointMake(_currentPageIndex * [self pageSize].width, 0);
}
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return UIDeviceOrientationIsPortrait(interfaceOrientation)||UIDeviceOrientationIsLandscape(interfaceOrientation);
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
_rotationInProgress = YES;
//to remove all views for memory managment
[self unloadPages];
[[self.scrollView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];
[[self.scrollView subviews] makeObjectsPerformSelector:@selector(release)];
[self.pageViews removeAllObjects];
for (NSUInteger i = 0; i < m_itotalPages; ++i)
[self.pageViews addObject:[NSNull null]];
//to load page views
[self currentPageIndexDidChange];
// hide other page views because they may overlap the current page during animation
for (NSUInteger pageIndex = 0; pageIndex < [self numberOfPages]; ++pageIndex)
if ([self isPageLoaded:pageIndex])
[self viewForPage:pageIndex].hidden = (pageIndex != _currentPageIndex);
}
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
// resize and reposition the page view, but use the current contentOffset as page origin
// (note that the scrollview has already been resized by the time this method is called)
UIView *pageView = [self viewForPage:_currentPageIndex];
[self viewForPage:_currentPageIndex].frame = [self alignView:pageView forPage:_currentPageIndex];
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
self.scrollView.contentMode=UIViewContentModeScaleAspectFill;
self.scrollView.contentOffset = CGPointMake(_currentPageIndex * [self pageSize].width,0);
// unhide
for (NSUInteger pageIndex = 0; pageIndex < [self numberOfPages]; ++pageIndex)
if ([self isPageLoaded:pageIndex])
[self viewForPage:pageIndex].hidden = NO;
_rotationInProgress = NO;
}
#pragma mark -
#pragma mark View methods
/**************************************************************************************
/* Method Name : loadScrollView
/* Purpose : to load Scrollview
/* Parameters : nil
/* Return Value : void
/***************************************************************************************/
- (void)loadScrollView {
self.scrollView = [[[UIScrollView alloc] init] autorelease];
self.scrollView.delegate = self;
self.scrollView.pagingEnabled = YES;
self.scrollView.showsHorizontalScrollIndicator = NO;
self.scrollView.showsVerticalScrollIndicator = NO;
self.scrollView.bounces=NO;
self.scrollView.frame=self.view.frame;
self.scrollView.contentMode=UIViewContentModeScaleAspectFill;
self.view = self.scrollView;
}
#pragma mark -
- (void)layoutPage:(NSUInteger)pageIndex {
@try {
UIView *pageView = [self viewForPage:pageIndex];
pageView.contentMode=UIViewContentModeScaleAspectFill;
pageView.frame = [self alignView:pageView forPage:pageIndex];
}
@catch (NSException *e) {
//NSLog(@"layoutPages");
}
}
- (CGRect)alignView:(UIView *)view forPage:(NSUInteger)pageIndex {
CGSize pageSize = [self pageSize];
self.scrollView.frame=CGRectMake(0, 0, pageSize.width,pageSize.height);
self.scrollView.contentSize=CGSizeMake(([self numberOfPages]*pageSize.width), pageSize.height);
return CGRectMake(pageIndex * pageSize.width,0,pageSize.width,pageSize.height);
}
#pragma mark -
- (NSUInteger)numberOfPages {
return m_itotalPages;
}
- (CGSize)pageSize {
return CGSizeMake(768,1024);
}
- (BOOL)isPageLoaded:(NSUInteger)pageIndex {
return [self.pageViews objectAtIndex:pageIndex] != [NSNull null];
}
- (UIView *)loadViewForPage:(NSUInteger)pageIndex {
UIView *controller=[[UIView alloc] init];
controller.backgroundColor=[UIColor blueColor];
return controller;
}
- (UIView *)viewForPage:(NSUInteger)pageIndex {
NSParameterAssert(pageIndex >= 0);
NSParameterAssert(pageIndex < [self numberOfPages]);
UIView *pageView;
@try{
if ([self.pageViews objectAtIndex:pageIndex] == [NSNull null]) {
pageView = [self loadViewForPage:pageIndex];
[self.pageViews replaceObjectAtIndex:pageIndex withObject:pageView];
[self.scrollView addSubview:pageView];
[pageView release];
} else {
pageView = [self.pageViews objectAtIndex:pageIndex];
}
}
@catch (NSException *e) {
//NSLog(@"Exception viewForPage");
}
return pageView;
}
- (void)currentPageIndexDidChange {
@try{
[self layoutPage:_currentPageIndex];
if (_currentPageIndex+1 < [self numberOfPages])
[self layoutPage:_currentPageIndex+1];
if (_currentPageIndex > 0)
[self layoutPage:_currentPageIndex-1];
[self unloadPages];
self.navigationItem.title = [NSString stringWithFormat:@"Page %d of %d", 1+_currentPageIndex, [self numberOfPages]];
}
@catch (NSException * e) {
//NSLog(@"currentPageIndexDidChange");
}
}
-(void)unloadPages {
@try {
if (self.pageViews) {
// unload non-visible pages in case the memory is scarse
for (NSUInteger pageIndex = 0; pageIndex < [self numberOfPages]; ++pageIndex) {
if (pageIndex < _currentPageIndex-1 || pageIndex > _currentPageIndex+1)
if ([self isPageLoaded:pageIndex]) {
if(pageIndex==0 || pageIndex ==1)
continue;
UIView *pageView = [self.pageViews objectAtIndex:pageIndex];
[[pageView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];
[pageView removeFromSuperview];
if(pageView)
pageView=nil;
[self.pageViews replaceObjectAtIndex:pageIndex withObject:[NSNull null]];
}
}
}
}
@catch (NSException * e) {
//NSLog(@"Exception Unload");
}
@finally {
}
}
#pragma mark -
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
@try {
if (_rotationInProgress)
return; // UIScrollView layoutSubviews code adjusts contentOffset, breaking our logic
CGSize pageSize = [self pageSize];
NSUInteger newPageIndex = (self.scrollView.contentOffset.x + pageSize.width / 2) / pageSize.width;
if (newPageIndex == _currentPageIndex) return;
// could happen when scrolling fast
if (newPageIndex < 0)
newPageIndex = 0;
else if (newPageIndex >= [self numberOfPages])
newPageIndex = [self numberOfPages] - 1;
_currentPageIndex = newPageIndex;
[self currentPageIndexDidChange];
}
@catch (NSException * e) {
//NSLog(@"DIDSCROLL");
}
}
#pragma mark -
#pragma mark View Destructors
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
[self unloadPages];
}
- (void)viewDidUnload {
self.pageViews = nil;
self.scrollView = nil;
}
- (void)dealloc {
[[self.scrollView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];
self.scrollView=nil;
[self.pageViews removeAllObjects];
[self.pageViews release];
self.pageViews=nil;
[self viewDidUnload];
[super dealloc];
}
@end
0 comments:
Post a Comment