2013-08-29 11 views
6

Bu konuyla ilgili birkaç soru buldum ancak yanıtlar sorunumu çözmüyor.İki modlu denetleyiciyi reddetme

PresentModalViewController'ı kullanarak sunduğum iki denetleyicim var.

Ana Denetleyici tarafından çağrılan ilk denetleyiciye modalTransitionStyle ekledim. İlk kontrolör ikinci kontrolörü normal olarak (geçiş stili olmaksızın) sundu.

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

Bu benim MainVC gitmek için kullanılan kod:

[self.presentingViewController.presentingViewController dismissModalViewControllerAnimated:YES]; 

Ve bu ne oldu: sayfa açılmak vermedi

enter image description here

. Bununla karşılaşmamın sebebi nedir?

cevap

3

Bu çağrı ile, sizin iki görüş peş peşe sunmalıdır:

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

    }]; 
}]; 

bu daha iyi davranması gerekir. Ayrıca, daha sonra bu viewControler'ların her ikisini de çekmeniz gerekeceğini bilin.

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

    }]; 
}]; 
+0

Yanıtladığınız için teşekkür ederiz. Ancak ikinci görüntü denetleyicisi, yalnızca ilk denetleyicinin görünümündeki bir düğmeyi tıklattıktan sonra çağrılır. –

+0

ahh, o zaman sonundan sonra ikisini de çıkardığına emin ol. – HalR

+0

Merhaba HalR, cevabınız bana yardımcı oldu. Yaptığım şey, tamamlama bloğu içinde bir bildirim göndermek oldu. 'code' [self.presentingViewController dismissViewControllerAnimated: NO tamamlama:^{[[NSNotificationCenter defaultCenter] postNotificationName: @" BACKTOMAIN "nesnesi: nil];}]; –

2

'İkincisini' reddetmeden 'ilk' işten çıkıyorsunuz gibi görünüyor.

Apple'ın bunu yapmasının önerilen yolu, temsilci ile yapılır.

mainVC'yi "ilk" delege yapmaya çalışın, böylece ilk önce kendisini reddetmek için mainVC yöntemini çağırabilirsiniz. Bunu 'ilk' bir 'delege' özelliği ilan ederek ve 'ilk' başladığında anaVC'ye ayarlayarak bunu yapın. daha sonra, ilk olarak "ilkDelegate" protokolünü tanımlayın. Bu, 'dismissFirst' gibi bir işlevi içerir ve sonra mainVC'de ilk.h'yi içe aktarır. Şimdi ilk önce 'ilk' görevini reddetmek için anaVC'de dismissFirst uygulamasını yapın ve şimdi ilk olarak görüntülenmesini istediğiniz her şeyi yapın.

gasp ... şimdi 'ilk' bir 'ikinci' temsilcisini de aynı şekilde yapın ve 'dismissSecond' işlevini mainVC'nin 'dismissFirst' işlevini çağırın ve her şey tümüyle doğru olacaktır.

Bunun çok karmaşık olduğunu biliyorum, ancak temsilci çekirdek bir iOS konseptidir ve bu, nerede kullanıldığıyla ilgili mükemmel bir örnektir.

Bunun nasıl çalıştığı hakkında iyi bir açıklama. http://chrisrisner.com/31-Days-of-iOS--Day-6%E2%80%93The-Delegate-Pattern

Ayrıca, hiç bitmeyen bir araştırmanızda, bir Apple mühendisinin Obj-C olarak da bilinen zihninin iç işlemlerini anlamanız için size iyi şanslar dilerim.

+1

Bir zincirde birbirini tanıtan birden çok denetleyiciyi reddetmek çok güzel. Zincirin içindeki ilkini reddederseniz, diğerlerinin hepsi reddedilir. Bu özel durumda, sorun, bunu saran sunum stillerinden kaynaklanır. – rdelmar

+0

Sorunu HalR ve bazı değişikliklerle verilen kodu kullanarak çözdüm. Diğer denetleyiciyi kapatmak için bir bildirim ekledim. –

6

Yaptığım deneylerde, kısmi bir kıvrımdan sonra standart bir sunuya sahip olamayacağınızı (dikey olarak kapatabileceğinizi) ve animasyonun HAYIR olarak ayarlı olarak yapılmadıkça bunları aynı anda reddettiğinizi göreceksiniz.firstVC kontrol olmadığını test ettikten sonra, animasyon ile viewDidAppear tekrar kapatmak içinde

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

Ardından:

bu olsa düzeltmek için bir yol (bu kod secondVC olan) bir animasyon ile secondVC bertaraf etmek sunulmakta olan:

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

yukarıdaki kod geri ilk kontrolörün görünümüne almak için uygundur, ancak bukle uncurls önce firstVC görüşüne görürsünüz. Bunu görmek istemezseniz, bunu düzeltmek için bulabildiğim tek yol, ikinci bir VC görüntüsünü oluşturmaktı, bunu ikinci bir VC'nin işten çıkarılmasından önce (bir görüntü görünümünde) ilk VC'ye bir alt görünüm olarak eklemekti. Yani, bunu yapmak için, secondVC kod (eğer bunun işe yaraması için secondVC içine QuartzCore bağlantısı olan ve ithal etmek zorunda olduğunu unutmayın) yerine bu olmalıdır:

-(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" nesnesini kullanarak sorunu başarıyla çözdüm: nil];}]; Sonra alıcı kontrolörde [self dismissModalViewControllerAnimated: YES] ekledim; Cevap için de teşekkürler :) –

0

Ben de aynı şüphe vardı. Başka bir yolla çözümledim -

Adım 1: Genel bir sınıfta (singleton) bir değişken bayrağı tanımlayabilirsiniz.

@property (nonatomic) int flag; 

Adım 2: varsayalım bu değeri ayarlamak için ikinci bir görünüm denetleyicisi işten sırasında, second view controller ve first view controller kapatmak ve geri Main view controller dönmek gerekir varsayalım.

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

Aşama 3: Sende - (void)viewWillAppear:(BOOL)animated yöntem first view controller bu yöntemi ayarlayabilirsiniz - Ben cevap bu kullanarak çözüldü umut

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

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

. Eğer hala şüphelerin varsa, sorabilirsiniz. Şerefe :)

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

Mutlu Bir unwind segue kullanmak gerekir. Görüntülemek istediğiniz denetleyicide "boş" bir IBAction oluşturun.

@IBAction func unwindToController(segue: UIStoryboardSegue) { 

} 

Ardından, storyboard'unuza gidin ve gelmek istediğiniz denetleyiciyi seçin. Seçilen bir denetleyicinin üstündeki simgelerde, en soldaki dosya merkezinde, merkezde küçük bir beyaz kare olan sarı bir daire olmalıdır. Ctrl-Gevşetmek istediğiniz görünüm denetleyicisinin "Çıkış" etiketine sürükleyin. Çıkış, kontrolör ağaçlarının dibinde veya Storyboard üzerinde, beyaz kare w/sağ oka sahip en kırmızı kare görüntü olarak bulunabilir. Bu bir diyaloğu açacak, oluşturduğunuz unwindToController eylemini seçin.

FROM denetleyicinizde yeni bir "Açma segmesini Çıkış" görünecektir. Çift tıklayın ve ona bir tanımlayıcı verin, ör. unwindIdentifier

Artık denetleyicisi İTİBAREN, kullanımda, iki kontrolör dinlenmek istediğinizde: orta kontrolörü atlayıp animasyon kontrolöre İÇİN yalnızca gösteren ikinci birine gevşeyin olacak

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

.

0

:) Kodlama