如何根据 PageViewController 更改按钮的操作?
Posted
技术标签:
【中文标题】如何根据 PageViewController 更改按钮的操作?【英文标题】:How to change the action of a button depending on the PageViewController? 【发布时间】:2014-07-27 17:02:49 【问题描述】:简介
Hello world,我是 Objective C 的新手,我一直在尝试使用 PageViewController
。我在制作这个应用程序时遇到的一个问题是根据PageViewController
更改按钮的操作。我已经通过多种方式处理了这种情况。
情况
我试图创建一个PageViewController
来帮助玩家选择游戏主题,但为了做到这一点,我需要弄清楚这个问题的答案。我遵循了这个tutorial,除了我去掉了startWalkthrough
按钮,因为它是不必要的,我更改了self.pageViewController.view = CGRectMake(0, 100, self.view.frame.size.width, self.view.frame.size.height - 200);
以及更改主视图控制器上的NSArray_pageTitles = @[@"Theme 1", @"Theme 2", @"Theme 3", @"Theme 4"];
,以便为按钮等提供更多空间。
我制作了一个新按钮 (chooseButton
) 和一个标签 (themeTitles
),作为示例来检查应用程序是否意识到它在主视图控制器上是哪个主题。我尝试使用以下代码行:
- (IBAction)chooseButton:(id)sender
if ()
_themeTitles.text = @"You chose theme 1";
if ()
_themeTitles.text = @"You chose theme 2";
if ()
_themeTitles.text = @"You chose theme 3";
if ()
_themeTitles.text = @"You chose theme 4";
您可能会注意到条件为空白。这是我尝试过各种事情的部分。这可能包括使用其他头文件中的属性,或在其自己的头文件中声明的属性,例如声明PageContentViewController *pageContentViewController;
,然后说if (pageContentViewController.pageIndex == 0)
等等直到等于3,或者说if (pageContentViewController.titleText isEqual: @"Theme 1")
。
当然,我还尝试在导入 AppDelegate *appDelegate;
并将 UIPageControl
公开为属性并将currentPage
属性设置为 if (AppDelegate.pageControl.currentPage == 0)
等之后声明它。
每一个选项我都快用尽了,而他们最终都在界面上为它所在的每个当前页面显示“你选择了主题 1”,或者根本不显示任何内容。
归根结底,关键是,我可以在 if 语句中加入什么条件才能让这个东西正常工作?
【问题讨论】:
【参考方案1】:UIPageViewController
没有本机的页码概念。它可以告诉您当前在 viewControllers 属性中可见哪些视图控制器,但您的工作是将它们映射到页面。
为什么?想象一本很大很大的书,其中每个页面都是一个视图控制器。将所有这些都保存在内存中会很浪费(就像UINavigationController
保存在当前堆栈中的方式一样)。所以 UIPageViewController 使页面数组是虚拟的,只向您的数据源询问相对于当前视图控制器的视图控制器。
该怎么办? SO中有几篇文章提出了建议。我最喜欢的是@EddieBorja 的回答here。简而言之,在创建视图控制器时为其分配索引属性(或 pageNumber)属性。
完成此操作后,您的操作方法可能如下所示:
- (IBAction)chooseButton:(id)sender
// get the currently visible view controllers
NSArray *viewControllers = self.myPageViewController.viewControllers
// get the first visible one
MyIndexKnowingViewController *myIndexKnowingVC = viewControllers[0];
// branch on it's index
if (myIndexKnowingVC.index == 0)
_themeTitles.text = @"You chose theme 1";
else (myIndexKnowingVC.index == 1)
// etc.
// if you have more than a few of these, consider a switch statement
// or even better ...
_themeTitles.text = [NSString stringWithFormat:@"You chose theme %d", myIndexKnowingVC.index+1];
以下是我如何实现我的数据源来设置索引(并在回答数据源协议时利用它):
#pragma mark - Page vc datasource
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
NSUInteger index = ((MyIndexKnowingViewController *)viewController).index;
return (index)? [self viewControllerAtIndex:index-1] : nil;
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
// note the +1
NSUInteger index = ((MyIndexKnowingViewController *)viewController).index + 1;
// define a max index that is one _greater_ then your number of pages
return (index < MAX_INDEX)? [self viewControllerAtIndex:index] : nil;
- (MyIndexKnowingViewController *)viewControllerAtIndex:(NSUInteger)index
// assuming it's defined in a xib, otherwise, just alloc-init
MyIndexKnowingViewController *childViewController = [[MyIndexKnowingViewController alloc] initWithNibName:@"MyIndexKnowingViewController" bundle:nil];
childViewController.index = index;
return childViewController;
【讨论】:
感谢您的回答,但它只显示了四页中的两页。最好只有return [self viewControllerAtIndex:index];
而没有.index + 1
。不管怎么说,还是要谢谢你! @danh
那个索引就是传入的vc的索引。该方法的目的是返回一个索引比传递的 vc 大一的 vc。如果 MAX_INDEX 太低,那将使它无法工作……嘿,想想看,我的评论是错误的。 MAX 应该比页数大一而不是小一。请参阅编辑 - 抱歉。
我更改了最大索引并再次使用了您的代码,但最终遇到了同样的问题...@danh以上是关于如何根据 PageViewController 更改按钮的操作?的主要内容,如果未能解决你的问题,请参考以下文章
如何通过 PageViewController 将 viewController 的数据传递给 pageViewController 的第二个 ViewController
如何在 SwiftUI 中的 PageViewController 中传递一些视图?
如何移动到 pageViewController 中的特定页面?