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

发布于 2024-11-29 13:36:16 字数 2345 浏览 1 评论 0原文

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

[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];
    }
}

I have a navigation based app with a navigation bar, but there are a few instances where instead of pushing a view controller onto the stack, I need to present the view controller modally. The problem is that when I dismiss the modal view controller, everything functions as expected except that the navigation bar is hidden and the (parent view) has been resized, which is the expected behavior according to the docs. So I figured I could simply call a built-in method to unhide the navigation bar. I have already tried

[self.navigationController setNavigationBarHidden:NO];

as well as the animated version without success.

The documentation talks about this in the method

presentModalViewController: animated:

in the discussion section where it says,

On iPhone and iPod touch devices, the view of modalViewController is always presented full screen" and "Sets the modalViewController property to the specified view controller. Resizes its view and attaches it to the view hierarchy."However, the docs didn't clue me in as to how to undo this process after dismissing a modal view.

Has anyone else experienced this and found a solution?

Edit: I am having this same problem, so instead of asking my own question I am sponsoring a bounty on this one. This is my specific situation:

In my case, I am presenting an Image Picker in a Modal View Controller, over a Navigation Controller:

-(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];
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

一枫情书 2024-12-06 13:36:16

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

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

如果您的视图控制器实际上位于 UINavigationController 的堆栈上,那么这是处理模式视图控制器的呈现和解除的正确方法。如果您的 UINavigationBar 仍然隐藏,则说明发生了其他奇怪的事情,我们需要查看您的代码来确定发生了什么。

编辑

我将您的代码复制到我的应用程序中,并且 UIImagePickerController 成功呈现并关闭,并且我的 UINavigationController 的 UINavigationBar 仍然在那里。我确实相信问题出在您架构的其他地方。如果您上传带有示例项目的 zip 文件,我会看一下。

Make sure you a presenting AND dismissing the modalViewController from the UINavigationController, like so:

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

If your view controller is actually on the UINavigationController's stack then this is the correct way to handle the presentation and dismissal of the modal view controller. If your UINavigationBar is still hidden, there is something else funky going on and we would need to see your code to determine what is happening.

Edit

I copied your code into an app of mine and the UIImagePickerController successfully presented and dismissed and my UINavigationController's UINavigationBar was still there. I truly believe that the problem lays elsewhere in your architecture. If you upload a zip w/ an example project I will take a look.

梦明 2024-12-06 13:36:16

只需尝试以下代码即可工作

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

需要显示导航控制器才能在所显示的控制器上显示导航栏

Simply try following code it will work

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

One need to present the navigation controller in order to have navigation bar on the presented controller

冷月断魂刀 2024-12-06 13:36:16

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

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

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

I think I've seen this behavior when presenting a view controller on the wrong VC. Are you calling presentModalViewController on the navigation controller or the individual VC?

Try calling it from the navigationController if you aren't already.

[self.navigationController presentModalViewController:myVC animated:YES];
鯉魚旗 2024-12-06 13:36:16

如果将控制器呈现为模型,视图控制器将显示在总视图中。

如果您想通过模型视图访问导航控制器属性,您需要创建另一个导航控制器引用,并且它会像以前一样继续。

这可能对你有用。

If you present a controller as model, View controller will appear to total view.

If you want to access the navigation controller properties over the model view, You need to create another navigation controller reference and it continues as previous.

This may be useful for you.

若水般的淡然安静女子 2024-12-06 13:36:16

看看这个。这是 UIViewController Class Reference 下的 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

Check this out. This is Apple's Documentation under UIViewController Class Reference:

It clearly mentions that modal view always presents in full screen mode, so it is obvious that navigation bar will be hidden. So put the seperate navigation bar on modal view to navigate back.

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.

Hope this helps you understand that hiding the whole view along with navigation controller is default behaviour for modal view so try putting a seperate navigation bar in modal view to navigate.

You can check it further on this link

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

始终不够爱げ你 2024-12-06 13:36:16
AddContactVC *addController =[self.storyboard instantiateViewControllerWithIdentifier:@"AddContactVC"];
UINavigationController *navigationController = [[UINavigationController alloc]initWithRootViewController:addController];
[self presentViewController:navigationController animated:YES completion: nil];

为我工作显示导航栏

AddContactVC *addController =[self.storyboard instantiateViewControllerWithIdentifier:@"AddContactVC"];
UINavigationController *navigationController = [[UINavigationController alloc]initWithRootViewController:addController];
[self presentViewController:navigationController animated:YES completion: nil];

working for me shows navigation bar

夏有森光若流苏 2024-12-06 13:36:16

Emphatic 和 Devin –

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

为了方便起见,请自行查看:

presentModalViewController:animated: 参考

我会尝试编写一个快速测试程序来看看是否我上面说的其实都是真的。但尝试一下——也许会有帮助!

Emphatic and Devin –

As I started reading through the Apple docs to get familiar with the problem, I noticed that the method you're using, presentModalViewController:animated:, appears to be deprecated in favor of presentViewController:animated:completion:. Perhaps you should try to use that method instead.

For your convenience, take a look for yourself:

presentModalViewController:animated: reference

I'll try to put together a quick test program to see whether what I've said above is actually true. But give it a shot – maybe it'll help!

錯遇了你 2024-12-06 13:36:16

Xcode 有一个模板,它的功能与您正在做的非常接近。从结果来看,我认为您不应该尝试执行 [self.navigationControllerpresentModalViewController:vc] 和 [self.navigationControllerdismissModalViewControllerAnimated:] ,而应该简单地执行 [selfpresentModalViewController:] 和 [selfdismissModalViewControllerAnimated:] 。

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

Xcode 新项目向导实用程序模板

从该选择中,选择“下一步”,然后为您的测试项目提供名称,选择“通用”,关闭自动引用计数,点击下一步,保存在你想要的地方。

现在,单击目标并将部署目标切换到 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;

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

(当然,在 iOS 5 中,使用故事板,同样的事情都可以通过模态转场来完成...这就是我为不支持 5.0 之前版本的应用程序执行此操作的方式,这些应用程序以这种方式呈现 modalViewController。)

Xcode has a template that does pretty close to what you're doing. from the results, i don't think you should be attempting to perform [self.navigationController presentModalViewController:vc] and [self.navigationController dismissModalViewControllerAnimated:] , but rather simply [self presentModalViewController:] and [self dismissModalViewControllerAnimated:] .

to see how the template does this for yourself, you can use the new project wizard in xcode 4.3 . perhaps it will provide some guidance:

Xcode new project wizard utility template

from that choice, choose Next, then give your test project a name, choose "Universal", turn off automatic reference counting, hit next, save where you want it.

now, click on the target and switch the deployment target to 4.3 (or 4.0 if you prefer) for your testing purposes, and switch to your device or the iOS 4.3 simulator .

finally, substitute the following code in applicationDidFinishLaunching:withOptions: in the created AppDelegate.m:

    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;

now, when i run this, it doesn't hide the navigationBar. and in the created MainViewController.m from the template, you'll see how it presents the modal view controller and dismisses it from the controller itself and not from the navigation controller. for good measure, to make the template code more like your own, go into MainViewController.m and delete the line that sets the modal view controller transition style ...

(of course, in iOS 5, with storyboards, the same thing can all be accomplished with modal segues ... which is how i've done this for apps that i'm not supporting for pre-5.0 that present a modalViewController in this fashion.)

江南月 2024-12-06 13:36:16

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

One of the best solution it to use this Category MaryPopin
https://github.com/Backelite/MaryPopin

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文