iOS:在不访问其父 ViewController 的情况下关闭和呈现 ModalViewController
Posted
技术标签:
【中文标题】iOS:在不访问其父 ViewController 的情况下关闭和呈现 ModalViewController【英文标题】:iOS: Dismissing and Presenting ModalViewController without access to its Parent ViewController 【发布时间】:2012-06-11 20:29:38 【问题描述】:背景:我想关闭我之前展示的 modalView,并立即展示我刚刚用新信息关闭的 viewController
。
问题:如果没有显式指针指向以模态方式呈现第一个 ViewController
的父 ViewController
,我在这方面做得并不好。我正在尝试编写这个类,它不会与以前的viewController
的代码混淆。
可能的线索:我一直在尝试几件事:
1.) 尝试访问父级 ViewController
,此时我不知道该怎么做。
2.) 一旦获得对父级的访问权限,我可以简单地应用以下代码:
UIViewController* toPresentViewController = [[UIViewController alloc] init];
[self dismissViewControllerAnimated:YES completion:^
[parentViewControllerAccessor presentModalViewController:toPresentViewController animated:YES];
];
理论上这应该可以访问父级viewController
。我对其他方法持开放态度。
假设:您无权更改父 ViewController
中的任何代码。
【问题讨论】:
【参考方案1】:您的代码看起来应该可以工作。如果您使用的是 ios 5,则有一个名为 presentingViewController
的 UIViewController
属性。
@property(nonatomic, readonly) UIViewController *presentingViewController;
因此,您可以使用此属性来获取呈现您的模态控制器的视图控制器。
注意:在 iOS 4 中,parentViewController
将设置为呈现控制器,因此如果您同时支持 iOS 4 和 5,则必须先检查操作系统版本以决定要使用哪个属性使用权。在 iOS 5 中,Apple 已修复此问题,以便 parentViewController
现在专门用于包含的视图控制器的父级(请参阅UIViewController
文档中的实现容器视图控制器部分)。 p>
编辑:关于从块内访问self.presentingViewController
:当块被调用时(模式视图控制器被解除后)presentingViewController
属性可能被设置为零。请记住,块内的self.presentingViewController
在块执行时给出属性值,而不是在创建块时。为了防止这种情况发生,请执行以下操作:
UIViewController* toPresentViewController = [[UIViewController alloc] init];
UIViewController* presentingViewController = self.presentingViewController;
[self dismissViewControllerAnimated:YES completion:^
[presentingViewController presentModalViewController:toPresentViewController animated:YES];
];
这是必要的,不是因为self
已消失/解除(它被块安全地保留),而是因为它不再存在,因此它的presentingViewController
现在为零。没有必要将presentingViewController
存储在其他任何地方,局部变量很好,因为它将被块保留。
【讨论】:
如果我理解正确的话,我应该把这个代码:[parentViewControllerAccessor presentModalViewController:toPresentViewController animated:YES];
改为[self.presentingViewController presentModalViewController:croppedPhotoVC animated:YES];
。可悲的是,这似乎不起作用。我是不是理解有误?
这可能是由于块如何保留对象 - 它会保留 self 而不是呈现视图控制器,所以当 'self' 被解除时,此属性可能会设置为 nil。将 self.presentingViewController 设置为块外的局部变量,然后在块内使用该变量。
这与我得出的结论相同。我可能必须创建一个静态变量来保存它,这样当self
被删除时,该方法仍然有效。但这看起来更像是一种黑客行为。
您不需要将其存储在静态中,该块将为您保留一个局部变量。我已经编辑了我的答案,向您展示如何做到这一点。【参考方案2】:
您可以使用通知来完成此操作。
例如,当您希望将其关闭时,从模式视图外部触发此通知:
[[NSNotificationCenter defaultCenter] postNotificationName:@"dismissModalView"
object:nil
userInfo:nil];
然后在模态视图中处理该通知:
- (void)viewDidLoad
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(dismissMe:)
name:@"dismissModalView"
object:nil];
- (void)dismissMe:(NSNotification)notification
// dismiss it here.
【讨论】:
“然后在你的模态视图中处理该通知:”我不确定这是什么意思,我明确说过,我无法触摸呈现此视图控制器的前一个视图控制器上的代码。除非,我在这里误会了什么?【参考方案3】:ios5的解决方案:
-(void)didDismissModalView:(id)sender
// Dismiss the modal view controller
int sold=0;
if(sold==0)
//Cash_sold.delegate = self;
// Cash_sold.user_amount.text=[NSString stringWithFormat:@"%d",somme];
Cash_sold = [[CashSoldview alloc] initWithNibName:@"CashSoldview" bundle:nil];
CGRect fram1 = CGRectMake(200,20,400,400);
Cash_sold.view.superview.frame = fram1;
Cash_sold.view.frame=fram1;
Cash_sold.modalTransitionStyle= UIModalTransitionStyleCoverVertical;
Cash_sold.modalPresentationStyle=UIModalPresentationFormSheet;
UIViewController* presentingViewController = self.parentViewController;
[self dismissViewControllerAnimated:YES completion:^
[presentingViewController presentModalViewController:Cash_sold animated:YES];
];
【讨论】:
【参考方案4】:试试下面的代码:
[self dismissViewControllerAnimated:NO
completion:^
// instantiate and initialize the new controller
MyViewController *newViewController = [[MyViewController alloc] init];
[[self presentingViewController] presentViewController:newViewController
animated:NO
completion:nil];
];
【讨论】:
以上是关于iOS:在不访问其父 ViewController 的情况下关闭和呈现 ModalViewController的主要内容,如果未能解决你的问题,请参考以下文章
在不创建 IBOutlets 的情况下访问 UIelements
如何在不使用其父级的情况下设置 SimpleXmlElement 的文本值?