在横向模式下分页视图控制器

时间:2010-11-23 14:19:42

标签: iphone objective-c uiscrollview uipagecontrol

我有这个代码,Apple的PageScrollView示例的修改版本。这里的不同之处在于m使用ViewControllers而不是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

以上代码在potrait模式下工作得非常好。但是当我改变方向时,整个分页都搞砸了...... :((

请帮我解决这个问题..

1 个答案:

答案 0 :(得分:0)

Apple没有将UIViewController设计为在视图层次结构中的任何位置工作。您添加到UIScrollView的视图由视图控制器管理,但我认为您会发现这些视图的视图控制器不会接收旋转事件。

您可以尝试将所有事件从滚动视图的控制器手动转发到子视图控制器,但我认为您会发现这很乏味且容易出错。我建议你只使用一个视图控制器来滚动视图及其子视图。