SORU
16 ŞUBAT 2013, CUMARTESİ


kalıcı görüntü ve kapatmak için nasıl denetleyicileri Görüntüleyin

Ve birden çok görünümü denetleyicileri gösteren kayıtsız olan sorunu çözmek için nasıl son bir haftadır kafamı yıkıyorum. Örnek bir proje oluşturulur ve doğrudan proje kodu yapıştırma var. Onların karşılık gelen 3 görünümü denetleyicileri var .xib dosyaları. , VC1 ve VC2 MainViewController. Ana görünüm kumandada iki düğme var.

- (IBAction)VC1Pressed:(UIButton *)sender
{
    VC1 *vc1 = [[VC1 alloc] initWithNibName:@"VC1" bundle:nil];
    [vc1 setModalTransitionStyle:UIModalTransitionStyleFlipHorizontal];
    [self presentViewController:vc1 animated:YES completion:nil];
}

Bu hiçbir sorunları ile VC1 açar. Aynı zamanda VC1, açık bir düğme var VC1 VC2 kapatmak.

- (IBAction)buttonPressedFromVC1:(UIButton *)sender
{
    VC2 *vc2 = [[VC2 alloc] initWithNibName:@"VC2" bundle:nil];
    [vc2 setModalTransitionStyle:UIModalTransitionStyleFlipHorizontal];
    [self presentViewController:vc2 animated:YES completion:nil];
    [self dismissViewControllerAnimated:YES completion:nil];
} // This shows a warning: Attempt to dismiss from view controller <VC1: 0x715e460> while a presentation or dismiss is in progress!


- (IBAction)buttonPressedFromVC2:(UIButton *)sender
{
    [self dismissViewControllerAnimated:YES completion:nil];
} // This is going back to VC1. 

Aynı zamanda VC1 iyi bellek kaldırılmış olması gerekirken ana görünüm denetleyicisi dönmek istiyorum. VC1 sadece ben ana kumanda üzerinde VC1 düğmesine tıkladığınızda göstermelidir.

Ana görünüm denetleyicisinde diğer düğme de atlayarak doğrudan VC1 VC2 görüntülemek için gerekir ve bir düğmeye VC2 üzerine tıklandığında ana denetleyicisi için geri gelmeli. Uzun kod, döngüler ya da herhangi bir zamanlayıcılar çalışıyor. Sadece çıplak kemik denetleyicileri görüntülemek için çağırır.

Yardım lütfen.

CEVAP
16 ŞUBAT 2013, CUMARTESİ


Bu satır:

    [self dismissViewControllerAnimated:YES completion:nil];

kendisi için bir mesaj değil, aslında zararlı VC bir mesaj, kayıtsız yapmamı gönderiyor. Bir VC şimdiki zaman, zararlı VC ve sunulan arasında bir ilişki oluşturun. Zararlı ise zararlı VC (sunulan VC mesajı tekrar görevden gönderemiyorum...) yok. Gerçekten bunu dikkate almıyorsunuz gibi kafası karışmış durumda app ayrılıyor. Cevabımı buraya bakın: Dismissing a Presented View Controller bu yöntem, daha açık bir dille yazılmış tavsiye ederim ki:

    [self.presentingViewController dismissViewControllerAnimated:YES completion:nil];

Senin durumunda, bu kontrol tüm MainViewController yapılır emin olmanız gerekir. Doğru mesaj MainViewController geri MainViewController görevden VC1 ve VC2 mevcut ise bundan sonra ViewController1, göndermek için bir temsilci kullanmalısınız.

VC2VC1 bir protokol ekleyin .yukarıda h dosyası @arabirimi:

@protocol ViewController1Protocol <NSObject>

    - (void)dismissAndPresentVC2;

 @end

ve aynı dosya içinde aşağı @arayüzü bölümüne bir özellik temsilci işaretçi tutmak için ilan:

@property (nonatomic,weak) id <ViewController1Protocol> delegate;

Bu VC1 .m dosyasını kapatmak için düğmeye yöntemi temsilci yöntemini çağırmalısınız

    - (IBAction)buttonPressedFromVC1:(UIButton *)sender {
        [self.delegate dissmissAndPresentVC2]
        }

Şimdi MainViewController, VC1 oluştururken VC1 temsilci olarak ayarlayın:

- (IBAction)present1:(id)sender {
        ViewController1* vc = [[ViewController1 alloc] initWithNibName:@"ViewController1" bundle:nil];
    vc.delegate = self;
    [self present:vc];
}

ve temsilci yöntemi uygulayın:

- (void)dismissAndPresent2
{
    [self dismissViewControllerAnimated:NO completion:
     ^{
         [self present2:nil];
     }];
}

present2: VC2Pressed: düğme İBAction yöntemi olarak aynı yöntemi olabilir. Tamamlanma blok VC1 VC2 tam olarak atlamamış kadar sunulan emin olmak için denir unutmayın.

Şimdi VC1 -^ dan hareket ediyor . VCMain->Hareketli için muhtemelen geçişler sadece birini istiyorum, böylece VC2.

güncelleme

Yorumlarınızı karmaşıklığı görünüşte basit bir şey elde etmek için gerekli şaşırdığını ifade. Sizi temin ederim, Bu heyet desen merkezi için çok Objective-C ve Kakao, ve bu örnekte olduğu hakkında en basit alabilirsiniz, bunu gerçekten yapmalısın çaba için rahat olsun.

Apple'ınGörünüm Denetleyicisi Programlama Kılavuzuthis to say.

Sunulan bir Görünüm Denetleyicisi kayıtsız

Zaman sunulan görünümü denetleyicisi kapatmak için geldiğinde, tercih edilen yaklaşım sunmak görünüm denetleyicisi kapatmak izin vermektir. Mümkün olduğunda, diğer bir deyişle, görünüm denetleyicisi sunulan aynı görünüm denetleyicisi aynı zamanda işten çıkarma sorumluluğunu almalıdır. Sunulan görünümü denetleyicisi reddedilmesi gerekir zararlı görünüm denetleyicisi bildirmek için çeşitli teknikler vardır, ancak, tercih edilen yöntem heyet. Daha fazla bilgi için, “Temsilci Başka Kontrolörleri ile İletişim kurmak için Kullanıyor.

Eğer gerçekten düşünmek istediğini elde etmek, ve nasıl olacak bu konuda, olur fark bu mesaj MainViewController için tüm işi tek mantıklı yol verilirse, bu senin için iyi olmaz kullanın bir NavigationController. Eğeryapınbir NavController, etkisi eğer değilse, açıkça, iş yapmak için navController. hatta delege kullanın Olması gerekirbazıne merkezi bir tutar o nesne VC navigasyon oluyor, ve sana ihtiyacım varbazıne yaparsan yap, iletişim yöntemi.

Uygulama Apple'ın tavsiyem biraz aşırı... normal durumlarda, senin için bir özel temsilci ve Yöntem, buna emin olabilirsin [self presentingViewController] dismissViewControllerAnimated: bu gibi durumlarda senin istediğin senin kayıtsız gerek diğer etkileri uzak nesneleri kendine bakım.

Burada bir şeyhayaltüm temsilci bir zorluk olmadan çalışır

- (IBAction)dismiss:(id)sender {
    [[self presentingViewController] dismissViewControllerAnimated:YES 
                                                        completion:^{
        [self.presentingViewController performSelector:@selector(presentVC2:) 
                                            withObject:nil];
    }];

}

Zararlı denetleyicisi bizi işten geldikten sonra, presentingViewController bir yöntem VC2 çağırmak için çağrıda tamamlanması bir blok var. Hiçbir temsilci gerekli. (Blokların büyük bir satış noktası bu şartlar altında temsilciler ihtiyacını azaltarak). Ancak bu durumda bazı şeyleri engelliyor

  • VC1 değilsinbiliyorumbu mainVC yöntemi present2 - zor-hata ayıklama hata veya çökme ile sona erebilir uygular. Delegeler, bu önlemek için yardımcı olur.
  • VC1 görevden sonra, gerçekten tamamlanma blok etrafında çalıştırmak için değil... yoksa değil mi? Kendi kendine yapar.presentingViewController artık bir anlamı? (Ben de öyle) bilmiyorsun... bir temsilci ile, bu belirsizlik yok.
  • Bu yöntemi çalıştırmak için çalıştığınızda, sadece herhangi bir uyarı veya hata ile kilitleniyor.

Bu yüzden lütfen... heyet öğrenmek için zaman ayırın!

update2

Yorum olarak da iş yapmak için VC2 düğme işleyicisi kapatmak içinde bu kullanarak başardın:

 [self.view.window.rootViewController dismissViewControllerAnimated:YES completion:nil]; 

Bu kesinlikle çok daha kolaydır, ama bir takım konularda size bırakır.

Sıkı kavrama
Sabit kablolama viewController yapınızı birlikte. Eğer mainViewController önce yeni bir viewController yerleştirin, örneğin, gerekli davranışların sonu (önceki gidin). VC1 de var alma VC2. Bu nedenle OOP/MVC hedefleri tatili arası bağımlılıkları, oldukça çok var.

Delegeler, ne de VC1 VC2 kullanarak mainVC hakkında hiçbir şey bilmek ya da biz her şeyi gevşek çiftli ve modüler devam et antecedants.

Bellek
VC1 uzağa gitmiş değil, hala iki işaretçiler tutun:

  • mainVC presentedViewController malıdır
  • VC2 presentingViewController özelliği

VC2 bu yaparak, ve sadece de bunu test edebilirsiniz

     [self dismissViewControllerAnimated:YES completion:nil]; 

Hala çalışıyor, hala VC1 geri alır.

Bir bellek sızıntısı gibi geliyor bana.

Bu ipucunu burada alıyorsanız uyarı:

[self presentViewController:vc2 animated:YES completion:nil];
[self dismissViewControllerAnimated:YES completion:nil];
 // Attempt to dismiss from view controller <VC1: 0x715e460>
 // while a presentation or dismiss is in progress!

Mantık sunmaktan VC görevden alma girişimi olarak ayırırhangiVC2 verilen VC. İkinci mesaj gerçekten idam almaz - ama belki de bazı şeyler oldu, ama hala kurtuldum düşündüğünüz bir nesne iki işaretçiler ile bırakılır. (edit - bu kontrol ettim ve her iki nesnenin geri mainVC geldiğinde de gider mi o kadar da kötü değil)

Bunu söylemenin uzun değil bir yol lütfen, delegeler kullanın. Eğer yardımı olacaksa, desenin başka bir kısa bir açıklama yaptı:
Is passing a controller in a construtor always a bad practice?

güncelleme 3
Eğer gerçekten delegeler önlemek istiyorsanız, en iyi yol bu olabilir:

VC1

  [self presentViewController:VC2
                   animated:YES
                 completion:nil];

Amayokher şeyi kapatmak... biz tespit olarak, zaten olmaz.

VC2

[self.presentingViewController.presentingViewController 
    dismissViewControllerAnimated:YES
                       completion:nil];

Biz (biliyorum) olarak VC1, MainVC üzerinden ulaşmak için geri biz görevden almadık. MainVC VC1 reddetti. Gitti çünkü VC1, VC2 onunla birlikte gider sundu, MainVC tekrar temiz bir durumda.

VC1 MainVC -^) geldi olduğunu bilmek VC2 ve VC2 ihtiyaçları hakkında bilmeniz gereken hala çok birleşiyorsa,. VC1, ama onun en iyi açık heyetin bir bit olmadan olacak.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • campos9896

    campos9896

    24 Mart 2012
  • MatheusDosGames

    MatheusDosGa

    28 Aralık 2011
  • Theodore Leaf

    Theodore Lea

    29 AĞUSTOS 2006