呈现模态视图控制器会隐藏导航栏

时间:2011-08-11 23:14:03

标签: objective-c ios cocoa-touch uinavigationbar modalviewcontroller

我有一个带导航栏的导航应用程序,但有一些实例,而不是将视图控制器推入堆栈,我需要以模态方式呈现视图控制器。问题是,当我关闭模态视图控制器时,除了导航栏被隐藏并且(父视图)已经调整大小之外,一切都按预期运行,这是根据文档的预期行为。所以我想我可以简单地调用内置方法取消隐藏导航栏。我已经尝试了

[self.navigationController setNavigationBarHidden:NO];

以及动画版本没有成功。

文档在方法

中讨论了这个问题
presentModalViewController: animated:

在讨论部分中,

  

在iPhone和iPod touch设备上,modalViewController的视图始终全屏显示“和”将modalViewController属性设置为指定的视图控制器。调整其视图大小并将其附加到视图层次结构。“但是,文档并没有让我知道在解除模态视图后如何撤消此过程。

有没有其他人经历过这个并找到了解决方案?

编辑:我遇到了同样的问题,所以我没有问自己的问题,而是赞助了这个问题。这是我的具体情况:

在我的情况下,我通过导航控制器在模态视图控制器中呈现图像选择器:

-(void) chooseImage {
    if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
        imagepicker = [[UIImagePickerController alloc] init];
        imagepicker.allowsEditing = NO;
        imagepicker.delegate = self;
        imagepicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
        imagepicker.navigationBar.opaque = true;
        imagepicker.wantsFullScreenLayout = NO;

        if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {

            if (self.view.window != nil) {
                popoverController = [[UIPopoverController alloc] initWithContentViewController:imagepicker];

                [popoverController presentPopoverFromBarButtonItem:reset permittedArrowDirections:UIPopoverArrowDirectionDown animated:YES];
            } else {}

        } else {
            [self.navigationController presentModalViewController:imagepicker animated:YES];   
        }
    }
}

-(void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
        [self.popoverController dismissPopoverAnimated:true];
    } else {
        [self.navigationController dismissModalViewControllerAnimated:YES];
    }
    //Save the image
}

-(void) imagePickerControllerDidCancel:(UIImagePickerController *)picker {
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
        [self.popoverController dismissPopoverAnimated:true];
    } else {
        [self.navigationController dismissModalViewControllerAnimated:YES];
    }
}

9 个答案:

答案 0 :(得分:18)

确保您从UINavigationController中呈现并解除modalViewController,如下所示:

// show
[self.navigationController presentModalViewController:vc animated:YES];
// dismiss
[self.navigationController dismissModalViewControllerAnimated:YES];

如果您的视图控制器实际上在UINavigationController的堆栈上,那么这是处理模式视图控制器的显示和解除的正确方法。如果您的UINavigationBar仍处于隐藏状态,那么还有其他一些时髦的东西,我们需要查看您的代码以确定发生了什么。

修改

我将你的代码复制到我的应用程序中,UIImagePickerController成功呈现并解散,我的UINavigationController的UINavigationBar仍然存在。我真的相信问题出现在你的架构的其他地方。如果您上传带有示例项目的zip,我将会看一下。

答案 1 :(得分:11)

只需尝试以下代码即可使用

SettingsViewController *settings    =   [[SettingsViewController alloc] init];
UINavigationController *navcont = [[UINavigationController alloc] initWithRootViewController:settings];
[self presentModalViewController:navcont animated:YES];
[settings release];
[navcont release];

需要提供导航控制器才能在呈现的控制器上显示导航栏

答案 2 :(得分:3)

我认为在错误的VC上呈现视图控制器时我已经看到过这种行为。您是在导航控制器或单个VC上调用presentModalViewController吗?

如果您还没有尝试从navigationController调用它。

[self.navigationController presentModalViewController:myVC animated:YES];

答案 3 :(得分:1)

检查一下。这是UIViewController类参考下的Apple文档:

它清楚地提到模态视图总是以全屏模式显示,因此很明显导航栏将被隐藏。因此,将单独的导航栏放在模态视图上以导航回来。

presentModalViewController:animated:
Presents a modal view managed by the given view controller to the user.

- (void)presentModalViewController:(UIViewController *)modalViewController animated:(BOOL)animated
Parameters
modalViewController
The view controller that manages the modal view.
animated
If YES, animates the view as it’s presented; otherwise, does not.
Discussion
On iPhone and iPod touch devices, the view of modalViewController is always presented full screen. On iPad, the presentation depends on the value in the modalPresentationStyle property.

Sets the modalViewController property to the specified view controller. Resizes its view and attaches it to the view hierarchy. The view is animated according to the transition style specified in the modalTransitionStyle property of the controller in the modalViewController parameter.

Availability
Available in iOS 2.0 and later.

希望这有助于您了解隐藏整个视图以及导航控制器是模态视图的默认行为,因此请尝试在模态视图中放置单独的导航栏以进行导航。

您可以在此链接上进一步查看

http://developer.apple.com/library/ios/#documentation/uikit/reference/UIViewController_Class/Reference/Reference.html

答案 4 :(得分:1)

如果您将控制器显示为模型,则视图控制器将显示为总视图。

如果要通过模型视图访问导航控制器属性,则需要创建另一个导航控制器参考,并且它将像以前一样继续。

这可能对您有用。

答案 5 :(得分:1)

1. 

{"root": {
    "item": [
        {
            "groupName": "Al Karama Fire Station",
            "vehicleId": 211,
            "speed": 81
        },
        {
            "groupName": "Al Karama Fire Station",
            "vehicleId": 137,
            "speed": 83
        }
    ],
    "rowCount": 2
}}

为我工作显示导航栏

答案 6 :(得分:0)

强调和德文 -

当我开始阅读Apple文档以熟悉该问题时,我注意到您使用的方法presentModalViewController:animated:似乎已被弃用,而不是presentViewController:animated:completion:。也许您应该尝试使用该方法。

为方便起见,请自己看看:

presentModalViewController:animated: reference

我会尝试整理一个快速测试程序,看看我上面说的是否真的如此。但试一试 - 也许它会有所帮助!

答案 7 :(得分:0)

Xcode有一个非常接近你正在做的模板。从结果来看,我认为你不应该尝试执行[self.navigationController presentModalViewController:vc]和[self.navigationController dismissModalViewControllerAnimated:],而只是简单地[self presentModalViewController:]和[self dismissModalViewControllerAnimated:]。

要查看模板如何为您自己执行此操作,您可以在xcode 4.3中使用新项目向导。也许它会提供一些指导:

Xcode new project wizard utility template

从该选项中选择Next,然后为您的测试项目命名,选择“Universal”,关闭自动引用计数,点击next,保存到您想要的位置。

现在,单击目标并将部署目标切换为4.3(或者如果您愿意,则为4.0)以用于测试目的,并切换到您的设备或iOS 4.3模拟器。

最后,在创建的AppDelegate.m中的applicationDidFinishLaunching:withOptions:中替换以下代码:

    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
        self.mainViewController = [[[MainViewController alloc] initWithNibName:@"MainViewController_iPhone"
                                                                        bundle:nil] autorelease];
    } else {
        self.mainViewController = [[[MainViewController alloc] initWithNibName:@"MainViewController_iPad"
                                                                        bundle:nil] autorelease];
    }
    UINavigationController* navigationController
      = [[UINavigationController alloc] initWithRootViewController:self.mainViewController];
    self.window.rootViewController = navigationController;
    [self.window makeKeyAndVisible];
    return YES;

现在,当我运行它时,它不会隐藏navigationBar。在模板中创建的MainViewController.m中,您将看到它如何呈现模态视图控制器并将其从控制器本身而不是从导航控制器中解除。为了更好地衡量,要使模板代码更像您自己,请进入MainViewController.m并删除设置模态视图控制器转换样式的行...

(当然,在iOS 5中,使用故事板,同样的事情都可以用模态segues完成...这就是我为那些我不支持5.0之前版本的应用程序所做的事情这种方式的modalViewController。)

答案 8 :(得分:0)

使用此类别MaryPopin的最佳解决方案之一 https://github.com/Backelite/MaryPopin