使用模态视图作为“正常”视图
Posted
技术标签:
【中文标题】使用模态视图作为“正常”视图【英文标题】:Use modal view as "normal" view 【发布时间】:2010-09-23 15:51:08 【问题描述】:我想使用模态视图 (UIViewController
) 作为“普通”视图,可以将其推送到导航控制器堆栈上。通常,模态视图是这样呈现的:
LoginViewController *myView = [[MyViewController alloc] init];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:myView];
[self.navigationController presentModalViewController:navController animated:YES];
[myView release];
myView = nil;
[navController release];
navController = nil;
但我想做这样的事情:
[[self navigationController] pushViewController:myView animated:YES];
问题是我的模态视图有一个左右按钮。所以我必须检查视图是如何加载的,并以另一种方式呈现按钮。这背后的想法是有后退按钮。所以我可以多次使用相同的模态视图。
编辑:
@petert:
现在我按照你的例子。我的问题是我使用UINavigationBar
作为模态视图。为了得到这个UINavigationBar
,我创建了一个导航控制器。我正在使用导航栏,因为其中有我的按钮。所以检查parentViewController
是否属于UINavigationController
类型对我不起作用。我总是得到一个模态视图。这是我的做法:
// load modal view
MyViewController *myView = [[MyViewController alloc] init];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:myView];
[[self navigationController] presentModalViewController:navController animated:YES];
[navController release];
navController = nil;
[myView release];
myView = nil;
// load as normal view
MyViewController *myView = [[MyViewController alloc] init];
[[self navigationController] pushViewController:myView animated:YES];
【问题讨论】:
【参考方案1】:此 *** 中的好提示 answer。
我更喜欢使用UIViewController的属性:
@property(nonatomic, readonly) UIViewController *parentViewController
在视图控制器的子类中:
查看控制器的
parentViewController
属性的值。如果它是UINavigationController
的实例,那么您就在导航堆栈中。如果您以模态方式显示,它将是您最后一个视图控制器的实例。
所以以-viewDidLoad
为例:
- (void)viewDidLoad
if ([self.parentViewController isKindOfClass:[UINavigationController class]])
// navigation controller
self.title = @"...";
else
// modal
self.title = @"Modal";
// add cancel and done buttons now...
或者,一个非常简单的解决方案是将您的 init
方法自定义到您的 MyViewController
类,以编码您对视图控制器的意图。
将以下内容添加到MyViewController
标头:
@interface MyViewController : UIViewController
BOOL modal;
- (id)initForModal:(BOOL)isModal;
@end
现在在实现文件中:
@interface MyViewController ()
@property (nonatomic) BOOL modal;
@end
@implementation MyViewController
@synthesize modal;
- (id)initForModal:(BOOL)isModal;
if (self = [super initWithNibName:@"MyViewController" bundle:nil])
self.modal = isModal;
return self;
- (void)viewDidLoad
[super viewDidLoad];
if (self.modal)
// add cancel and done buttons …
else
// assuming we're presented from a navigation view …
现在以模态方式使用:
// load modal view
MyViewController *myView = [[MyViewController alloc] initForModal:YES];
或非模态:
// load as normal view
MyViewController *myView = [[MyViewController alloc] initForModal:NO];
我假设您是从 NIB 创建视图控制器,但一如既往地看到 View Controller Progamming Guide for ios,尤其是标题为“定义自定义视图控制器类”的部分。
【讨论】:
感谢您提供的示例代码。我认为它会很好用,但我使用UINavigationController
来展示我的模态视图。我为什么要这样做在我编辑的问题中进行了解释。也许你可以提供一个解决方案。
您的支持很棒!这个解决方案非常简单并且效果很好。现在有一些问题需要我的理解:1)为什么要在实现文件中做一个新的接口声明? 2) initForModal
中的 if
调用超级构造函数,如果成功则返回对象 (ViewController
),否则返回 nil。它是否正确?在if
语句中,如果对象不为零,则仅设置一个选项。 3)我需要这里的属性,因为变量在方法边界上方使用?
很高兴它很有帮助 - 1)它隐藏了 modal 属性,因为它不能在这个类实现之外使用; 2) 是的,绝对是 init 方法的通用 obj-c 风格; 3)我使用属性只是为了让事情变得更简单,我认为你的问题的答案是肯定的?记得给答案投票,如果有帮助,谢谢。【参考方案2】:
澄清一下:myView 不是模态的。您只需将其呈现为模态的。
如果您只是将它推入 UINavigationController 层次结构,它的行为将像“正常”的那样。
您不能将同一个视图控制器多次推送到导航堆栈上。就一次。
有关如何自定义视图,另请参阅此内容:
SO modal question
【讨论】:
好的,我将它呈现为模态视图。你有一个“真实”模式视图的例子吗?我不想同时将它推入堆栈。只有一次是什么意思?我可以把它作为普通视图放在堆栈上,但以后不能作为模态视图?以上是关于使用模态视图作为“正常”视图的主要内容,如果未能解决你的问题,请参考以下文章