Skip to content

Commit f82398a

Browse files
committed
first commit
0 parents  commit f82398a

13 files changed

+1246
-0
lines changed

Classes/MyViewController.h

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//
2+
// MyViewController.h
3+
// ScrollViewWithPaging
4+
//
5+
// Created by CECID on 18/05/2010.
6+
// Copyright 2010 __MyCompanyName__. All rights reserved.
7+
//
8+
9+
#import <UIKit/UIKit.h>
10+
11+
12+
@interface MyViewController : UIViewController {
13+
UILabel *pageNumberLabel;
14+
int pageNumber;
15+
}
16+
17+
@property (nonatomic, retain) IBOutlet UILabel *pageNumberLabel;
18+
19+
- (id)initWithPageNumber:(int)page;
20+
21+
@end

Classes/MyViewController.m

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
//
2+
// MyViewController.m
3+
// ScrollViewWithPaging
4+
//
5+
// Created by CECID on 18/05/2010.
6+
// Copyright 2010 __MyCompanyName__. All rights reserved.
7+
//
8+
9+
#import "MyViewController.h"
10+
11+
static NSArray *__pageControlColorList = nil;
12+
13+
@implementation MyViewController
14+
15+
@synthesize pageNumberLabel;
16+
17+
// Creates the color list the first time this method is invoked. Returns one color object from the list.
18+
+ (UIColor *)pageControlColorWithIndex:(NSUInteger)index {
19+
if (__pageControlColorList == nil) {
20+
__pageControlColorList = [[NSArray alloc] initWithObjects:[UIColor redColor], [UIColor greenColor], [UIColor magentaColor],
21+
[UIColor blueColor], [UIColor orangeColor], [UIColor brownColor], [UIColor grayColor], nil];
22+
}
23+
24+
// Mod the index by the list length to ensure access remains in bounds.
25+
return [__pageControlColorList objectAtIndex:index % [__pageControlColorList count]];
26+
}
27+
28+
// Load the view nib and initialize the pageNumber ivar.
29+
- (id)initWithPageNumber:(int)page {
30+
if (self = [super initWithNibName:@"MyViewController" bundle:nil]) {
31+
pageNumber = page;
32+
}
33+
return self;
34+
}
35+
36+
- (void)dealloc {
37+
[pageNumberLabel release];
38+
[super dealloc];
39+
}
40+
41+
// Set the label and background color when the view has finished loading.
42+
- (void)viewDidLoad {
43+
pageNumberLabel.text = [NSString stringWithFormat:@"Page %d", pageNumber + 1];
44+
self.view.backgroundColor = [MyViewController pageControlColorWithIndex:pageNumber];
45+
}
46+
47+
@end
+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//
2+
// ScrollViewWithPagingAppDelegate.h
3+
// ScrollViewWithPaging
4+
//
5+
// Created by CECID on 18/05/2010.
6+
// Copyright __MyCompanyName__ 2010. All rights reserved.
7+
//
8+
9+
#import <UIKit/UIKit.h>
10+
11+
@class ScrollViewWithPagingViewController;
12+
13+
@interface ScrollViewWithPagingAppDelegate : NSObject <UIApplicationDelegate> {
14+
UIWindow *window;
15+
ScrollViewWithPagingViewController *viewController;
16+
}
17+
18+
@property (nonatomic, retain) IBOutlet UIWindow *window;
19+
@property (nonatomic, retain) IBOutlet ScrollViewWithPagingViewController *viewController;
20+
21+
@end
22+
+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//
2+
// ScrollViewWithPagingAppDelegate.m
3+
// ScrollViewWithPaging
4+
//
5+
// Created by CECID on 18/05/2010.
6+
// Copyright __MyCompanyName__ 2010. All rights reserved.
7+
//
8+
9+
#import "ScrollViewWithPagingAppDelegate.h"
10+
#import "ScrollViewWithPagingViewController.h"
11+
12+
@implementation ScrollViewWithPagingAppDelegate
13+
14+
@synthesize window;
15+
@synthesize viewController;
16+
17+
18+
- (void)applicationDidFinishLaunching:(UIApplication *)application {
19+
20+
// Override point for customization after app launch
21+
[window addSubview:viewController.view];
22+
[window makeKeyAndVisible];
23+
}
24+
25+
26+
- (void)dealloc {
27+
[viewController release];
28+
[window release];
29+
[super dealloc];
30+
}
31+
32+
33+
@end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//
2+
// ScrollViewWithPagingViewController.h
3+
// ScrollViewWithPaging
4+
//
5+
// Created by CECID on 18/05/2010.
6+
// Copyright __MyCompanyName__ 2010. All rights reserved.
7+
//
8+
9+
#import <UIKit/UIKit.h>
10+
11+
@interface ScrollViewWithPagingViewController : UIViewController <UIScrollViewDelegate> {
12+
UIScrollView *scrollView;
13+
UIPageControl *pageControl;
14+
NSMutableArray *viewControllers;
15+
16+
// To be used when scrolls originate from the UIPageControl
17+
BOOL pageControlUsed;
18+
}
19+
20+
@property (nonatomic, retain) IBOutlet UIScrollView *scrollView;
21+
@property (nonatomic, retain) NSMutableArray *viewControllers;
22+
23+
- (IBAction)changePage:(id)sender;
24+
25+
@end
26+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
//
2+
// ScrollViewWithPagingViewController.m
3+
// ScrollViewWithPaging
4+
//
5+
// Created by CECID on 18/05/2010.
6+
// Copyright __MyCompanyName__ 2010. All rights reserved.
7+
//
8+
9+
#import "ScrollViewWithPagingViewController.h"
10+
#import "MyViewController.h"
11+
12+
static NSUInteger kNumberOfPages = 7;
13+
14+
@interface ScrollViewWithPagingViewController (PrivateMethods)
15+
16+
- (void)loadScrollViewWithPage:(int)page;
17+
- (void)scrollViewDidScroll:(UIScrollView *)sender;
18+
19+
@end
20+
21+
@implementation ScrollViewWithPagingViewController
22+
23+
@synthesize scrollView, viewControllers;
24+
25+
/*
26+
// The designated initializer. Override to perform setup that is required before the view is loaded.
27+
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
28+
if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
29+
// Custom initialization
30+
}
31+
return self;
32+
}
33+
*/
34+
35+
/*
36+
// Implement loadView to create a view hierarchy programmatically, without using a nib.
37+
- (void)loadView {
38+
}
39+
*/
40+
41+
42+
/*
43+
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
44+
*/
45+
- (void)viewDidLoad {
46+
[super viewDidLoad];
47+
48+
// view controllers are created lazily
49+
// in the meantime, load the array with placeholders which will be replaced on demand
50+
NSMutableArray *controllers = [[NSMutableArray alloc] init];
51+
for (unsigned i = 0; i < kNumberOfPages; i++) {
52+
[controllers addObject:[NSNull null]];
53+
}
54+
self.viewControllers = controllers;
55+
[controllers release];
56+
57+
// a page is the width of the scroll view
58+
scrollView.pagingEnabled = YES;
59+
scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * kNumberOfPages, scrollView.frame.size.height);
60+
scrollView.showsHorizontalScrollIndicator = NO;
61+
scrollView.showsVerticalScrollIndicator = NO;
62+
scrollView.scrollsToTop = NO;
63+
scrollView.delegate = self;
64+
65+
pageControl.numberOfPages = kNumberOfPages;
66+
pageControl.currentPage = 0;
67+
68+
// pages are created on demand
69+
// load the visible page
70+
// load the page on either side to avoid flashes when the user starts scrolling
71+
[self loadScrollViewWithPage:0];
72+
[self loadScrollViewWithPage:1];
73+
}
74+
75+
- (void)loadScrollViewWithPage:(int)page {
76+
if (page < 0) return;
77+
if (page >= kNumberOfPages) return;
78+
79+
// replace the placeholder if necessary
80+
MyViewController *controller = [viewControllers objectAtIndex:page];
81+
if ((NSNull *)controller == [NSNull null]) {
82+
controller = [[MyViewController alloc] initWithPageNumber:page];
83+
[viewControllers replaceObjectAtIndex:page withObject:controller];
84+
[controller release];
85+
}
86+
87+
// add the controller's view to the scroll view
88+
if (nil == controller.view.superview) {
89+
CGRect frame = scrollView.frame;
90+
frame.origin.x = frame.size.width * page;
91+
frame.origin.y = 0;
92+
controller.view.frame = frame;
93+
[scrollView addSubview:controller.view];
94+
}
95+
}
96+
97+
- (void)scrollViewDidScroll:(UIScrollView *)sender {
98+
// We don't want a "feedback loop" between the UIPageControl and the scroll delegate in
99+
// which a scroll event generated from the user hitting the page control triggers updates from
100+
// the delegate method. We use a boolean to disable the delegate logic when the page control is used.
101+
if (pageControlUsed) {
102+
// do nothing - the scroll was initiated from the page control, not the user dragging
103+
return;
104+
}
105+
106+
// Switch the indicator when more than 50% of the previous/next page is visible
107+
CGFloat pageWidth = scrollView.frame.size.width;
108+
int page = floor((scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
109+
pageControl.currentPage = page;
110+
111+
// load the visible page and the page on either side of it (to avoid flashes when the user starts scrolling)
112+
[self loadScrollViewWithPage:page - 1];
113+
[self loadScrollViewWithPage:page];
114+
[self loadScrollViewWithPage:page + 1];
115+
116+
// A possible optimization would be to unload the views+controllers which are no longer visible
117+
}
118+
119+
// At the begin of scroll dragging, reset the boolean used when scrolls originate from the UIPageControl
120+
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
121+
pageControlUsed = NO;
122+
}
123+
124+
// At the end of scroll animation, reset the boolean used when scrolls originate from the UIPageControl
125+
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
126+
pageControlUsed = NO;
127+
}
128+
129+
- (IBAction)changePage:(id)sender {
130+
int page = pageControl.currentPage;
131+
132+
// load the visible page and the page on either side of it (to avoid flashes when the user starts scrolling)
133+
[self loadScrollViewWithPage:page - 1];
134+
[self loadScrollViewWithPage:page];
135+
[self loadScrollViewWithPage:page + 1];
136+
137+
// update the scroll view to the appropriate page
138+
CGRect frame = scrollView.frame;
139+
frame.origin.x = frame.size.width * page;
140+
frame.origin.y = 0;
141+
[scrollView scrollRectToVisible:frame animated:YES];
142+
143+
// Set the boolean used when scrolls originate from the UIPageControl. See scrollViewDidScroll: above.
144+
pageControlUsed = YES;
145+
}
146+
147+
/*
148+
// Override to allow orientations other than the default portrait orientation.
149+
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
150+
// Return YES for supported orientations
151+
return (interfaceOrientation == UIInterfaceOrientationPortrait);
152+
}
153+
*/
154+
155+
- (void)didReceiveMemoryWarning {
156+
// Releases the view if it doesn't have a superview.
157+
[super didReceiveMemoryWarning];
158+
159+
// Release any cached data, images, etc that aren't in use.
160+
}
161+
162+
- (void)viewDidUnload {
163+
// Release any retained subviews of the main view.
164+
// e.g. self.myOutlet = nil;
165+
}
166+
167+
168+
- (void)dealloc {
169+
[viewControllers release];
170+
[scrollView release];
171+
[pageControl release];
172+
[super dealloc];
173+
}
174+
175+
@end

0 commit comments

Comments
 (0)