繁体   English   中英

如果当前视图控制器发生更改,如何关闭模式视图控制器?

[英]How can a modal view controller be dismissed if the presenting view controller is changed?

我在iPad上展示了一个模式视图控制器,该模态视图控制器在展示时更改了展示视图控制器。 例如:

  1. 当用户在表视图中选择一个单元格时,视图控制器VC将显示模式视图控制器。
  2. 用户在模态视图控制器上选择一个项目,并打开另一个VC实例代替第一个。 重要的是,替换第一个的视图控制器实例具有相同的类型。
  3. 模态视图控制器无法关闭,否则会发生EXC_BAD_ACCESS异常。

失败的解雇是可以理解的:呈现视图控制器不再可用。 基本上,我将如何从其他呈现视图控制器中删除此呈现模式视图控制器?

我已经拥有的代码是:

ViewController1.m

- (void)showModalViewController:(UIViewController *)viewController
{
    UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:viewController];
    navigationController.modalPresentationStyle = UIModalPresentationFormSheet;
    viewController.navigationItem.rightBarButton = [[UIBarButton alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(dismissModalViewController)];
    [self presentViewController:navigationController animated:YES completion:nil];
}

- (void)dismissModalViewController
{
    [self dismissViewControllerAnimated:YES completion:nil];
    [self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES];
}

感谢您的建议,但我通过使用委托解决了该问题。 呈现的视图控制器定义了一个委托,以便在发生动作时通知呈现者。

ChildViewControler.h:

@protocol ChildViewControllerDelegate <NSObject>
- (void) childView:(ChildViewController *)childView didSelectItem:(Item *)item;
@end

ChildViewController.m:

// in interface
@property (nonatomic, weak) id <ChildViewControllerDelegate> delegate;

// in implementation
- (void)closeView:(Item *)anItem
{
    [self.delegate childView:self didSelectItem:anItem];
}

ViewController1.m:

- (void)showModalViewController:(UIViewController *)viewController
{
    UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:viewController];
    navigationController.modalPresentationStyle = UIModalPresentationFormSheet;
    viewController.navigationItem.rightBarButton = [[UIBarButton alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(dismissModalViewController)];
    // Different view controller types may be passed here so check is required...
    if (viewController.class == [ChildViewController class]) {
        ((ChildViewController *)viewController).delegate = self;
    [self presentViewController:navigationController animated:YES completion:nil];
}

- (void)childView:(ChildViewController *)childView didSelectItem:(Item *)item
{
    [self dismissViewControllerAnimated:YES completion:nil];
    [self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES];
    // Perform action required with 'item'
}

你可以尝试改变

self.presentingViewController 

关闭之前,在模态视图控制器中使用(显示此视图控制器或其最远祖先的视图控制器)属性。

根据文档,presentingViewController是一个只读属性。 您无法修改它。

@property(nonatomic,readonly) UIViewController *presentingViewController NS_AVAILABLE_IOS(5_0);

这是您的问题:

 //...
        viewController.navigationItem.rightBarButton = [[UIBarButton alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(dismissModalViewController)];
    //...
- (void)dismissModalViewController
{
    [self dismissViewControllerAnimated:YES completion:nil];
    [self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES];
}

您尝试关闭演示者视图控制器(当前似乎已经切换到另一个演示者),而不是显示的模式视图控制器(在您的情况下为UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:viewController]; ),因此(如果演示者视图控制器而不是tabViewController的选项卡,或者没有存储在navigationController的堆栈中或其他位置),您必须将对其的引用存储在演示者视图控制器中以外的其他地方,该控制器将被切换并可以被释放。

我尚未测试此代码,但dismissModalViewController中可能有错误。
请在此方法上放置断点第一行是完美的,第二行可能会导致错误,可能self.tableView无法访问或self.tableView indexPathForSelectedRow可能为nil。

    - (void)dismissModalViewController
{
    [self dismissViewControllerAnimated:YES completion:nil];    
    [self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES];
}

谢谢。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM