簡體   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