横向模式下的分页视图控制器
Posted
技术标签:
【中文标题】横向模式下的分页视图控制器【英文标题】:Paging viewcontrollers in Landscape mode 【发布时间】:2010-11-23 14:19:42 【问题描述】:我有这个代码,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
上面的代码在肖像模式下工作得很好。但是当我改变方向时,整个页面都搞砸了.. :((
请帮我解决这个问题..
【问题讨论】:
当你说“整个页面都搞砸了”时,你将不得不更加具体。 ScrollView 不会横向分页。它只是滚动。 【参考方案1】:Apple 没有将 UIViewController 设计为可以在视图层次结构中的任何位置工作。您添加到 UIScrollView 的视图由视图控制器管理,但我认为您会发现这些视图的视图控制器不接收旋转事件。
您可以尝试手动将所有事件从滚动视图的控制器转发到子视图控制器,但我认为您会发现这样做很乏味且容易出错。我建议您只为滚动视图及其子视图使用单个视图控制器。
【讨论】:
视图控制器正在旋转,但不会根据方向改变它们的大小。在风景中,它们仍然具有肖像的框架。如何让他们改变横向的大小?? 您可以尝试为每个子视图设置自动调整大小的掩码。尝试 view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;每个子视图。 它不适用于自动调整掩码.. :-( 我如何使用单个视图控制器并向每个页面添加不同的子视图,例如按钮图像文本、标签????以上是关于横向模式下的分页视图控制器的主要内容,如果未能解决你的问题,请参考以下文章