我正在深入研究UIPageViewControllers的新世界,并且有很多教程,但是它们似乎都创建了一个视图,然后只使用不同内容的新实例.
我真的希望能够创建多个XIB,然后将它们与UIPageViewController链接起来,但它太新了,我无法理解它的工作方式.
解决方法
好吧,这是一个很长的答案,你应该能够复制和粘贴. (此代码改编自Erica Sadun(https://
github.com/erica/iOS-5-Cookbook))
首先,创建一个类型为UIPageViewController的新类.称之为BookController.现在将以下代码粘贴到.h文件中.
// Used for storing the most recent book page used #define DEFAULTS_BOOKPAGE @"BookControllerMostRecentPage" @protocol BookControllerDelegate <NSObject> - (id) viewControllerForPage: (int) pageNumber; @optional - (void) bookControllerDidTurnToPage: (NSNumber *) pageNumber; @end @interface BookController : UIPageViewController <UIPageViewControllerDelegate,UIPageViewControllerDataSource> + (id) bookWithDelegate: (id) theDelegate; + (id) rotatableViewController; - (void) moveToPage: (uint) requestedPage; - (int) currentPage; @property (assign) id <BookControllerDelegate> bookDelegate; @property (nonatomic,assign) uint pageNumber;
并在您的.m文件中:
#define IS_IPHONE ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) #define SAFE_ADD(_Array_,_Object_) {if (_Object_ && [_Array_ isKindOfClass:[NSMutableArray class]]) [pageControllers addObject:_Object_];} #define SAFE_PERFORM_WITH_ARG(THE_OBJECT,THE_SELECTOR,THE_ARG) (([THE_OBJECT respondsToSelector:THE_SELECTOR]) ? [THE_OBJECT performSelector:THE_SELECTOR withObject:THE_ARG] : nil) #pragma Utility Class - VC that Rotates @interface RotatableVC : UIViewController @end @implementation RotatableVC - (void) loadView { [super loadView]; self.view.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; self.view.backgroundColor = [UIColor whiteColor]; } - (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation { return YES; } @end #pragma Book Controller @implementation BookController @synthesize bookDelegate,pageNumber; #pragma mark Debug / Utility - (int) currentPage { int pageCheck = ((UIViewController *)[self.viewControllers objectAtIndex:0]).view.tag; return pageCheck; } #pragma mark Page Handling // Update if you'd rather use some other decision style - (BOOL) useSideBySide: (UIInterfaceOrientation) orientation { BOOL isLandscape = UIInterfaceOrientationIsLandscape(orientation); return isLandscape; } // Store the new page and update the delegate - (void) updatePageTo: (uint) newPageNumber { pageNumber = newPageNumber; [[NSUserDefaults standardUserDefaults] setInteger:pageNumber forKey:DEFAULTS_BOOKPAGE]; [[NSUserDefaults standardUserDefaults] synchronize]; SAFE_PERFORM_WITH_ARG(bookDelegate,@selector(bookControllerDidTurnToPage:),[NSNumber numberWithInt:pageNumber]); } // Request controller from delegate - (UIViewController *) controllerAtPage: (int) aPageNumber { if (bookDelegate && [bookDelegate respondsToSelector:@selector(viewControllerForPage:)]) { UIViewController *controller = [bookDelegate viewControllerForPage:aPageNumber]; controller.view.tag = aPageNumber; return controller; } return nil; } // Update interface to the given page - (void) fetchControllersForPage: (uint) requestedPage orientation: (UIInterfaceOrientation) orientation { BOOL sideBySide = [self useSideBySide:orientation]; int numberOfPagesNeeded = sideBySide ? 2 : 1; int currentCount = self.viewControllers.count; uint leftPage = requestedPage; if (sideBySide && (leftPage % 2)) leftPage--; // Only check against current page when count is appropriate if (currentCount && (currentCount == numberOfPagesNeeded)) { if (pageNumber == requestedPage) return; if (pageNumber == leftPage) return; } // Decide the prevailing direction by checking the new page against the old UIPageViewControllerNavigationDirection direction = (requestedPage > pageNumber) ? UIPageViewControllerNavigationDirectionForward : UIPageViewControllerNavigationDirectionReverse; [self updatePageTo:requestedPage]; // Update the controllers NSMutableArray *pageControllers = [NSMutableArray array]; SAFE_ADD(pageControllers,[self controllerAtPage:leftPage]); if (sideBySide) SAFE_ADD(pageControllers,[self controllerAtPage:leftPage + 1]); [self setViewControllers:pageControllers direction: direction animated:YES completion:nil]; } // Entry point for external move request - (void) moveToPage: (uint) requestedPage { [self fetchControllersForPage:requestedPage orientation:(UIInterfaceOrientation)[UIDevice currentDevice].orientation]; } #pragma mark Data Source - (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController { [self updatePageTo:pageNumber + 1]; return [self controllerAtPage:(viewController.view.tag + 1)]; } - (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController { [self updatePageTo:pageNumber - 1]; return [self controllerAtPage:(viewController.view.tag - 1)]; } #pragma mark Delegate - (UIPageViewControllerSpineLocation)pageViewController:(UIPageViewController *)pageViewController spineLocationForInterfaceOrientation:(UIInterfaceOrientation)orientation { NSUInteger indexOfCurrentViewController = 0; if (self.viewControllers.count) indexOfCurrentViewController = ((UIViewController *)[self.viewControllers objectAtIndex:0]).view.tag; [self fetchControllersForPage:indexOfCurrentViewController orientation:orientation]; BOOL sideBySide = [self useSideBySide:orientation]; self.doubleSided = sideBySide; UIPageViewControllerSpineLocation spineLocation = sideBySide ? UIPageViewControllerSpineLocationMid : UIPageViewControllerSpineLocationMin; return spineLocation; } -(void)dealloc{ self.bookDelegate = nil; } #pragma mark Class utility routines // Return a UIViewController that knows how to rotate + (id) rotatableViewController { UIViewController *vc = [[RotatableVC alloc] init]; return vc; } // Return a new book + (id) bookWithDelegate: (id) theDelegate { BookController *bc = [[BookController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStylePageCurl navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil]; bc.dataSource = bc; bc.delegate = bc; bc.bookDelegate = theDelegate; return bc; }
此类现在可用于控制您在任何项目中创建的任何书籍,以及单个项目中的多本书籍.对于每本书,使用@interface创建一个委托UIPageViewController:
@interface NameOfBookController : UIPageViewController <BookControllerDelegate>
// Implement loadView to create a view hierarchy programmatically,without using a nib. - (void)loadView { [super loadView]; CGRect appRect = [[UIScreen mainScreen] applicationFrame]; self.view = [[UIView alloc] initWithFrame: appRect]; self.view.backgroundColor = [UIColor whiteColor]; self.view.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; // Establish the page view controller bookController = [BookController bookWithDelegate:self]; bookController.view.frame = (CGRect){.size = appRect.size}; } // Implement viewDidLoad to do additional setup after loading the view,typically from a nib. - (void)viewDidLoad { // Add the child controller,and set it to the first page [self.view addSubview:bookController.view]; [self addChildViewController:bookController]; [bookController didMoveToParentViewController:self]; }
然后加:
- (id) viewControllerForPage: (int) pageNumber { // Establish a new controller UIViewController *controller; switch (pageNumber) { case 0: view1 = [[FirstViewController alloc] init]; view1.view.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; controller = view1; //rinse and repeat with each new view controller break; case 1: //etc. break; default: return nil; break; } return controller; }
为了记录,此代码不是内存安全的.如果使用ARC,请添加@autoreleasePool {};如果没有,请不要忘记您的保留/释放周期.
我希望这有帮助!