Denetleyici Kapsamı Görüntüleme iOS 5'te nasıl çalışır?


108

WWDC 2011 Oturum 102, Apple benzer özel görünüm denetleyicisi kapları yaratma yeteneği olduğunu View Controller İçericinin tanıttı UITabBarController, UINavigationControllerve benzeri.

Örnekleri birkaç kez izledim. Bu modelle ilişkili bir dizi yöntem var, ancak bunları tam olarak anlamak biraz zordu. Burada olduğunu düşündüğüm şeyleri yayınlayacağım ve topluluğun şüphelerimi onaylayıp onaylamayacağını göreceğim.

Senaryo 1: Üst öğe yoktan yeni bir üst öğe görünümü denetleyicisine geçme

[vc willMoveToParentViewController:self];
[self addChildViewController:vc];
[self.view addSubview:vc.view]; // or something like this.
[vc didMoveToParentViewController:self];

İlk iki satır verilen sırada mı olmalı yoksa tersine çevrilebilir mi?

Senaryo 2: Üst görünüm denetleyicisinden üst görünüm denetleyicisine geçme

[vc willMoveToParentViewController:nil];
[vc.view removeFromSuperview];
[vc removeFromParentViewController];

Aramak da gerekli [vc didMoveToParentViewController:nil]mi? 102. Oturumdaki örnekler bu senaryoda bunu yapmadı , ancak bunun bir ihmal olup olmadığını bilmiyorum.

Senaryo 3: Bir üst öğe görünümü denetleyicisinden diğerine geçiş

Bu muhtemelen aşağıdaki şekilde gerçekleşecektir, çünkü her bir üst öğe görüntüleme denetleyicisindeki mantık kapsüllenecektir.

// In the old parent
[vc willMoveToParentViewController:nil];
[vc.view removeFromSuperview];
[vc removeFromParentViewController];

// In the new parent
[vc willMoveToParentViewController:self];
[self addChildViewController:vc];
[self.view addSubview:vc.view];
[vc didMoveToParentViewController:self];

Sorular

Ana sorum şudur: Genel olarak, görünüm denetleyicisi muhafazası bu şekilde mi çalışmalı? Yukarıda verilen mekanikler doğru mu?

Aramadan willMoveToParentViewControllerönce aramak gerekli addChildViewControllermi? Bu bana mantıklı bir sıra gibi görünüyor, ama kesinlikle gerekli mi?

Aradıktan didMoveToParentViewController:nilsonra aramak gerekli removeFromParentViewControllermi?

Yanıtlar:


72

UIViewControllerDocs ne zaman ve ne zaman değil çağrısına oldukça nettir willMove/ didMoveyöntemlerle. Check out "Bir Konteyner View Controller uygulanması" belgelere.

Dokümanlar, geçersiz kılmıyorsanız addChildViewController, willMoveToParentViewController:yöntemi çağırmanıza gerek olmadığını söylüyor . Ancak didMoveToParentViewController:, geçiş tamamlandıktan sonra yöntemi çağırmanız gerekir . "Aynı şekilde, willMoveToParentViewController:yöntemi çağırmadan önce yöntemi çağırmak da konteyner görünümü denetleyicisinin sorumluluğundadır removeFromParentViewController. Yöntem, çocuk görüntüleme denetleyicisinin removeFromParentViewControlleryöntemini çağırır didMoveToParentViewController:."

Ayrıca, burada çalışılmış bir örnek ve burada örnek kod var .

İyi şanslar


17
Anlıyorum, bu yüzden addChildViewControllerdengelenmeli didMoveToParentViewControllerve willMoveToParentViewControllerdengelenmelidir removeFromParentViewController. Bu tam olarak aradığım şeydi. Belgelerde bunu nasıl kaçırdığımdan emin değilim.
Gregory Higley

Neden olmasın? Neden willMoveToParentViewController'ı çağırmak zorunda değilsiniz ama didMoveToParentViewController'ı çağırmak zorundasınız?
user4951

Çünkü doktorların söylediği bu. Apple açıkça bilmemize gerek olmadığını düşünüyor.

7
Nedeni animasyon uğruna: Kendi gezinme denetleyicinizi yarattığınızı varsayalım. Bir kayma animasyonunun başlangıcında, 'willMove' çağrılmalıdır ve animasyonun sonunda 'didMove' çağrılmalıdır. Artık animasyonun başlangıcında 'addChild' çağırdığınızda, sizin için otomatik olarak 'willMove' çağırır. Ancak animasyonun (eğer varsa) ne zaman biteceğini bilemez, bu nedenle animasyonun sonunda (veya animasyon yokken hemen) 'didMove'u manuel olarak çağırmanız gerekir.
Chris

2
Ve 'dışarı kayma' animasyonuna gelince, örneğin çocuk kaldırılırken, animasyonun başında manuel olarak 'willMove' çağrısı yapmanız gerekir, çünkü uikit aksi takdirde çocuğunuzun VC'sinin 'viewWillDisappear'ı ne zaman arayacağını bilemezdi. Ve animasyonun sonunda, removeFromParentViewController'ı çağırdığınızda, sizin için otomatik olarak 'didMove' çağrısı yapabilir.
Chris

23

Bu kısım doğru değil:

[vc willMoveToParentViewController:self];
[self addChildViewController:vc];
[self.view addSubview:vc.view]; // or something like this.
[vc didMoveToParentViewController:self];

Dokümanlara göre:

Özel kapsayıcınız addChildViewController: yöntemini çağırdığında, eklemeden önce alt öğe olarak eklenecek görünüm denetleyicisinin willMoveToParentViewController: yöntemini otomatik olarak çağırır.

Yani [vc willMoveToParentViewController:self]aramaya ihtiyacın yok . Aradığınızda otomatik olarak yapılır [self addChildViewController:vc]. İşte kod örneği yine:

[self addChildViewController:vc];
// [vc willMoveToParentViewController:self] called automatically
[self.view addSubview:vc.view]; // or something like this.
[vc didMoveToParentViewController:self];

Görünüm denetleyicilerini kaldırmak için:

RemoveFromParentViewController yöntemi, alt öğe kaldırıldıktan sonra alt görünüm denetleyicisinin didMoveToParentViewController: yöntemini otomatik olarak çağırır.

Muhtemelen bu çağrı [oldVC didMoveToParentViewController:nil].

[vc willMoveToParentViewController:nil];
[vc.view removeFromSuperview];
[vc removeFromParentViewController];
// [vc didMoveToParentViewController:nil] called automatically

Aksi takdirde, işe yarıyor gibi görünse bile, presentingViewController'ın presentViewController üzerinde ayarlanmadığı görülür.
Adrian

Dokümanlar, didMoveToParentViewController " addChildViewController: yöntemini çağırdıktan hemen sonra " çağrısı yapar, alt görünümü gerçekten ne zaman eklediğinizi belirtmez. Merak ediyorum, herkes bunu yanlış anladı. Bazı Apple Dokümanlarında bunu kontrol edebileceğimiz bir örnek var mı?
Robert

Not: do aramaya gerek willMoveToParentViewControlleröncesinde addChildViewControllertaşıdığınız öğeyi geçersiz kılınmış olan özel bir sınıf ise addChildViewController(sizin geçersiz kılma dahili olarak çağırır sürece)
bunkerdive
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.