【问题标题】:iOS: Dismissing and Presenting ModalViewController without access to its Parent ViewControlleriOS:在不访问其父 ViewController 的情况下关闭和呈现 ModalViewController
【发布时间】: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 中的任何代码。

【问题讨论】:

    标签: iphone ios ipad modalviewcontroller presentmodalviewcontroller


    【解决方案1】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-02
        • 2014-03-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多