如何在使用UIPageViewController时将UIBarButtonItem添加到NavigationBar

时间:2014-02-12 16:51:43

标签: ios uinavigationcontroller uinavigationbar uibarbuttonitem uipageviewcontroller

请原谅我,关于如何以编程方式将一个UIBarButtonItem添加到NavigationBar已经有很多问题,但我似乎无法让任何解决方案在我的情况下工作。

以下是我一直在学习UIPageViewController的简单测试应用程序的布局。

storyboard

我让页面视图控制器与三个独特的viewControllers很好地协同工作。我现在想为每个视图控制器设置唯一的rightBarButtonItems。我只需执行此操作即可轻松在barButtonItem中设置公共DetailViewController

UIBarButtonItem *newButton = [[UIBarButtonItem alloc] initWithTitle:@"Whatever" 
                              style:UIBarButtonItemStylePlain 
                              target:self 
                              action:@selector(doSomething)];    

self.navigationItem.rightBarButtonItem = newButton;

鉴于我需要pageViewController中三个页面中每个页面的唯一按钮,我无法在detailViewController中设置按钮。我在三个控制器的viewDidAppear中尝试了上面的代码,但按钮不会出现。我也尝试以相同的方式创建按钮,然后设置它,没有运气。

DetailViewController *vc = [[DetailViewController alloc] init];
vc.navigationItem.rightBarButtonItem = newButton;

我知道我离这里很近,我只是不确定如何指定我需要在NavigationController的NavigationBar中添加一个按钮,该按钮运行我的contentViewControllers所嵌入的detailViewController。任何帮助都会很棒ESPECIALLY片段。

作为旁注,我尝试了一些其他方法,这些方法都存在问题。

  • viewDidLoad而不是viewDidAppear中设置按钮
    • 这不起作用,因为每次从一个页面滑动到下一个页面时都不会调用viewDidLoad方法。然而,viewDidAppear方法是如此,我试图在那里设置按钮。每次都可以调用viewWillAppear,但我没有检查过。
  • 在UIPageViewController委托方法中设置按钮
    • 如果用户翻阅页面以快速按钮无法更改或无法显示,则会出现问题。

事实证明我很接近......而不是在UIPageViewController方法中创建按钮,我只需要在我的三个视图控制器中创建一个navigationItem属性。当控制器在委托方法中实例化时,我只需将navigationItem属性设置为等于detailViewController的属性。那样在我的viewDidApper方法中我可以创建按钮。然后在viewWillDisappear我将按钮设置为nil。您也可以在viewdidLoad的{​​{1}}处创建按钮,然后更改各个viewControllers的DetailViewController中的文本和操作。这是一个样本。

在委托方法

viewDidAppear

我根据viewController的索引调用一个辅助方法。辅助方法在调用视图控制器时实例化它。实例化后,我设置了一些属性,包括navigationItem属性。

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController

然后在viewController的-(FirstController *)controllerAtIndex:(NSUInteger)index { FirstController *fvc = [self.storyboard instantiateViewControllerWithIdentifier:@"FirstPageController"]; fvc.imageFile = self.pageImages[index]; fvc.titleText = self.pageTitles[index]; fvc.pageIndex = index; fvc.navItem = self.navigationItem; return fvc; } 中,我就这样做了

viewDidAppear

3 个答案:

答案 0 :(得分:2)

如果每次更改所查看的页面时都需要更改按钮,则必须在您尝试过的一种委托方法中完成。但我建议,您只需更改标题,而不是创建新按钮并将其设置为导航项。

您可以在界面构建器中创建按钮,并将其链接到DetailViewController中的媒体资源,然后每次进入新页面时都会在按钮上调用setTitle:forState UIControlStateNormal

如果您需要按钮为每个页面执行不同的操作,我建议您在按钮操作方法中检查当前页面,而不是每次都声明一个新页面。

答案 1 :(得分:1)

通过在其某个分页视图控制器中查找页面控制器,然后获取其导航项,您可以找到正确的导航项来设置按钮/标题。 e.g。

UIViewController *pageController = [[self.navigationController childViewControllers] lastObject];
pageController.navigationItem.title = @"My page's title";

self.navigationItem不起作用真的很烦人!

答案 2 :(得分:0)

我的一位同事遇到了与页面视图控制器相同的问题。

据我了解,您无法将UIBarButtonItem添加到UIPageViewController中成员视图控制器的导航栏。对于UIPageViewController,'navigationController'的原因设置为nil。要确认,请打印[UIPageViewController navigationController]的值。

但是你可以做一件事来克服这个问题。请下载示例PhotoScroller

在AppDelegate.m中进行以下更改

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{
// kick things off by making the first page
PhotoViewController *pageZero = [PhotoViewController photoViewControllerForPageIndex:0];

UINavigationController * nav = [[UINavigationController alloc] initWithRootViewController:pageZero];
if (pageZero != nil)
{
    // assign the first page to the pageViewController (our rootViewController)
    UIPageViewController *pageViewController = (UIPageViewController *)self.window.rootViewController;
    pageViewController.dataSource = self;

    [pageViewController setViewControllers:@[nav]
                                  direction:UIPageViewControllerNavigationDirectionForward
                                   animated:NO
                                 completion:NULL];
}
return YES;
}

以及PhotoViewController.m中的更改

- (void)loadView 
{
.....
.....
self.title =@"Frogs";
UIBarButtonItem *newButton = [[UIBarButtonItem alloc] initWithTitle:@"Something" style:UIBarButtonItemStylePlain target:self action:@selector(doSomething)];

[newButton setTintColor:[UIColor redColor]];
self.navigationItem.rightBarButtonItem = newButton;
}

为避免崩溃,您必须在AppDelegate.m中正确处理UIPageViewControllerDataSource委托方法

尽管如此,我不建议你去做,因为它打破了UIPageViewController的整个概念。

我希望这会有所帮助。