iPhone Dev- Page Control - scrollViewDidScroll not firing - iphone

I'm new to iPhone development and am working on this tutorial: http://www.iosdevnotes.com/2011/03/uiscrollview-paging/#comment-25166 - but am doing it in XCode 4.3.2. The example is pretty simple and I understand the code, but for some reason the scrollViewDidScroll function isn't firing for me in my ViewController.m (this thus doesn't change the Page Control pagination icons and update it to the current page). I placed an NSLog() in this function so I can tell if it is ever activating - but in my debug console I never see this text
The code from my ViewController.h is:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UIScrollViewDelegate> {
UIScrollView* scrollView;
UIPageControl* pageControl;
}
#property (nonatomic, retain) IBOutlet UIScrollView* scrollView;
#property (nonatomic, retain) IBOutlet UIPageControl* pageControl;
#end
The code from my ViewController.m is:
#import "ViewController.h"
#implementation ViewController
#synthesize scrollView, pageControl;
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
NSArray *colors = [NSArray arrayWithObjects:[UIColor redColor], [UIColor greenColor], [UIColor blueColor], nil];
for (int i = 0; i < colors.count; i++) {
CGRect frame;
frame.origin.x = self.scrollView.frame.size.width * i;
frame.origin.y = 0;
frame.size = self.scrollView.frame.size;
UIView *subview = [[UIView alloc] initWithFrame:frame];
subview.backgroundColor = [colors objectAtIndex:i];
[self.scrollView addSubview:subview];
[subview release];
}
self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.size.width * colors.count, self.scrollView.frame.size.height);
self.pageControl.currentPage = 0;
self.pageControl.numberOfPages = colors.count;
}
//!!!!!!!!!!!!!!
//THIS IS WHERE MY PROBLEM IS -- THIS CODE DOESN'T SEEM TO EVER GET RUN EVEN WHEN I SCROLL!!!!!
//!!!!!!!!!!!!!
- (void)scrollViewDidScroll:(UIScrollView *)sender {
NSLog(#"this just fired");
// Switch the indicator when more than 50% of the previous/next page is visible
CGFloat pageWidth = self.scrollView.frame.size.width;
int page = floor((self.scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
self.pageControl.currentPage = page;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void)viewDidUnload {
self.scrollView = nil;
self.pageControl = nil;
}
- (void)dealloc {
[scrollView release];
[pageControl release];
[super dealloc];
}
#end
Any help would be greatly appreciated. I've been going back and forth from the downloadable file they have on the tutorial to my own over and over and over... I just feel like this thing should fire when I start scrolling and have no idea why it's not... Thanks in advance!

In Interface Builder you did not connect the scroll view’s “delegate” outlet to you view controller. But you can do it programmatically.
[self.scrollView setDelegate:self];

dianz is Right, Set your delegate.
[self.scrollView setDelegate:self];
OR
self.scrollView.delegate=self;

You forgot to set your delegate:
- (void)viewDidLoad {
[super viewDidLoad];
// This is what you forgot to do, set the delegate of the scrollView.
scrollView.delegate = self;
NSArray *colors = [NSArray arrayWithObjects:[UIColor redColor], [UIColor greenColor], [UIColor blueColor], nil];
for (int i = 0; i < colors.count; i++) {
CGRect frame;
frame.origin.x = self.scrollView.frame.size.width * i;
frame.origin.y = 0;
frame.size = self.scrollView.frame.size;
UIView *subview = [[UIView alloc] initWithFrame:frame];
subview.backgroundColor = [colors objectAtIndex:i];
[self.scrollView addSubview:subview];
[subview release];
}

Please make sure you have set the scrollview delegate to the viewcontroller you want.
You can also attach the delegate in the xib file, if the scrollview is added in the xib.
Also, don't forget to implement the scrollview delegate protocol UIScrollViewDelegate in the viewcontroller's header file.

Related

IOS Help Modifying Code Snippet [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
I am using a view controller that consists of a horizontal scroll view and page controller to display a number of images in a carrousel fashion. The controller is passed an array of images and displays them starting with the first image. I obtained the code snippet from a third party tutorial and have spent the last day trying to understand it and change its functionality. I have been trying to make the carrousel start at the middle of the array of images, (i.e. if there are nine images start at image five and allow for scrolling both ways) but have had no luck in modifying the existing code. I have played around with the loadPage and loadVisiblePages methods but have had little luck. Here are the .m and .h files.
PeekPagedScrollViewController.m
#import "PeekPagedScrollViewController.h"
#interface PeekPagedScrollViewController ()
#property (nonatomic, strong) NSMutableArray *pageViews;
- (void)loadVisiblePages;
- (void)loadPage:(NSInteger)page;
- (void)purgePage:(NSInteger)page;
#end
#implementation PeekPagedScrollViewController
#synthesize scrollView = _scrollView;
#synthesize pageControl = _pageControl;
#synthesize gallaryType = _gallaryType;
#synthesize pageImages = _pageImages;
#synthesize pageViews = _pageViews;
#synthesize startPoint = _startPoint;
#pragma mark -
- (void)loadVisiblePages
{
// First, determine which page is currently visible
CGFloat pageWidth = self.scrollView.frame.size.width;
NSInteger page = (NSInteger)floor((self.scrollView.contentOffset.x * 2.0f + pageWidth) / (pageWidth * 2.0f));
// Work out which pages we want to load
NSInteger firstPage = page - 1;
NSInteger lastPage = page + 1;
// Purge anything before the first page
for (NSInteger i=0; i<firstPage; i++) {
[self purgePage:i];
}
for (NSInteger i=firstPage; i<=lastPage; i++) {
[self loadPage:i];
}
for (NSInteger i=lastPage+1; i<self.pageImages.count; i++) {
[self purgePage:i];
}
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)loadPage:(NSInteger)page
{
if (page < 0 || page >= self.pageImages.count)
{
// If it's outside the range of what we have to display, then do nothing
return;
}
// Load an individual page, first seeing if we've already loaded it
UIView *pageView = [self.pageViews objectAtIndex:page];
if ((NSNull*)pageView == [NSNull null])
{
CGRect frame = self.scrollView.bounds;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0.0f;
frame = CGRectInset(frame, 10.0f, 0.0f);
UIImageView *newPageView = [[UIImageView alloc] initWithImage:[self.pageImages objectAtIndex:page]];
newPageView.contentMode = UIViewContentModeScaleAspectFit;
newPageView.frame = frame;
[self addTapHandler:newPageView actionSelector:#selector(handleSingleTap:)];
[self.scrollView addSubview:newPageView];
[self.pageViews replaceObjectAtIndex:page withObject:newPageView];
}
}
- (void)purgePage:(NSInteger)page
{
if (page < 0 || page >= self.pageImages.count)
{
// If it's outside the range of what we have to display, then do nothing
return;
}
// Remove a page from the scroll view and reset the container array
UIView *pageView = [self.pageViews objectAtIndex:page];
if ((NSNull*)pageView != [NSNull null])
{
[pageView removeFromSuperview];
[self.pageViews replaceObjectAtIndex:page withObject:[NSNull null]];
}
}
- (void)addTapHandler:(UIView *)pageView actionSelector:(SEL)actionSelector
{
[pageView setUserInteractionEnabled:YES];
UITapGestureRecognizer *tapper = [[UITapGestureRecognizer alloc] initWithTarget:self action:actionSelector];
[pageView addGestureRecognizer:tapper];
}
- (void)handleSingleTap:(UITapGestureRecognizer *)recognizer
{
if (_gallaryType == 0)
{
NSString *messageString = #"Use as profile image?";
UIAlertView *imageAlertView = [[UIAlertView alloc] initWithTitle:#"Select Image" message:messageString delegate:self cancelButtonTitle:#"No" otherButtonTitles:#"Yes", nil];
[imageAlertView show];
}
else if (_gallaryType == 1)
{
NSString *messageString = #"Use as cover photo?";
UIAlertView *imageAlertView = [[UIAlertView alloc] initWithTitle:#"Select Image" message:messageString delegate:self cancelButtonTitle:#"No" otherButtonTitles:#"Yes", nil];
[imageAlertView show];
}
}
-(void) alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 1)
{
// add yes button text here
}
}
#pragma mark -
- (void)viewDidLoad
{
[super viewDidLoad];
[self.view setTranslatesAutoresizingMaskIntoConstraints:YES];
self.title = #"Paged";
NSInteger pageCount = self.pageImages.count;
// Set up the array to hold the views for each page
self.pageViews = [[NSMutableArray alloc] init];
for (NSInteger i = 0; i < pageCount; ++i)
{
[self.pageViews addObject:[NSNull null]];
}
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// Set up the content size of the scroll view
CGSize pagesScrollViewSize = self.scrollView.frame.size;
self.scrollView.contentSize = CGSizeMake(pagesScrollViewSize.width * self.pageImages.count, pagesScrollViewSize.height);
// Load the initial set of pages that are on screen
[self loadVisiblePages];
}
- (IBAction)back:(id)sender
{
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void)viewDidUnload
{
[super viewDidUnload];
self.scrollView = nil;
self.pageControl = nil;
self.pageImages = nil;
self.pageViews = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
#pragma mark - UIScrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
// Load the pages which are now on screen
[self loadVisiblePages];
}
#end
PeekPagedScrollViewController.h
#import <UIKit/UIKit.h>
#interface PeekPagedScrollViewController : UIViewController <UIScrollViewDelegate, UIAlertViewDelegate>
#property (nonatomic, strong) IBOutlet UIScrollView *scrollView;
#property (nonatomic, strong) IBOutlet UIPageControl *pageControl;
#property (nonatomic, strong) NSArray *pageImages;
#property (nonatomic) NSInteger *gallaryType;
#property (nonatomic) NSInteger *startPoint;
- (IBAction)back:(id)sender;
#end
Thanks
just take scroll view
set its content size/// that is how much it is going to scroll
scrollView.contentSize = CGSizeMake(scrollView.bounds.size.width*imageArray.count,scrollView.frame.size.height);
// and then set the starting point
scrollView.contentOffset = CGPointMake(currentpage * scrollView.bounds.size.width, 0);
I think you only need to scroll to a particular page. The rest of the thing will automatically happens. Try like this
CGRect frame = self.scrollView.frame;
frame.origin.x = (frame.size.width * page);
frame.origin.y = 0;
[self.scrollView scrollRectToVisible:frame animated:YES];
Here page is the page number(eg 5)

Swiping Images with Page Control in Iphone

I am trying to make practice app where i can scroll images with page control. I am able to scroll images and able to include the page control. But the problem i face is i am not able to interlink the two. Meaning to say when I scroll the images, the page control is not affected and when i change the page control, the scrolling of the images is unaffected.
I have referred to this: http://www.iosdevnotes.com/2011/03/uiscrollview-paging/ for the scrolling with page control.
Viewcontroller.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UIScrollViewDelegate>{
UIScrollView *scrollView;
UIPageControl *pageControl;
BOOL pageControlBeingUsed;
}
#property (nonatomic, retain) IBOutlet UIScrollView *scrollView;
#property (nonatomic, retain) IBOutlet UIPageControl *pageControl;
- (IBAction)changePage;
#end
Viewcontroller.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize scrollView,pageControl;
- (void)scrollViewDidScroll:(UIScrollView *)sender {
if (!pageControlBeingUsed) {
// Switch the indicator when more than 50% of the previous/next page is visible
CGFloat pageWidth = self.scrollView.frame.size.width;
int page = floor((self.scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
self.pageControl.currentPage = page;
}
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
pageControlBeingUsed = NO;
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
pageControlBeingUsed = NO;
}
- (void)viewDidLoad
{
[super viewDidLoad];
NSArray *images = [[NSArray alloc] initWithObjects:[UIImage imageNamed:#"1.jpeg"],[UIImage imageNamed:#"2.jpeg"],[UIImage imageNamed:#"3.jpeg" ], nil];
self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.size.width * images.count, self.scrollView.frame.size.height);
for (int i = 0; i < images.count; i++) {
CGRect frame;
frame.origin.x = self.scrollView.frame.size.width * i;
frame.origin.y = 0;
frame.size = self.scrollView.frame.size;
UIImageView* imgView = [[UIImageView alloc] init];
imgView.image = [images objectAtIndex:i];
imgView.frame = frame;
[scrollView addSubview:imgView];
}
self.pageControl.currentPage = 0;
self.pageControl.numberOfPages = images.count;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
self.scrollView = nil;
self.pageControl = nil;
}
- (IBAction)changePage{
// update the scroll view to the appropriate page
CGRect frame;
frame.origin.x = self.scrollView.frame.size.width * self.pageControl.currentPage;
frame.origin.y = 0;
frame.size = self.scrollView.frame.size;
[self.scrollView scrollRectToVisible:frame animated:YES];
pageControlBeingUsed = YES;
}
#end
Need some guidance on this... Thanks..
I learned page control and scrollView from this tutorial, its very clearly written, hope it helps you http://www.raywenderlich.com/10518/how-to-use-uiscrollview-to-scroll-and-zoom-content
Check whether you have set the delegate of the scroll view to the ViewController
And you have just set the pageControlBeingUsed to YES or NO and you have not used it anywhere in the ViewController

Designing a threaded comment system for iOS

I am building an app to go alongside a web app I've built, which features a threaded comment system.
I'm wondering what the best approach to building this threaded view would be. Is there a relatively easy way to build an accordion style control?
I really like how the Alien Blue app does it, and the UI & UX is very smooth:
Does anyone have any idea how these are built?
Would making custom UIViews added as subviews be the best approach? If so, how would you implement 'collapse' style functionality?
I'd suggest creating a UIView subclass to contain each comment. It should have a toggle button to expand / collapse. On toggling open i'd set the frame size to the size of the content (plus any padding). It would contain an array of sub-comments, for each one you'd add the UIView subclasses to itself at expand time (And remove when collapsing) which would initially be collapsed (and so just appear as the toggle button). Collapsing is just the reverse, remove the subviews, set the frame to be the hight of the toggle button (plus padding)
As each comment view knows its size, you can put the whole thing in a UIScrollView with content-size set to the sum of the comment views sizes allowing scrolling regardless of expanded / contracted nature.
A partial implementation for this idea:
Comment.h
#import <Foundation/Foundation.h>
#interface Comment : NSObject {
NSMutableArray* subComments;
NSString* comment;
}
#property (nonatomic, retain) NSMutableArray* subComments;
#property (nonatomic, retain) NSString* comment;
#end
Comment.m
#import "Comment.h"
#implementation Comment
#synthesize comment, subComments;
-(id)init
{
self = [super init];
if (self)
{
subComments = [[NSMutableArray alloc] init];
}
return self;
}
#end
CommentView.h
#import <UIKit/UIKit.h>
#interface CommentView : UIView {
UIButton* toggle;
NSMutableArray* subComments;
NSString* commentText;
UITextView* comment;
BOOL expanded;
}
#property (strong, nonatomic) NSMutableArray* subComments;
#property (strong, nonatomic) NSString* commentText;
- (void) expand;
- (void) collapse;
- (void) toggleState;
#end
CommentView.m
#import "CommentView.h"
#implementation CommentView
#synthesize subComments,commentText;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
[self setBackgroundColor:[UIColor whiteColor]];
expanded = NO;
toggle = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[toggle setTitle:#"Toggle" forState:UIControlStateNormal];
[toggle addTarget:self action:#selector(toggleState) forControlEvents:UIControlEventTouchUpInside];
CGRect curentFrame = self.frame;
curentFrame.size.height = toggle.frame.size.height + 10;
[self setFrame:curentFrame];
curentFrame = toggle.frame;
curentFrame.origin.y = 5;
curentFrame.origin.x = 5;
[toggle setFrame:curentFrame];
[self addSubview:toggle];
[self collapse];
return self;
}
- (void) toggleState
{
if (expanded)
{
[self collapse];
}
else
{
[self expand];
}
}
- (void) expand
{
comment = [[UITextView alloc] init];
[comment setEditable:NO];
[comment setText:commentText];
[self addSubview:comment];
CGRect curentFrame = comment.frame;
curentFrame.size.height = comment.contentSize.height;
curentFrame.origin.x = toggle.frame.size.width + toggle.frame.origin.x + 10;
curentFrame.size.width = self.frame.size.width - curentFrame.origin.x;
curentFrame.origin.y = toggle.frame.size.height + toggle.frame.origin.y + 10;
[comment setFrame:curentFrame];
curentFrame = self.frame;
curentFrame.size.height += comment.frame.size.height + 10;
[self setFrame:curentFrame];
float height = comment.frame.origin.y + comment.frame.size.height;
for (NSObject* o in subComments)
{
CommentView* subComment = [[CommentView alloc] initWithFrame:CGRectMake(comment.frame.origin.x,height,0,self.frame.size.width)];
[self addSubview:subComment];
height += subComment.frame.size.height;
curentFrame = self.frame;
curentFrame.size.height += subComment.frame.size.height;
[self setFrame:curentFrame];
[self bringSubviewToFront:subComment];
}
expanded = YES;
}
- (void) collapse
{
for (UIView* v in [self subviews])
{
[v removeFromSuperview];
}
CGRect curentFrame = self.frame;
curentFrame.size.height = toggle.frame.size.height + 10;
[self setFrame:curentFrame];
curentFrame = toggle.frame;
curentFrame.origin.y = 5;
curentFrame.origin.x = 5;
[toggle setFrame:curentFrame];
[self addSubview:toggle];
expanded = NO;
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
// Drawing code
}
*/
#end
ViewContoller.m (Example usage)
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
CommentView* mainCommentView = [[CommentView alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
Comment* mainComment = [[Comment alloc] init];
[mainComment setComment: #"Lorem Ipsum 1"];
Comment* sub1 = [[Comment alloc] init];
[sub1 setComment: #"Lorem Ipsum 1-1"];
Comment* sub11 = [[Comment alloc] init];
[sub11 setComment: #"Lorem Ipsum 1-1-1"];
[[sub1 subComments] addObject:sub11];
Comment* sub2 = [[Comment alloc] init];
[sub2 setComment: #"Lorem Ipsum 1-2"];
Comment* sub12 = [[Comment alloc] init];
[sub12 setComment: #"Lorem Ipsum 1-2-1"];
[[sub2 subComments] addObject:sub12];
[[mainComment subComments] addObject:sub1];
[[mainComment subComments] addObject:sub2];
[mainCommentView setCommentText:[mainComment comment]];
[mainCommentView setSubComments:[mainComment subComments]];
self.view = mainCommentView;
}
Looks like Apple has some sample code for collapsing UITableViewCells:
http://developer.apple.com/library/ios/#samplecode/TableViewUpdates/Introduction/Intro.html
There's also GCRetractableSectionController
Is something like this not just a webview with custom built HTML page displaying the comments?

Xcode/iPhone: First Windows-Based Application - Why isn't anything showing up in the TabBarController views

Is there something that I need to remember when using the windows-based template? Because I'm unclear as to why the tabs are showing up but nothing in the views are showing up.
Could you help? Because I've been searching through previous questions for a few hours now and I still haven't found anything to clear this up.
AnotherMadeUpAppDelegate.h
#import <UIKit/UIKit.h>
#import "AnotherMadeUpViewController.h"
#interface AnotherMadeUpAppDelegate : NSObject <UIApplicationDelegate> {
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#end
AnotherMadeUpAppDelegate.m
#import "AnotherMadeUpAppDelegate.h"
#implementation AnotherMadeUpAppDelegate
#synthesize window=_window;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
UIViewController *vc1 = [[UIViewController alloc] init];
UIViewController *vc2 = [[UIViewController alloc] init];
AnotherMadeUpViewController *vc3 = [[AnotherMadeUpViewController alloc] init];
UITabBarController *tbc = [[UITabBarController alloc] init];
tbc.viewControllers = [NSArray arrayWithObjects:vc1, vc2, vc3, nil];
[vc1 release];
[vc2 release];
[vc3 release];
[self.window addSubview:tbc.view];
[self.window makeKeyAndVisible];
return YES;
}
...
#end
AnotherMadeUpViewController.h
#import <UIKit/UIKit.h>
#interface AnotherMadeUpViewController : UIViewController<UIScrollViewDelegate>
{
IBOutlet UIPageControl *pageControl;
IBOutlet UIScrollView *scroller;
IBOutlet UILabel *label;
}
#property (nonatomic,retain)IBOutlet UIPageControl *pageControl;
#property (nonatomic,retain)IBOutlet UIScrollView *scroller;
#property (nonatomic,retain)IBOutlet UILabel *label;
-(IBAction)clickPageControl:(id)sender;
#end
AnotherMadeUpViewController.m
#import "AnotherMadeUpViewController.h"
#implementation AnotherMadeUpViewController
#synthesize pageControl,scroller,label;
-(IBAction)clickPageControl:(id)sender
{
int page=pageControl.currentPage;
CGRect frame=scroller.frame;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0;
[scroller scrollRectToVisible:frame animated:YES];
}
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
int page = scrollView.contentOffset.x/scrollView.frame.size.width;
pageControl.currentPage=page;
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)dealloc
{
[super dealloc];
[label release];
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
scroller.pagingEnabled=YES;
CGFloat labelOriginX = label.frame.origin.x;
CGFloat labelOriginY = label.frame.origin.y;
CGFloat scrollWidth = 0;
int pageNumber = 0;
for (int i=0; i<9; i++)
{
CGRect rect = label.frame;
rect.size.height = label.frame.size.height;
rect.size.width = label.frame.size.width;
rect.origin.x = labelOriginX + scrollWidth;
rect.origin.y = labelOriginY;
label.frame = rect;
label.text = [NSString stringWithFormat:#"%d", pageNumber];
label.textColor = [UIColor redColor];
[scroller addSubview:label];
pageNumber++;
scrollWidth += scroller.frame.size.width;
}
scroller.delegate=self;
scroller.directionalLockEnabled=YES;
scroller.showsHorizontalScrollIndicator=NO;
scroller.showsVerticalScrollIndicator=NO;
pageControl.numberOfPages=9;
pageControl.currentPage=0;
scroller.contentSize=CGSizeMake(pageControl.numberOfPages*self.view.frame.size.width, self.view.frame.size.height);
[self.view addSubview:scroller];
}
- (void)viewDidUnload
{
[super viewDidUnload];
[label release];
self.label = nil;
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
Dissecting your viewDidLoad –
scroller = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width,self.view.frame.size.height)];
You seem to be creating a new scroll view instance here but you have declared it as an outlet. If you don't have an outlet then remove the IBOutlet tag for scroller. If you do have one and want to use it then remove the above line. A shorter way of doing it would be,
scroller = [[UIScrollView alloc] initWithFrame:self.view.bounds];
Another thing is that you are creating 10 labels but assigning no frame. To show one of them each in different page,
int pageNumber = 0;
for (int i = 0; i < 10; i++)
{
UILabel *label = [[UILabel alloc] init];
[label sizeToFit];
label.center = CGPointMake (((2 * i + 1) * self.view.frame.size.width) / 2, self.view.frame.size.height / 2);
label.text = [NSString stringWithFormat:#"%d", pageNumber];
[scroller addSubview:label];
[label release];
pageNumber++;
}
and later set the contentSize to show 10 pages,
scroller.contentSize = CGSizeMake(10 * self.view.frame.size.width, self.view.frame.size.height);
The problem is with this line
AnotherMadeUpViewController *vc3 = [[AnotherMadeUpViewController alloc] init];
You need to change it to
AnotherMadeUpViewController *vc3 = [[AnotherMadeUpViewController alloc] initWithNibName:#"AnotherMadeUpViewController" bundle:nil];
Then your .xib will get loaded and your outlets will be connected.
And don't forget to connect your outlets to File's owner in IB.

Paging viewcontrollers in Landscape mode

I have this code, modified version of Apple's PageScrollView sample. Here the differnce is that m using ViewControllers instead of UIView.
MyClass.h
#interface MyClass : UIViewController {
UIScrollView *scrollView;
UIPageControl *pageControl;
NSMutableArray *viewControllers;
BOOL pageControlUsed;
}
#property (nonatomic, retain) IBOutlet UIScrollView *scrollView;
#property (nonatomic, retain) IBOutlet UIPageControl *pageControl;
#property (nonatomic, retain) NSMutableArray *viewControllers;
- (IBAction)changePage:(id)sender;
#end
MyClass.m
#import "MyClass.h"
#import "MyViewController.h"
#import "MyViewControllerZero.h"
#import "MyViewControllerOne.h"
#import "MyViewControllerTwo.h"
static NSUInteger kNumberOfPages = 3;
#interface MyClass (PrivateMethods)
- (void)loadScrollViewWithPage:(int)page;
- (void)scrollViewDidScroll:(UIScrollView *)sender;
#end
#implementation MyClass
#synthesize scrollView, pageControl, viewControllers;
/*
// The designated initializer. Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
// Custom initialization
}
return self;
}
*/
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
NSMutableArray *controllers = [[NSMutableArray alloc] init];
for (unsigned i = 0; i < kNumberOfPages; i++) {
[controllers addObject:[NSNull null]];
}
self.viewControllers = controllers;
[controllers release];
// a page is the width of the scroll view
scrollView.pagingEnabled = YES;
scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * kNumberOfPages, scrollView.frame.size.height);
scrollView.showsHorizontalScrollIndicator = NO;
scrollView.showsVerticalScrollIndicator = NO;
scrollView.scrollsToTop = NO;
scrollView.delegate = self;
pageControl.numberOfPages = kNumberOfPages;
pageControl.currentPage = 0;
// pages are created on demand
// load the visible page
// load the page on either side to avoid flashes when the user starts scrolling
[self loadScrollViewWithPage:0];
[self loadScrollViewWithPage:1];
}
- (void)loadScrollViewWithPage:(int)page {
// if (page < 0) return;
// if (page >= kNumberOfPages) return;
if(page==0)
{
MyViewControllerZero *controller = [viewControllers objectAtIndex:page];
if ((NSNull *)controller == [NSNull null])
{ controller = [[MyViewControllerZero alloc] init];
[viewControllers replaceObjectAtIndex:page withObject:controller];
if (nil == controller.view.superview) {
CGRect frame = scrollView.frame;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0;
controller.view.frame = frame;
[scrollView addSubview:controller.view];
}
}
}
if(page==1)
{
MyViewControllerOne *controller = [viewControllers objectAtIndex:page];
if ((NSNull *)controller == [NSNull null])
{ controller = [[MyViewControllerOne alloc] init];
[viewControllers replaceObjectAtIndex:page withObject:controller];
if (nil == controller.view.superview) {
CGRect frame = scrollView.frame;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0;
controller.view.frame = frame;
[scrollView addSubview:controller.view];
}
}
}
if(page==2)
{
MyViewControllerTwo *controller = [viewControllers objectAtIndex:page];
if ((NSNull *)controller == [NSNull null])
{ controller = [[MyViewControllerTwo alloc] init];
[viewControllers replaceObjectAtIndex:page withObject:controller];
if (nil == controller.view.superview) {
CGRect frame = scrollView.frame;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0;
controller.view.frame = frame;
[scrollView addSubview:controller.view];
}
}
}
}
- (void)scrollViewDidScroll:(UIScrollView *)sender {
if (pageControlUsed) {
return;
}
CGFloat pageWidth = scrollView.frame.size.width;
int page = floor((scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
pageControl.currentPage = page;
// load the visible page and the page on either side of it (to avoid flashes when the user starts scrolling)
[self loadScrollViewWithPage:page - 1];
[self loadScrollViewWithPage:page];
[self loadScrollViewWithPage:page + 1];
// A possible optimization would be to unload the views+controllers which are no longer visible
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Overriden to allow any orientation.
return YES;
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
pageControlUsed = NO;
}
// At the end of scroll animation, reset the boolean used when scrolls originate from the UIPageControl
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
pageControlUsed = NO;
}
- (IBAction)changePage:(id)sender {
int page = pageControl.currentPage;
// load the visible page and the page on either side of it (to avoid flashes when the user starts scrolling)
[self loadScrollViewWithPage:page - 1];
[self loadScrollViewWithPage:page];
[self loadScrollViewWithPage:page + 1];
// update the scroll view to the appropriate page
CGRect frame = scrollView.frame;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0;
[scrollView scrollRectToVisible:frame animated:YES];
// Set the boolean used when scrolls originate from the UIPageControl. See scrollViewDidScroll: above.
pageControlUsed = YES;
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[viewControllers release];
[scrollView release];
[pageControl release];
[super dealloc];
}
#end
The Above code works absolutely fine in the potrait mode. But when i change the orientation,the whole paging gets screwed up.. :((
please help me to resolve this problem..
Apple didn't design UIViewController to work at any point in a view hierarchy. The views that you're adding to your UIScrollView are managed by view controllers, but I think you'll find that the view controllers for those views don't receive rotation events.
You could try to manually forward all events from the scroll view's controller to the child view controllers, but I think you'll find that to be tedious and error prone. I'd suggest instead that you simply use a single view controller for the scroll view and its child views.