2013-08-29 82 views
6

我發現了幾個關於這個問題,但答案不能解決我的問題。關閉兩個模式視圖控制器

我有兩個控制器,我使用presentModalViewController呈現。

我將modalTransitionStyle添加到由主控制器調用的第一個控制器。第一個控制器正常顯示第二個控制器(沒有過渡樣式)。

FirstVC *first = [[FirstVC alloc] initWithNibName:@"FirstVC" bundle:nil]; 
first.modalTransitionStyle = UIModalTransitionStylePartialCurl; 
[self presentModalViewController:first animated:YES]; 

SecondVC *second = [[SecondVC alloc] initWithNibName:@"SecondVC" bundle:nil]; 
[self presentModalViewController:second animated:YES]; 

這是我經常去的MainVC代碼:

[self.presentingViewController.presentingViewController dismissModalViewControllerAnimated:YES]; 

這是發生了什麼:

enter image description here

頁沒有舒展。我遇到這個的原因是什麼?

回答

3

你應該出示兩種觀點一前一後,這個電話:

[self presentViewController:firstViewController animated:YES completion:^(
    [self presentViewController:secondViewController animated:YES completion:^(

    }]; 
}]; 

這應該表現得更加出色。另外,知道你必須在這之後關閉這兩個viewControllers。

[self.presentingViewController.presentingViewController dismissViewControllerAnimated:YES completion:^{ 
    [self.presentingViewController.presentingViewController dismissViewControllerAnimated:YES completion:^{ 

    }]; 
}]; 
+0

感謝您的回答。但是第二個視圖控制器僅在點擊第一個控制器視圖內的按鈕後纔會被調用。 –

+0

啊,那麼只要確保你在結束後把它們都拉下來。 – HalR

+0

嗨HalR,你的回答幫了我。我所做的就是在完成塊內發佈通知。 'code' [self.presentingViewController dismissViewControllerAnimated:NO completion:^ {[[NSNotificationCenter defaultCenter] postNotificationName:@「BACKTOMAIN」object:nil];}]; –

2

看起來好像你是在駁回'第一'的情況下駁回'第二'。

蘋果推薦的做法是委派。

嘗試使mainVC成爲'first'的代理,以便首先調用mainVC的方法來解除自身。通過聲明'first'的'delegate'屬性並在'first'被實例化時將其設置爲mainVC來做到這一點。然後在first.h中定義一個'firstDelegate'協議,其中包含一些像'dismissFirst'這樣的函數,然後在mainVC中導入first.h。現在在mainVC中實施dismissFirst以實際解除「第一」,然後做任何你想要的東西,現在首先完成顯示。

喘氣...現在用同樣的方法讓'第一'代表'second',然後讓'dismissSecond'函數調用mainVC的'dismissFirst'函數,這一切都將與世界一致。

我知道這很複雜,但代表團是一個核心的iOS概念,這是使用它的典型例子。

下面是對此工作原理的一個很好的解釋。 http://chrisrisner.com/31-Days-of-iOS--Day-6%E2%80%93The-Delegate-Pattern

我希望你能在你永無止境的追求中體驗蘋果工程師心靈的內在詭計,也就是Obj-C。

+1

解僱在鏈中呈現彼此的多個控制器是很好的。如果你解僱了第一個鏈,那麼所有其他人都會被解僱。在這種特定情況下,問題是由演示文稿造成的。 – rdelmar

+0

我通過使用HalR給出的代碼和一些修改解決了這個問題。我添加了一個通知來解散其他控制器。 –

6

在我的實驗中,似乎在部分捲曲之後不能有標準演示文稿(垂直覆蓋),並且同時忽略它們,除非您將動畫設置爲否解除。

解決這一問題,雖然一個方法是駁回secondVC與沒有動畫(這個碼是在secondVC):

-(IBAction)dismissSelf:(id)sender { 
    [self dismissViewControllerAnimated:NO completion:nil]; 
} 

然後在firstVC在viewDidAppear再次駁回動畫,測試控制器不後被提出:

-(void)viewDidAppear:(BOOL)animated { 
    if (![self isBeingPresented]) { 
     [self dismissViewControllerAnimated:YES completion:nil]; 
    } 
} 

雖然上面的代碼工作,回到最初的控制器的視圖,你會看到firstVC的看法出現捲曲舒展了之前。如果你不想看到這一點,那麼我唯一能找到解決辦法的方法是創建一個secondVC的圖像,在解除secondVC之前將它添加爲firstVC的子視圖(在圖像視圖中)。因此,要做到這一點,在secondVC代碼應該是這樣的,而不是(請注意,你必須將它鏈接到QuartzCore和導入secondVC這個工作):

-(void)viewDidAppear:(BOOL)animated { 
    [super viewDidAppear:animated]; 
    UIImage *img = [self imageWithView:self.view]; 
    FirstViewController *first = (FirstViewController *)self.presentingViewController; 
    UIImageView *iv = [[UIImageView alloc] initWithFrame:first.view.bounds]; 
    iv.image = img; 
    [first.view addSubview:iv]; 
} 


-(IBAction)dismissSelf:(id)sender { 
    [self dismissViewControllerAnimated:NO completion:nil]; 
} 


- (UIImage *)imageWithView:(UIView *)view { 
    UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, [[UIScreen mainScreen] scale]); 
    [view.layer renderInContext:UIGraphicsGetCurrentContext()]; 
    UIImage * img = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    return img; 
} 
+0

我已經使用[self.presentingViewController dismissViewControllerAnimated:NO completion:^ {[[NSNotificationCenter defaultCenter] postNotificationName:@「BACKTOMAIN」object:nil];}];然後在接收控制器中,我添加了[self dismissModalViewControllerAnimated:YES];謝謝你的回答:) –

0

我也有同樣的疑問。我用其他方式解決 -

第1步:在全局類(單例)中,您可以定義一個變量標誌。

@property (nonatomic) int flag; 

步驟2:假設你需要解僱second view controllerfirst view controller和返回到Main view controller,而駁回可以設置這個值的第二視圖控制器爲假設1

[[Global sharedObject] setFlag:1]; 
[self.navigationController popViewControllerAnimated:YES]; 

步驟3:在您- (void)viewWillAppear:(BOOL)animated的方法first view controller你可以把這個方法 -

if([[Global sharedObject] flag] == 1) 
{ 
    [[Global sharedObject] setFlag:0]; 
    [self performSelector:@selector(back) withObject:nil afterDelay:0.5]; 
} 

- (void) back 
{ 
[self.navigationController popViewControllerAnimated:YES]; 
} 

我希望你的答案就是採用這種解決。如果你仍然有疑問,你可以問。乾杯:)

0
- (UIViewController*)topViewController 
{ 
    UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController; 
    while (topController.presentedViewController) { 
     topController = topController.presentedViewController; 
    } 
    return topController; 
} 


- (void)dismissAllModalController{ 

    __block UIViewController *topController = [self topViewController]; 

    while (topController.presentingViewController) { 
     [topController dismissViewControllerAnimated:NO completion:^{ 

     }]; 
     topController = [self topViewController]; 
    } 
} 

編碼快樂:)

0

你需要使用一個unwind segue。在視圖控制器中創建一個「空」IBAction,您想要繼續。

@IBAction func unwindToController(segue: UIStoryboardSegue) { 

} 

然後去你的故事板,並選擇你想要來自的控制器。在選定控制器頂部的圖標中,最左邊的應該是一個黃色的圓圈,中間有一個小的白色正方形,即文件所有者。按Ctrl-拖動到您想要展開的視圖控制器的「退出」標籤。可以在控制器樹的底部附近找到「出口」,或者在故事板上找到「出口」,作爲最右邊的紅色正方形圖像,其中帶有白色方框的w /向右箭頭。這將彈出一個對話框,選擇您創建的unwindToController操作。

您的FROM控制器中會出現一個新的「退出退出」。雙擊它並給它一個標識符,例如unwindIdentifier

現在,當你想放鬆2個控制器,在從控制器,使用方法:

self.performSegueWithIdentifier("unwindIdentifier", sender:nil) 

這將跳過中間控制器和放鬆到第二個,只顯示在動畫控制。