如何使用 UIPageViewController 加载单独的 XIB?

2024-01-06

我正在深入研究 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>

在此委托的 .m 文件中,包括:

// 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{};如果没有,请不要忘记您的保留/释放周期。

我希望这有帮助!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 UIPageViewController 加载单独的 XIB? 的相关文章

  • CoreMediaIO,错误更新的属性 kCMIODevicePropertyDeviceIsRunningSomewhere

    当某些进程开始使用相机时 我需要接收一个事件 我通过 CMIOObjectGetPropertyData 完成此操作 但它不能正常工作 只有第一次访问时才是正确的值 我还尝试使用 CMIOObjectAddPropertyListenerB
  • XCode 4 中的标头搜索路径

    我想添加一个路径到标题搜索路径 但是 在构建设置中 当我双击标题搜索路径时 它不会弹出一个可以输入的新窗口 我做错了什么 单击左侧文件导航器中的项目 然后在出现的编辑器中单击项目或目标 单击 构建设置 然后从 基本 更改为 全部 它位于搜索
  • #include 在 iOS 的 C++ 文件中找不到文件

    我在 iOS 下有一个目标 c c 项目 将其从 OS X 移动 然后出现 文件未找到 错误 include
  • UITextField 文本更改事件

    如何检测文本字段中的任何文本更改 委托方法shouldChangeCharactersInRange适用于某些东西 但它并不能完全满足我的需求 因为在它返回 YES 之前 textField 文本不可用于其他观察者方法 例如在我的代码中ca
  • 带 ModalPresentationStyle 的弹出框在 iOS 7 iPad 中不居中

    我在使用 iOS 7 时遇到了一个问题 这似乎是一个错误 或者只是我没有做正确的事情 我有 modalViewController 它在 iPad 上以 ModalPresentationStyle 的形式显示为弹出窗口 而且它不是标准尺寸
  • 部署目标是什么意思?

    这是我假设的一个非常简单的问题 有人可以告诉我部署目标是什么意思吗 如果我选择 iOS 10 是否意味着只有 iOS 10 的用户才能下载该应用程序 选择较低的部署目标是否不好 另外 继续部署目标 是否不建议在较低的部署目标上运行 假设您已
  • 故事板 - 不支持的配置 8 个冲突的约束

    我正在使用故事板自动布局 我今天在编写警告消息时注意到 MainStoryboard iphone storyboard Unsupported Configuration 8 conflicting constraints 单击警告会进入
  • NSDictionary 上的 NSPredicate

    我试图根据字母表在表格视图中创建部分 并在这些部分下按字母顺序对我的条目进行排序 我已经收集了 bandArrayIndex 中 bandArray 每个条目的第一个字母 现在我尝试使用 NSPredicate 来计算每个字母有多少个 我正
  • 将第 3 方库 ZXing 导入 Xcode

    我尝试了多种方法将第 3 方库 ZXing 导入我的 iOS 应用程序 但所有方法都很痛苦 或者根本不起作用 如果有人可以建议我做错了什么 或者提出导入 ZXing 等库的更好方法 我将非常感激 一定比这个容易 这就是我所做的 结果是 My
  • 在 uilabel 中查找文本的位置 {x,y}

    我有一个来自服务器的字符串 我正在 UILabel multiligne 上显示它 在该字符串中 我正在识别一些特定的子字符串 我想在该子字符串上放置一个按钮 按钮将是 UILabel 的子视图 为此 我需要子字符串坐标 我经历过这个 但我
  • 您是否标记 UIView 或将它们保留为属性?

    这主要是一个风格问题 但自从我开始为 iPhone 编程以来 我一直很好奇其他人的想法是什么 当您的 iPhone 应用程序中有一个 UIView 并且需要在应用程序的其他位置访问它时 通常在视图控制器中的另一个函数中 您是否喜欢用整数标记
  • 是否有适用于 iPad 2 的条码扫描仪 SDK? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 在 Objective-C 中比较 2 个字符串

    我写了以下代码 if depSelectedIndice gt 1 comSelectedIndice gt 1 NSLog depart elemet d depSelectedIndice NSLog depart elemet d c
  • Crashlytics dSYM 错误

    我已经在我的 mac 上安装了 crashlytics 并想用它来设置我的项目 xcode 我通过复制代码创建运行脚本构建阶段 第一次构建的结果是 PhaseScriptExecution Run Script Users danielbo
  • NSString – 静态还是内联?有性能提升吗?

    如果我写的话会有任何性能提升吗 NSString helloStringWithName NSString name static NSString formatString Hello return NSString stringWith
  • 在 iphone/ipad 选项卡之间共享 NSManagedObjectContext 和其他服务类

    我很乐意构建一个基于 Core Data 选项卡的 iPad 应用程序 我在我的应用程序委托类中使用以下内容将 NSManagedObjectContext 传递到我的根视图 BOOL application UIApplication a
  • 导入 RNCryptor 后架构 armv7 的未定义符号

    我导入了 RNCryptor 可以在这里找到 https github com rnapier RNCryptor https github com rnapier RNCryptor进入我的应用程序 但是 我在日志中收到了三个错误 Und
  • 水平 UICollectionView 单行布局

    我正在尝试使用以下命令设置简单的水平布局UICollectionView 兜圈子却没有达到预期的结果 所以任何指针或例子将不胜感激 我粘贴经常更改的代码但没有成功可能没什么意义 该图像显示两行 第一行是单个项目 尺寸正确并且在中心正确对齐
  • UIImageJPEGRepresentation 在视网膜显示屏上提供 2x 图像

    我有这段代码 它创建一个图像 然后向其添加一些效果并缩小其大小以使其largeThumbnail UIImage originalImage UIImage imageWithData self originalImage thumbnai
  • iOS - UITableViewCell 使文本加粗

    我有一个字符串 NSString userInfo James Johnson james 我想做的就是大胆James Johnson并保留 james正常字体 所以我尝试过的是使用NSAttributedString但为了完成这个过程 我

随机推荐

  • listStatus 端点包括响应中的收件人状态

    有没有办法在 listStatus 端点的响应正文中包含收件人状态 这是我提出的卷曲请求 curl X PUT https na2 docusign net restapi v2 accounts XXXXX envelopes statu
  • Javascript 相当于 Java 的 UUID 类

    在java中 你可以做类似的事情 UUID id UUID fromString eb66c416 4739 465b 9af3 9dc33ed8eef9 long msb id getMostSignificantBits long ls
  • 把jdbc操作放在actor中好不好?

    我正在构建一个传统的 Web 应用程序 通过 JDBC 执行数据库 CRUD 操作 我想知道将 jdbc 操作放入当前请求处理线程之外的参与者中是否合适 我做了一些搜索 但没有找到演示此功能的教程或示例应用程序 那么有哪些缺点和优点呢 这种
  • 如何在 PHP 中重命名子数组键? [复制]

    这个问题在这里已经有答案了 当我对名为 tags 多维数组 的变量进行 var dump 时 我得到以下信息 Array 0 gt Array name gt tabbing url gt tabbing 1 gt Array name g
  • 如何让查询生成器将其原始 SQL 查询输出为字符串?

    给出以下代码 DB table users gt get 我想获取上面的数据库查询生成器将生成的原始 SQL 查询字符串 在这个例子中 它将是SELECT FROM users 我该怎么做呢 Answer recommended by PH
  • 以编程方式更改 Android EditText 的色调颜色

    我正在尝试改变一个的着色颜色EditText在运行时以编程方式查看 基本上我想改变你通常应用的内容 attr colorControlNormal就像在默认背景可绘制 https github com android platform fr
  • nth-child:如何选择两个一组的元素

    假设我有一个这样的表 div class fc slats table tbody tr td class fc widget content fc major 16 td td class fc widget content fc min
  • play 和 postgres 未找到关系错误(虽然表确实存在)

    我有一个名为 ETL TABLES 的表 它驻留在公共模式上 在 我的 application conf 我有以下行 hibernate default schema public 这应该意味着 postgres 的 search path
  • Android - 等待齐射响应以继续

    我构建了一个应用程序 它在地图中加载标记 我为 volley JSON 文件获取标记 但我需要首先加载 volley 然后继续执行代码 因为另一种方式显示错误纬度空 这个参数加载得不快 另一个方法先执行并显示 null 我的负载标记齐射代码
  • React/TypeScript:具体为组件输入 props.children

    假设我们有一个组件Foo呈现props children和另一个组件Bar 两个模块都导出一个 props 接口 有没有办法强制执行Foo的孩子可以是only类型的Bar 理想情况下 我们可以在构建时使用 TypeScript 来完成此任务
  • 在 CakePHP 3 中连接多个数据库

    我想将一些数据历史记录和日志存储在其他数据库表中 就未来的记录而言 这可能是非常大的数据库 还应该支持跨数据库 SQL 连接 所以请帮我解决这个问题 提前致谢 您可以按照以下步骤在同一个 cakephp 应用程序中使用多个数据源 在 Con
  • .NET 中的标准输入和输出

    如何从标准输入读取并写入标准输出 System Diagnostics Process StandardInput 的 MSDN 参考没有帮助 因为它单独启动进程 然后重定向标准输入 输出 但是如果该进程已经在运行并调用我的应用程序来为其提
  • 需要一个 CouchDB 技巧来按日期排序并按组过滤

    我有包含 日期 和 组 字段的文档 这是我的观点 byDateGroup map function doc if doc date doc group emit doc date doc group null 与此等效的查询是什么 sele
  • Java 中的独立 Socket.IO 服务器

    我正在寻找一个用 Java 编写的简单 Socket IO 服务器 我熟悉this one http code google com p socketio java 但它依赖于 servlet 而我没有在我的应用程序中使用它 我正在寻找类似
  • Spark python中基于条件过滤RDD并提取匹配数据

    我有这样的数据 cl id cn id cn value 10004 77173296 390 0 10004 77173299 376 0 10004 77173300 0 0 20005 77173296 0 0 20005 77173
  • 媒体源扩展 (MSE) 与 WebRTC 的比较

    媒体源扩展和 WebRTC 之间的根本区别是什么 我可以暂时表达一下我自己的理解吗 WebRTC 包含一个 RTCPeerConnection 它处理从媒体流获取流并将它们传递到协议以流式传输到应用程序的连接对等点 WebRTC 似乎在底层
  • 替换 pandas 数据框中很少出现的值

    我有一个中等大 约 60 000 行 x 15 列 的 csv 文件 我正在使用 pandas 处理它 每行代表一个人并包含个人数据 我想匿名呈现数据 我想要这样做的一种方法是替换特定列中罕见的值 我最初尝试这样做 def clean da
  • Selenium:如何等到光标发生变化?

    使用 CSS JS 可以更改用户看到的鼠标指针光标 例如 您可以设置cursor wait将光标更改为微调器 我想做的是进行 Selenium 测试 等待光标更改为 从wait 但是 我找不到任何 预期条件 EC 方法来观察光标的 CSS
  • Convert.DateTime 引发错误:字符串未被识别为“06-13-2012”的有效日期时间

    我正在将一个日期插入我的数据库 该值来自 s theDate Convert ToDateTime 06 13 2012 我收到错误 字符串未被识别为有效的日期时间 我该如何解决这个问题 尝试这个 DateTime ParseExact 0
  • 如何使用 UIPageViewController 加载单独的 XIB?

    我正在深入研究 UIPageViewControllers 的新世界 那里有很多教程 但是它们似乎都创建了一个视图 然后仅使用具有不同内容的新实例 我真的很希望能够创建多个 XIB 然后将它们与 UIPageViewController 链