views:

550

answers:

2

My Case:

I have original Page Control app from Apple. I would like to modify the launch of the app on right side on page control at the bottom of UIScrollView? By default, when launch - it is on the first page which is on the left. Say for example, i have 7 pages. So, I want the first page appear on the last page which is on the 7th page and second page page on the 6th page and so on. In short, the reverse of the default.

I know there have to be one code that do this trick. I'm not sure what it is. Please help. Thanks!

Below is description of Page Control app from Apple:

PageControl

This application demonstrates use of UIScrollView's paging functionality to use horizontal scrolling as a mechanism for navigating between different pages of content. Each page is managed by its own view controller which is loaded only when it is needed. A UIPageControl is displayed at the bottom of the window as an alternative interface for moving between pages

The Code in AppDelegate.m

#import "AppDelegate.h"
#import "MyViewController.h"

static NSUInteger kNumberOfPages = 7;

@interface AppDelegate (PrivateMethods)

- (void)loadScrollViewWithPage:(int)page;
- (void)scrollViewDidScroll:(UIScrollView *)sender;

@end

@implementation AppDelegate

@synthesize window, scrollView, pageControl, viewControllers;

- (void)dealloc {
    [viewControllers release];
    [scrollView release];
    [pageControl release];
    [window release];
    [super dealloc];
}

- (void)applicationDidFinishLaunching:(UIApplication *)application {
    // view controllers are created lazily
    // in the meantime, load the array with placeholders which will be replaced on demand
    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;

    // replace the placeholder if necessary
    MyViewController *controller = [viewControllers objectAtIndex:page];
    if ((NSNull *)controller == [NSNull null]) {
        controller = [[MyViewController alloc] initWithPageNumber:page];
        [viewControllers replaceObjectAtIndex:page withObject:controller];
        [controller release];
    }

    // add the controller's view to the scroll view
    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 {
    // We don't want a "feedback loop" between the UIPageControl and the scroll delegate in
    // which a scroll event generated from the user hitting the page control triggers updates from
    // the delegate method. We use a boolean to disable the delegate logic when the page control is used.
    if (pageControlUsed) {
        // do nothing - the scroll was initiated from the page control, not the user dragging
        return;
    }
    // Switch the indicator when more than 50% of the previous/next page is visible
    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
}

// 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;
}

@end
+1  A: 

Well you can just set your scrollViews offset to be the last page and so then it will start at t he last page and you have to scroll to the right instead of the left...use UIScrollViews - (void)setContentOffset:(CGPoint)contentOffset animated:(BOOL)animated method.

Daniel
Sorry I'm a bit newbie at this stuff.Assuming you would have to put setContentOffset. Where exactly do you put it in the code? (I put in the code for reference)Also, if you were to use setContentOffset - does it affect the UIPageControl also?
viper15
Maybe right after you instantiate your scrollView, for p agesControl all you need to do is set the active page i think..
Daniel
A: 

Taking the PageControl sample from Apple, here's the code that would do this. I tested it and it works fine, except for noticing a jump of the page control when you launch the app from the initial dot to the last one, but I don't know how to solve that. Let me know if this doesn't work for you.

- (void)applicationDidFinishLaunching:(UIApplication *)application {
 // view controllers are created lazily
 // in the meantime, load the array with placeholders which will be replaced on demand
 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;

 // First, set the number of pages
 pageControl.numberOfPages = kNumberOfPages;
 // Then, tell the page control that you're on the last page (numPages - 1, since we're 0-indexed)
 pageControl.currentPage = kNumberOfPages - 1;

 // Now, we have to tell the frame that we're at the end of the frame
 // So we set the content offset to be the last page
 scrollView.contentOffset = CGPointMake(scrollView.frame.size.width * (kNumberOfPages - 1), 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];

 // Now, instead of loading the original page, we load the last two pages
 [self loadScrollViewWithPage:kNumberOfPages - 1];
 [self loadScrollViewWithPage:kNumberOfPages - 2];
}
Itay
I think i tried that. That didn't work. numPages - 1 will just go back to the previous before the last.Say, there is 7 pages. It will go to the 6th page. But when scroll to either right or left, it changes back to original page 1,2,3 etc. There must be something in the code that need to be changed so that it will go reverse.
viper15
I'd have to actually try the code out. I'll try and do it later today, and post back a more complete solution.
Itay
Hey Itay, thanks a lot man! That would be great. Appreciate it.
viper15
Updated with a tested and working solution. Let me know if it doesn't work.
Itay
Hey Itay! You're a genius man! It works - the jumping dot maybe has to do with pagecontrol when instantiated. Anyway man, thanks a lot!
viper15
Oh yeah man, i think i know why the jumping dot. Because of the default.png image - if you look at the image, the dot highlighted at first. So, if i change the image so that the dot at the back - it should work, Right? Cool man!
viper15