Http://www.wannabegeek.com /? P = 168
Although it seems that it is common to use uipagecontrol to navigate a series of uiviews or uiviewcontroller
Apple does not provide such a method or demo: In the latest IOS version (5.0 is not the latest ), apple provides many ways to implement the uiviewcontroller container in other ways (for reference here), but the tragedy is that they have little to do with uipagecontrol. We will solve this problem today.Create InterfaceFirst, we need to create a uipagecontrol and uiscrollview in a uiviewcontroller in interface builder. Of course, you can create many similar uiviewcontroller.
Set pageviewcontroller classThe pageviewcontroller object here will contain a uiscrollview and a uipagecontrol. Uiscrollview will contain all subviews, which are subpages controlled by uipagecontrol. You may add some algorithms to viewcontroller to specifically process page conversion: addchildviewcontroller: method. However, this is not the case in my case. Let's take a look at the Code:
@interface PagerViewController : UIViewController @property (nonatomic, strong) IBOutlet UIScrollView *scrollView;@property (nonatomic, strong) IBOutlet UIPageControl *pageControl; - (IBAction)changePage:(id)sender; @end
In the implemented code file, I first won't allow it to rotate the screen. When pagerviewcontroller is ready for display, We need to mark which view is activated, that is, displayed. Then we need to add the following code to viewdidapplear and viewwilldisappear:
- (BOOL)automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers { returnNO;} - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; UIViewController *viewController = [self.childViewControllers objectAtIndex:self.pageControl.currentPage]; if(viewController.view.superview != nil) { [viewController viewDidAppear:animated]; }} - (void)viewWillDisappear:(BOOL)animated { UIViewController *viewController = [self.childViewControllers objectAtIndex:self.pageControl.currentPage]; if(viewController.view.superview != nil) { [viewController viewWillDisappear:animated]; } [super viewWillDisappear:animated];} - (void)viewDidDisappear:(BOOL)animated { UIViewController *viewController = [self.childViewControllers objectAtIndex:self.pageControl.currentPage]; if(viewController.view.superview != nil) { [viewController viewDidDisappear:animated]; } [super viewDidDisappear:animated];}Viewwillappear may be a bit complicated, because we also need to load all the child views to the scrollview, and we must ensure that the contentsize of the scrollview is larger than that of the Child view.
- (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; for(NSUInteger i =0; i < [self.childViewControllers count]; i++) { [self loadScrollViewWithPage:i]; } self.pageControl.currentPage = 0; _page = 0; [self.pageControl setNumberOfPages:[self.childViewControllers count]]; UIViewController *viewController = [self.childViewControllers objectAtIndex:self.pageControl.currentPage]; if(viewController.view.superview != nil) { [viewController viewWillAppear:animated]; } self.scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * [self.childViewControllers count], scrollView.frame.size.height);}To load the content of uiviewcontroller to the contentview of uiscrolview, the following code is required:
- (void)loadScrollViewWithPage:(int)page { if(page < 0) return; if(page >= [self.childViewControllers count]) return; // replace the placeholder if necessary UIViewController *controller = [self.childViewControllers objectAtIndex:page]; if(controller == nil) { return; } // add the controller's view to the scroll view if(controller.view.superview == nil) { CGRect frame = self.scrollView.frame; frame.origin.x = frame.size.width * page; frame.origin.y = 0; controller.view.frame = frame; [self.scrollView addSubview:controller.view]; }}
Process scrollingTo process scrolling, we need to implement several uiscrollviewdelegate methods and declare the method as soon as possible-(ibaction) changepage :( ID) sender must first know how rolling is implemented, or gesture, either click the uipagecontrol side. Let's take a look at the following code:
// At the begin of scroll dragging, reset the boolean used when scrolls originate from the UIPageControl- (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;} - (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView { UIViewController *oldViewController = [self.childViewControllers objectAtIndex:_page]; UIViewController *newViewController = [self.childViewControllers objectAtIndex:self.pageControl.currentPage]; [oldViewController viewDidDisappear:YES]; [newViewController viewDidAppear:YES]; _page = self.pageControl.currentPage;}Now, to update the current display when the page changes, we only need to implement the scrollviewdidscroll delegate method and the changepage ibaction method.
- (IBAction)changePage:(id)sender { intpage = ((UIPageControl *)sender).currentPage; // update the scroll view to the appropriate page CGRect frame = self.scrollView.frame; frame.origin.x = frame.size.width * page; frame.origin.y = 0; UIViewController *oldViewController = [self.childViewControllers objectAtIndex:_page]; UIViewController *newViewController = [self.childViewControllers objectAtIndex:self.pageControl.currentPage]; [oldViewController viewWillDisappear:YES]; [newViewController viewWillAppear:YES]; [self.scrollView scrollRectToVisible:frame animated:YES]; // Set the boolean used when scrolls originate from the UIPageControl. See scrollViewDidScroll: above. _pageControlUsed = YES;} - (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 || _rotating) { // 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 = self.scrollView.frame.size.width; intpage = floor((self.scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1; if(self.pageControl.currentPage != page) { UIViewController *oldViewController = [self.childViewControllers objectAtIndex:self.pageControl.currentPage]; UIViewController *newViewController = [self.childViewControllers objectAtIndex:page]; [oldViewController viewWillDisappear:YES]; [newViewController viewWillAppear:YES]; self.pageControl.currentPage = page; [oldViewController viewDidDisappear:YES]; [newViewController viewDidAppear:YES]; _page = page; }}
Final Processing Rotation
First, return yes in the shouldautorotatetointerfaceorientation method, and transmit three messages to the currently displayed sub-uiviewcontroller.
willAnimateRotationToInterfaceOrientation:duration:willRotateToInterfaceOrientation:duration:didRotateFromInterfaceOrientation:
However, we still need to solve the Rotation Problem by ourselves, such as re-scaling the contentview of the scrollview and adjusting the Frame Rate of the sub-view. Otherwise, something unexpected will occur. So let's take a look at the following processing methods:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{ returnYES;} - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { UIViewController *viewController = [self.childViewControllers objectAtIndex:self.pageControl.currentPage]; [viewController willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration]; _rotating = YES;} - (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { UIViewController *viewController = [self.childViewControllers objectAtIndex:self.pageControl.currentPage]; [viewController willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration]; self.scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * [self.childViewControllers count], scrollView.frame.size.height); NSUInteger page = 0; for(viewController in self.childViewControllers) { CGRect frame = self.scrollView.frame; frame.origin.x = frame.size.width * page; frame.origin.y = 0; viewController.view.frame = frame; page++; } CGRect frame = self.scrollView.frame; frame.origin.x = frame.size.width * _page; frame.origin.y = 0; [self.scrollView scrollRectToVisible:frame animated:NO]; } - (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { _rotating = NO; UIViewController *viewController = [self.childViewControllers objectAtIndex:self.pageControl.currentPage]; [viewController didRotateFromInterfaceOrientation:fromInterfaceOrientation];}
Summary
Let's talk nonsense. Here we release the code on GitHub.