iOS:在没有访问其父视图控制器的情况下解除和呈现ModalViewController

6

背景:我想要关闭之前展示的一个modalView,并立即以新信息展示同一个viewController

问题:在不使用显式指针指向之前展示第一个ViewController的父ViewController的情况下,我一直没有成功实现这一点。我正在尝试编写一个可以在不干扰之前viewController代码的情况下工作的类。

可能的线索:我一直在尝试以下几个方面:

1.) 尝试获取父ViewController的访问权限,但目前还不知道如何操作。

2.) 一旦获得了对父级的访问权限,我可以简单地应用以下代码:

UIViewController* toPresentViewController = [[UIViewController alloc] init];
    [self dismissViewControllerAnimated:YES completion:^{
        [parentViewControllerAccessor presentModalViewController:toPresentViewController animated:YES];
}];

在理论上,只要有访问父视图控制器的权限,这应该可以实现。我也愿意尝试其他方法达到目的。
假设您没有权限更改父视图控制器中的任何代码。
4个回答

10

你的代码看起来应该可以工作。如果你正在使用iOS 5,则有一个名为presentingViewControllerUIViewController属性。

@property(nonatomic, readonly) UIViewController *presentingViewController;

因此,您可以使用此属性获取呈现您的模态控制器的视图控制器。

注意: 在iOS 4中,parentViewController将设置为呈现控制器,因此,如果您同时支持iOS 4和5,则必须首先检查操作系统版本,以决定访问哪个属性。在iOS 5中,Apple已经修复了这个问题,parentViewController现在专门用于包含视图控制器的父级(请参见UIViewController文档中有关实现容器视图控制器的部分)。

编辑: 关于从块内访问self.presentingViewController: 当调用块时(模态视图控制器被解除后),presentingViewController属性可能设置为nil。请记住,在块内使用self.presentingViewController会给出该属性在执行块时而非创建时的值。为了防止这种情况,请执行以下操作:

UIViewController* toPresentViewController = [[UIViewController alloc] init];
UIViewController* presentingViewController = self.presentingViewController;
[self dismissViewControllerAnimated:YES completion:^
{
    [presentingViewController presentModalViewController:toPresentViewController animated:YES];
}];

这是必要的,不是因为self已经消失/被解雇了(它会被块安全地保留),而是因为它不再呈现,因此它的presentingViewController现在为nil。不需要将presentingViewController存储在其他任何地方,局部变量很好,因为它将被块保留。


如果我理解正确的话,我应该更改这段代码:[parentViewControllerAccessor presentModalViewController:toPresentViewController animated:YES];[self.presentingViewController presentModalViewController:croppedPhotoVC animated:YES];。不幸的是,这似乎并没有起作用。我是否有什么误解? - Byte
1
这可能是由于块保留对象的方式 - 它会保留self但不会保留呈现视图控制器,因此在 'self' 被解除显示之前,该属性可能已设置为nil。将 self.presentingViewController 设置为块外的局部变量,然后从块内使用该变量。 - jhabbott
这是我得出的相同结论。我可能需要创建一个静态变量来保存它,以便在self被删除时,该方法仍然可以工作。但那看起来更像是一种hack。 - Byte
你不需要将它存储在静态变量中,代码块会为你保留局部变量。我已经编辑了我的答案向你展示如何做到这一点。 - jhabbott

1

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

1
尝试以下代码:
[self dismissViewControllerAnimated:NO 
                         completion:^{
  // instantiate and initialize the new controller
  MyViewController *newViewController = [[MyViewController alloc] init];
  [[self presentingViewController] presentViewController:newViewController
                                                animated:NO
                                              completion:nil];
}];

1
您可以使用通知来完成此操作。
例如,当您想要关闭模态视图时,请从模态视图外部触发此通知:
[[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.
}

然后在您的模态视图中处理该通知:我不确定这意味着什么,我明确表示,我不能触摸呈现此视图控制器的上一个视图控制器上的代码。除非我在这里误解了什么? - Byte

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接