How to set the default page on the right side instead on the left (reverse) when launching App that used UIPageControl of UIScrollView?

StackOverflow https://stackoverflow.com/questions/1301329

Question

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
Was it helpful?

Solution

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

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top