objective-c - 跨 subview Controller 从 UITabBarController 继承/保留 UINavigationBar?

标签 objective-c cocoa-touch uitabbarcontroller uinavigationbar

我创建了一个 UITabBarController,其中包含多个 UIViewControllers 作为其选项卡。我还想在此 UITabBarController 中显示一个常量 UINavigationBar,它将跨选项卡持续存在。由于 UITabBarController 的 subview Controller 都不是 UINavigationControllers,我希望这是可能的并且不会引起冲突。有办法做到这一点吗?

目前我正在将完全相同的 UINavigationBar 和相应的逻辑复制粘贴到每个 subview Controller ,所以我猜有更好的方法。

关于这为何有用:想象一个 UINavigationBar,它包含两个 UIBarButtonItems,用于“注销”和“帐户”。按“注销”将使您注销并推送一个模态视图 Controller ,以便您可以重新登录,而按“帐户”将调出一个带有您的帐户信息的模态视图 Controller 。

我在 Stack Overflow 上发现了这个现有问题,但问题本身及其评论都措辞不当且信息不足:How to add a navigation bar to UITabBarController?


更新:

我觉得我可能没有很好地解释自己,所以我创建了一个图形来说明我正在尝试做的事情。在下图中,我有一个 UITabBarController,它以四个 UIViewController 作为子级呈现。我希望有一个不变的 UINavigationBar,以便用户可以按 Done 关闭模态呈现的 View Controller 。由于每个 subview Controller 都是一个单独的 View ,因此似乎没有必要将每个 subview Controller 嵌入到它自己的 UINavigationController 中,以便让 UINavigationBar 出现。当前,当 UITabBarController 以模态方式呈现时,不会出现导航栏。

Visualization of desired UITabBarController with UINavigationBar and child UIViewControllers

最佳答案

我终于让它工作了!!

简而言之:您不能继承或保留 UINavigationBar,但您可以通过其 UINavigationItem 设置其 UIBarButtonItem

这是我所做的,然后是相关代码,然后是注意事项:

我做了什么:

1) UITabBarController 子类:我创建了自己的 UITabBarController 自定义子类。因为我希望我的两个 UIBarButtonItem 跨选项卡持续存在,所以我还在我的 UITabBarController 子类中创建了 @property。因为我还希望我的 UITabBarController 处理这些 UIBarButtonItem,所以我还在我的 UITabBarController 子类中为每个按钮创建了一个方法。

2) 在 UINavigationControllers 中为选项卡嵌入 View Controller :即使您不想要或不需要 UINavigationController,这是获得预期效果的最佳方式,因为在iOS 7 导航栏在状态栏下方向上延伸到屏幕顶部。 (据我所知,我无法在没有 UINavigationController 的情况下使用 UINavigationBar 在 iOS 7 中复制这种效果。)

3) Assign UIBarButtonItems To Top View Controllers:我将 UITabBarController 子类中的 UIBarButtonItem 分配给了我想要的 View Controller 标签栏 Controller 的 -[initWithNibName:bundle:]-[awakeFromNib] 方法。我通过 self.viewControllers 遍历在我的选项卡栏 Controller 中分配为选项卡的所有 View Controller 来完成此操作;检查它们是否是 UINavigationController;并通过 [navigationController.topViewController.navigationItem setLeftBarButtonItem:self.leftBarButton][navigationController. topViewController.navigationItem setRightBarButtonItem:self.RightBarButton].

相关代码:

// MyTabBarController.h //

@interface MyTabBarController () <UITabBarControllerDelegate>
@property (nonatomic, strong) UIBarButtonItem *leftBarButton;
@property (nonatomic, strong) UIBarButtonItem *rightBarButton;
- (void)setup;
- (void)buttonLeft:(UIBarButtonItem *)sender;
- (void)buttonRight:(UIBarButtonItem *)sender;
@end

@implementation MyTabBarController

@synthesize leftBarButton = _leftBarButton;
@synthesize rightBarButton = _rightBarButton;

- (UIBarButtonItem *)leftBarButton
{
    if (!_leftBarButton) _leftBarButton = [[UIBarButtonItem alloc] initWithTitle:@"Left" style:UIBarButtonItemStyleBordered target:self action:@selector(buttonLeft:)];
    return _leftBarButton;
}

- (UIBarButtonItem *)rightBarButton
{
    if (!_rightBarButton) _rightBarButton = [[UIBarButtonItem alloc] initWithTitle:@"Right" style:UIBarButtonItemStyleBordered target:self action:@selector(buttonRight:)];
    return _rightBarButton;
}

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self)
    {
        [self setup];
    }
    return self;
}

- (void)awakeFromNib
{
    [self setup];
}

- (void)setup
{
    [self setDelegate:self]; // since I am using myself as the UITabBarControllerDelegate
    for (UIViewController *viewController in self.viewControllers)
    {
        if ([viewController isKindOfClass:[UINavigationController class]])
        {
            UINavigationController *navigationController = (UINavigationController *)viewController;
            [navigationController.topViewController.navigationItem setLeftBarButtonItem:self.leftBarButton];
            [navigationController.topViewController.navigationItem setRightBarButtonItem:self.rightBarButton];
        }
    }
}

- (void)buttonLeft:(UIBarButtonItem *)sender
{
    // Left bar button action
}

- (void)buttonRight:(UIBarButtonItem *)sender
{
    // Right bar button action
}

@end

注意事项:

在实现我的解决方案的过程中,我学到了很多东西,包括以下内容:

  • 您不能以编程方式设置自己的 UINavigationBar。您最多可以创建自己的自定义 UINavigationBar 子类并将其设置为您的 UINavigationController 如所述通过 Interface Builder/Storyboard here (external website: iOS Dev Notes) .
  • 您不能从 XIB 创建和使用 UINavigationBar,如下所述:How to customize UINavigationBar with XIB?
  • 通过将 UINavigationBar 和 UITabBar 拖入 UIViewController 来组合“UITabBarController/UINavigationController”在 iOS 7 中不起作用,因为 iOS 7 使用重叠的半透明 UI 元素,而这些元素的重叠不能以编程方式设置良好(例如,状态栏后面的导航栏的扩展)。
  • 在 UINavigationController 中嵌入 UITabBarController 可行,但 Apple 文档明确不鼓励/禁止。这是因为嵌入顶级导航功能(即允许用户的 UITabBarController在应该能够推送和弹出其 View Controller 的 UI 中在并行接口(interface)之间切换)。

关于objective-c - 跨 subview Controller 从 UITabBarController 继承/保留 UINavigationBar?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21447080/

相关文章:

iphone - 如何更改 UItabbar 图标图像?

iphone - 如何使方法更改 Root View

ios - 折叠 Objective-c 中的部分

objective-c - 在没有 Nib 的应用程序中跟踪鼠标位置

iPhone - 当设备方向改变时 UIViewController 不旋转

ios - 使 View Controller 不在选项卡式 View 中

iphone - UIWindow 的 'rootViewController' 导出在 iOS 4.0 之前的版本上不可用

ios - 以编程方式设置自定义图像大小和位置

objective-c - 寻找 iPhoneOS 中的 marg_setValue 修复

objective-c - xcode 无法隐藏 tabbarcontroller