2010-07-12 34 views
20

A'nın root, B'nin ilk modal görüntüleme denetleyicisi ve C'nin üçüncü modal vc olduğu üç görünüm denetleyicisiyle yığın oluşturunuz. Aynı anda C'den A'ya gitmek istiyorum. this solution to dismiss'u denedim. çalışmasını doğru bir şekilde yapmıyor. En son kontrolörün görevden alındığı zaman, ilk gösterilmeden önce ikinci görüntü denetleyicisini gösterecektir. Aradığım şey, ikinci görüşü fark etmeden güzel bir animasyonda üçüncü vc'den birinciye geçmenin bir yoludur. Bu konuda herhangi bir yardım büyük ölçüde uygundur.Birden çok model görünümü denetleyicisini aynı anda reddetme?

+0

(tabii ki temsilci yöntemlerine veya diğer eşit olarak heyecan verici tasarım desenleri ile tüm bu kısmının yerini alabilecek, önemli parçası viewControllerB seviyesinde görevden mani olmaktır) Bir modal görüntü denetleyicisinin daha fazlasını reddetmek için daha genel bir yol [burada] (https://stackoverflow.com/a/44583711/1151916) – Ramis

cevap

20

Sadece bir kez dismissModalViewControllerAnimated: numaralı telefonu aradığınızdan emin olun.

Yığınlanan her modal görünüm denetleyicisini reddetmeyi istemek, her ikisinin de animasyon yapmasına neden olacağını buldum.

Şu ana kadar: A =modal> B =modal> C

Yalnızca [myViewControllerB dismissModalViewControllerAnimated:YES] kullanırsanız, normal olarak B. C görevden ve olmayacaktır [myViewControllerA dismissModalViewControllerAnimated:YES]

çağırmalıdır nedeniyle (o B işine son vereceğini kullanmak (unstacked) Yanıtlayan zincir mesajı A) 'ya kadar köpürüyor. B'yi tanımladığınız yığılmış senaryoda bir üst görünüm denetleyicisi bulunur ve bu, bir modal görünüm denetleyicisi olmanın önceliğini alır.

+7

Şu an kullanıyorum: [[[self parentViewController] parentViewController] dismissModalViewControllerAnimated: YES]; Kök görünüm denetleyicisini kullanır. Bununla birlikte, hala ikinci bir breif ikinci vc gösterir. – sebrock

+0

Oh ve Yardımcı Program şablonunu kullandığımı ve ikinci vc'nin yandan görüntü aldığını söylemeliyim. Üçüncüsü, flipsitten başlatılan modal vc'dir. – sebrock

+1

NOT: iOS5'te bu, çalışan bir çözüm için "presentViewController" olarak değiştirildi. Http://game4mob.com/index.php/jawbreaker/66-dismiss-modal-view-in-ios5-sdk –

-5

Kullanmak istediğiniz, popToRootViewControllerAnimated:. Tüm müdahale edenleri göstermeden sizi kök denetleyicisine götürür.

+1

A, 'UINavigationController' – ohhorob

+1

Oh evet'in köküdür. Sadece uyandım, o yüzden ben yakalamadım. – lucius

0

Bu modalViewControllers öğesini rootViewController sayfanızdan çıkarabilirsiniz. Kabul cevabı benim için çalışma yaptı

UIViewController *viewController = yourRootViewController; 

    NSMutableArray *array = [NSMutableArray array]; 
    while (viewController.modalViewController) { 
     [array addObject:viewController]; 
     viewController = viewController.modalViewController; 
    } 

    for (int i = 0; i < array.count; i++) { 
     UIViewController *viewController = array[array.count-1-i]; 
     [viewController dismissModalViewControllerAnimated:NO]; 
    } 
3

rağmen, şimdi modası geçmiş ve en üstteki modal hemen yok olur ve animasyon arka modalview olurdu garip görünümlü animasyon bırakılabilir. Bunu önlemek için pek çok şey denedim ve güzel görünmesi için bir hack kullanmam gerekti. Not: (sadece iOS8 + test, ama iOS7 + çalışmalıdır)

Temelde, viewControllerA rootview olarak viewControllerB ile UINavigationController oluşturur ve modally sunar.

// ViewControllerA.m 
- (void)presentViewB { 
    ViewControllerB *viewControllerB = [[ViewControllerB alloc] init]; 
    UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:viewControllerB]; 

    navigationController.modalPresentationStyle = UIModalPresentationFormSheet; 
    [self presentViewController:navigationController animated:YES completion:nil]; 
} 

Şimdi viewControllerB biz viewControllerC aynı şekilde sunacakları, ama biz onu sunmak sonra, biz viewControllerB 'ın navigasyon kontrolörü görünümü tabakasının üzerinde viewControllerC bir anlık koymak için gidiyoruz. Ardından, işten çıkarma sırasında viewControllerC kaybolduğunda, değişikliği görmeyiz ve animasyon güzel görünecektir.

//ViewControllerB.m 
- (void)presentViewC { 
    ViewControllerC *viewControllerC = [[ViewControllerC alloc] init]; 

    // Custom presenter method to handle setting up dismiss and snapshotting 
    // I use this in a menu that can present many VC's so I centralized this part. 
    [self presentViewControllerForModalDismissal:viewControllerC]; 
} 

Aşağıda, görünümü sunmak ve işten çıkarmayı işlemek için kullanılan yardımcı işlevlerim bulunmaktadır. Dikkat edilmesi gereken tek şey, otomatik düzen kısıtlamaları eklemek için Purelayout kullanıyorum. Şimdi biz sadece biz ViewControllerC bir özellik olarak tanımlanan dismissBlock sağlamak için ihtiyaç https://github.com/PureLayout/PureLayout

#pragma mark - Modal Presentation Helper functions 
- (void)presentViewControllerForModalDismissal:(UIViewController*)viewControllerToPresent { 
    UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:viewControllerToPresent]; 
    navigationController.modalPresentationStyle = UIModalPresentationFormSheet; 

    // Ensure that anything we are trying to present with this method has a dismissBlock since I don't want to force everything to inherit from some base class. 
    NSAssert([viewControllerToPresent respondsToSelector:NSSelectorFromString(@"dismissBlock")], @"ViewControllers presented through this function must have a dismissBlock property of type (void)(^)()"); 
    [viewControllerToPresent setValue:[self getDismissalBlock] forKey:@"dismissBlock"]; 

    [self presentViewController:navigationController animated:YES completion:^{ 
     // We want the presented view and this modal menu to dismiss simultaneous. The animation looks weird and immediately becomes the menu again when dismissing. 
     // So we are snapshotting the presented view and adding it as a subview so you won't see the menu again when dismissing. 
     UIView *snapshot = [navigationController.view snapshotViewAfterScreenUpdates:NO]; 
     [self.navigationController.view addSubview:snapshot]; 
     [snapshot autoPinEdgesToSuperviewEdges]; 
    }]; 
} 

- (void(^)()) getDismissalBlock { 
    __weak __typeof(self) weakSelf = self; 
    void(^dismissBlock)() = ^{ 
     __typeof(self) blockSafeSelf = weakSelf; 
     [blockSafeSelf.navigationController.presentingViewController dismissViewControllerAnimated:YES completion:nil]; 
    }; 

    return dismissBlock; 
} 

de Purelayout manuel olarak eklemek veya almak için bu değiştirebilirsiniz.h bu yardımcı olur

// ViewControllerC.h 
@interface ViewControllerC : UIViewController 
@property (nonatomic, copy) void (^dismissBlock)(void); 
@end 

//ViewControllerC.m 
// Make an method to handle dismissal that is called by button press or whatever logic makes sense. 
- (void)closeButtonPressed { 
    if (_dismissBlock) {// If the dismissblock property was set, let the block handle dismissing 
     _dismissBlock(); 
     return; 
    } 

    // Leaving this here simply allows the viewController to be presented modally as the base as well or allow the presenter to handle it with a block. 
    [self dismissViewControllerAnimated:YES completion:nil]; 
} 

Hope, mutlu programlama :)

+0

(Bu faydası ile karşılaştırıldığında) –

+1

Bu, ama tam anlamıyla iyi ve iyi görünüyor iyi bir çalışma çözümü yoktur. Apple'ın bununla başa çıkmak için iyi bir yolu olmadığı konusunda hüsrana uğramıştım. Umarım bu sonbaharda yeni sürümle. – johnrechd

+0

Kesinlikle doğru. Başka bir yolla gittim ve birbiri ardına viewControllers'ı reddettim (bu sorun için bir çözüm değil, ama çalışıyor ve çirkin değil) –

İlgili konular