如果更改呈现视图控制器,如何关闭模态视图控制器?

时间:2014-02-17 10:15:08

标签: ios objective-c uiviewcontroller

我在iPad上呈现一个模态视图控制器,它可以在呈现时更改呈现视图控制器。例如:

  1. 当用户在表格视图中选择单元格时,视图控制器VC会显示模态视图控制器。
  2. 用户选择模态视图控制器上的项目,打开另一个VC实例代替第一个。重要的是,替换第一个的视图控制器实例属于同一类型。
  3. 无法解除模态视图控制器或发生EXC_BAD_ACCESS异常。
  4. 失败的解雇是可以理解的:呈现视图控制器不再可用。基本上,我如何从不同的呈现视图控制器中忽略这个呈现的模态视图控制器?

    我已经拥有的代码是:

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

5 个答案:

答案 0 :(得分:1)

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

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'
}

答案 1 :(得分:0)

您可以尝试更改

self.presentingViewController 

(呈现此视图控制器或其最远祖先的视图控制器。) 解雇之前模态View Controller中的属性。

答案 2 :(得分:0)

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

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

答案 3 :(得分: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的堆栈中或其他地方),你必须在其他地方存储对它的引用,而不是在presenter视图控制器中,它将被切换并可以被释放。

答案 4 :(得分:0)

我没有测试过这段代码,但是dismissModalViewController可能有错误 请把这个方法的断点放在第一行完美可能你的第二行可能会导致错误,可能是self.tableView无法访问或者是self.tableView indexPathForSelectedRow可能是nil。

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

感谢。