Uyarı: -Çoklu görünüm denetleyicilerinde görünüm denetleyicilerinin sunulması önerilmez


180

Uygulamamda bir gezinti denetleyicisi kullanıyorum. Daha sonra bazı görünümlerde presentViewControlleryakınlaştırılmış bir görüntüyü göstermek için kullanıyorum . Ayrıca bir Storyboard veya uç kullanmıyorum.

Bu hatayı yalnızca iOS 7'de alıyorum. İOS 6 ve önceki sürümlerde iyi çalışır:

Ayrık görünüm denetleyicilerinde görünüm denetleyicilerinin sunulması önerilmez


Henüz çözemedim. Ama benim app i window.rootviewcontroller için herhangi bir viewcontroller atamıyorum. pencereye görünüm ekliyorum. Belki de bu benim nedenim. ama emin değilim ...
Gagan Joshi

@GaganJoshi Yukarıda bahsettiğiniz neden nedeni olmayabilir. Ben de aynı sorunla karşı karşıyayım. Ve projemizde window.rootviewcontroller'a bir görünüm denetleyicisi ataıyorum.
Rajesh

1
Diğer yorumlar doğru rootViewController ve pencere bağlantısı hakkında bir şey ile ilgili düşünüyorum. Bunu tam olarak anlayamadım, ancak denetleyiciyi navigasyon denetleyicisi veya çocuklarından biri yerine doğrudan rootViewController'da sunarak sorunu çözebildim.
Rich Waters

Yanıtlar:


207

Bir push navigasyonunda uyarı almamak için doğrudan şunları kullanabilirsiniz:

[self.view.window.rootViewController presentViewController:viewController animated:YES completion:nil];

Ve daha sonra modsal görünüm denetleyicinizde, her şey bittiğinde şunları arayabilirsiniz:

[self dismissViewControllerAnimated:YES completion:nil];


Bu satır kodu ile görüntü seçici sunuyorum "[self.view.window.rootViewController presentViewController: viewController animated: YES completion: nil];" Ancak bu satırla göz alıcı görünümü kapatamıyor "[self dismissViewControllerAnimated: YES completion: nil];" Dismisscontroller için herhangi bir alternatif seçenek
kb920

@keyurbhalodiya Çalışması için modalView'dan dismissViewController yöntemini çağırmanız gerekir. Bu nedenle, [viewA.window.rootViewController presentViewController: viewB] ile bir viewA'dan viewB adlı bir görünüm görüntülerseniz, viewB'de, örneğin, [self dismissViewControllerAnimated] öğesini çağıran özel bir eylemle ilişkili bir düğme eklemeniz gerekir. Daha net mi?
cdescours

11
İOS 8'de viewcontroller sunmuyor
Rajesh Maurya

1
iOS 8 için: [self.view.window.rootViewController.navigationController
Fede Cugliandolo

31
kullanarak self.navigationControllerbenim için yaptı.
Brandon Zacharie

62

Bu uyarının nedeni, tam boyut görünümü olmayan küçük bir görünüm üzerinde bir görünüm denetleyicisi sunuyordum. Aşağıda projemin görüntüsü verilmiştir. yukarıdaki dört seçeneğe tıklayın. Kullanıcı farklı childviewcontroller görünümüne gidin. (TabViewcontroller gibi çalışır). Ancak childviewcontroller küçük boyutlu bir görünüm içerir. Yani childviewcontroller'dan bir görünüm sunarsak, bu uyarıyı verir.

ana ayrıntı görünümü

Bundan kaçınmak için childviewcontroller'ın ebeveynine bir görünüm sunabilirsiniz

  [self.parentViewController presentViewController:viewController animated:YES completion:nil];

1
[self.view.window.rootViewController.navigationController pushViewController: YOUR_VIEW_CONTROLER animated: YES];
Fede Cugliandolo

1
"tam boyutlu görünüm olmayan küçük bir görünüm üzerinde bir görünüm denetleyicisi sunuyordu." ... KESİNLİKLE. İyi iş.
Fattie

61

Bekleyin viewDidAppear():

Bu hata, görünüm gerçekten görünmeden önce görünüm denetleyicisini sunmaya çalışıyorsanız da ortaya çıkabilir; örneğin, görünümü içinde viewWillAppear()veya öncesinde sunma . viewDidAppear()İçinden veya içinden başka bir görüş sunmaya çalışın .


9
Başka bir deyişle, herhangi bir görünüm denetleyicisi sunmayın viewDidLoad(), insanlar! Bu hatayı birçok kez yaptım ...
T Blank

Teşekkürler bu yardımcı oldu. Ben sonunda bir iletişim kutusu görüntülemeye çalıştı viewDidLoad kodu vardı.
ArdenDev

Animasyonlarla test etmediğim birim / entegrasyon testlerini çalıştırırken bu hatayı alıyorum.
mixtly87

21

Benim durumumda, alt sampleViewControllergörünüm olarak eklenen bir görünüm var, daha sonra sampleViewController(burada selfbunun yerine bir UIViewControllerörnek) görünümünden bir popover sunmaya çalışır :

[self.view addSubview:sampleViewController.view];

Doğru yol aşağıda olmalıdır:

// make sure the vc has been added as a child view controller as well
[self addChildViewController:sampleViewController];
[self.view addSubview:sampleViewController.view];
[sampleViewController didMoveToParentViewController:self];

Btw, bu aynı zamanda bir tableview hücresi oluşturan bir popover sunmak için çalışır, sadece tableview denetleyicisinin de çocuk view denetleyicisi olarak eklendiğinden emin olmanız gerekir.


Ayrıca didMoveToParentViewController'ı arayın. Pleaes check out Ekle ve Kaldır ChildViewController: gist.github.com/tomohisa/2897676
Jakehao

@jianzong son adımı yapmaya gerek olmadığını hatırlıyorum. Herhangi bir şekilde, onu eklememe izin verin, öneri için teşekkürler. :)
Kjuly

Evet, son adım olmadan çalışacaktır. Bunun amacı, bir şey yapmak için bazı yöntemler çağıracak şekilde parentViewController'ı bilgilendirmektir. :)
Jakehao

2
benim için çalışıyor, başka bir denetleyicide bir denetleyici görünümünü kullanarak im - (Konteyner görünümü programlı olarak), ben eklemedim [self addChildViewController:sampleViewController];, şimdi bunu ekledim, teşekkür ederim
anjnkmr

16

Sorun, uygun bir görünüm denetleyicisi hiyerarşisine sahip olmamanız olduğunu düşünüyorum. Uygulamanın rootviewcontroller'ını ayarlayın ve yeni görünüm denetleyicilerini iterek veya sunarak yeni görünümler gösterin. Her görünüm denetleyicisinin görüşlerini yönetmesine izin verin. Yalnızca tabbarviewcontroller gibi kapsayıcı görünümü denetleyicileri, kendi görünümlerine başka görünüm denetleyicileri görünümleri eklemelidir. Görüntü denetleyicilerini doğru kullanma hakkında daha fazla bilgi için görüntü denetleyicileri programlama kılavuzunu okuyun. https://developer.apple.com/library/content/featuredarticles/ViewControllerPGforiPhoneOS/


14

Hızlı 3

Buna tökezleyen herkes için, işte hızlı cevap.

self.parent?.present(viewController, animated: true, completion: nil)

9

Neredeyse aynı sorunum var. Bunun nedeni, bir diğerinde "bazı" denetleyiciyi sunmaya çalışmam ve animasyon tamamlandıktan sonra sunulan denetleyiciyi root olarak ayarlamamdı. Bu işlemden sonra, sunulan diğer tüm denetleyiciler beni şu uyarıya götürür : " Ayrık görüntü denetleyicilerinde görünüm denetleyicilerinin sunulması önerilmez. " Ve ben bu uyarıyı sadece başlangıçta herhangi bir sunum yapmadan "bazı" kontrolörünü root olarak çözüyorum.

kaldırıldı:

[[self rootController] presentViewController:controller animated:YES completion:^{

       [self window].rootViewController = controller;

       [[self window] makeKeyAndVisible];}];

Herhangi bir sunum yapmadan root yapın:

 [[self window] setRootViewController:controller];

1
Bu benim sorunumdu. Bir UIModalTransitionStyleCrossDissolve ile sunmak ve sonra rootViewController yapmaya çalışıyordu. Bundan sonra, diğer tüm sunumlar verilen uyarı mesajı ile başarısız oldu. Sadece animasyon olmadan rootViewcontroller olarak ayarlamak hile yaptı. Teşekkürler!
Bernardo Oliveira

7

Bunun çözümlerinden biri, childviewcontroller'ınız olması durumunda, viewcontroller'ı üst tarafından verilen

[self.parentViewController presentViewController:viewController animated:YES completion:nil];

Ve işten çıkarma için aynı işten çıkarma denetleyicisini kullanın.

[self dismissViewControllerAnimated:YES completion:nil];

Bu benim için mükemmel bir çözüm.


7

[self.navigationController presentViewController:xxx animated:YES completion:nil]İOS 8'de kullanın .


5

Bu kodu deneyin

UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:<your ViewController object>];

[self.view.window.rootViewController presentViewController:navigationController animated:YES completion:nil];

4

Tabanlı bir uygulama TabBarControllerolup olmadığını sunmayı deneyin TabBarController.

[self.tabBarController presentViewController:viewController animated:YES completion:nil];

Sebep olabilir selfçocuğu TabBarControllerve sizden sunmaya çalışıyorsunuz ChildViewController.


4

Evet, başka bir görünümde olan bir Uyarı denetleyicisi görüntülerken aynı uyarı iletisiyle de karşılaştım. Daha sonra, aşağıdaki gibi ana görünüm denetleyicisinden uyarı denetleyicisini sunarak bunu önledim:

[self.parentViewController presentViewController:alertController animated:YES completion:nil];

3

yeni denetleyiciyi üst görünüm denetleyicisinin alt öğesi olarak gösterecek görünüm denetleyicisini eklemeniz gerekir.

AnaViewController'ınız olduğunu varsayalım, o zaman controllerA adlı yeni bir denetleyici eklersiniz ve daha sonra controllerA'dan controllerB adlı yeni bir denetleyici sunmak istiyorsunuz

böyle bir şey yazmak zorundasınız:

[self addChildViewController:controllerA]; //self is yourMainViewController
[self.view addsubView:controllerA.view]; 

ve denetleyiciA içinde yeni denetleyiciyi uyarı vermeden sunabilirsiniz

[self presentViewController:controllerB animated:YES completion:nil]; //self is controllerA

3

Swift 4.1 ve Xcode 9.4.1'de

Çözüm şudur

DispatchQueue.main.async(execute: {
    self.present(alert, animated: true)
})

Eğer böyle yazıyorsam aynı hatayı alıyorum

let alert = UIAlertController(title: "title", message: "message", preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "OK", style: .default, handler: { action in
    })
alert.addAction(defaultAction)

present(alert, animated: true, completion: nil) 

Aynı hatayı alıyorum

Presenting view controllers on detached view controllers is discouraged <MyAppName.ViewController: 0x7fa95560Z070>.

Komple çözüm:

let alert = UIAlertController(title: "title", message: "message", preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "OK", style: .default, handler: { action in
     })
alert.addAction(defaultAction)
//Made Changes here    
DispatchQueue.main.async(execute: {
    self.present(alert, animated: true)
})

DispatchQueue aracılığıyla çalıştırmak benim için işe yaradı. Ben ilk görünüm denetleyicisi (yeni kullanıcıları yönlendirmek için bir ilk başlatma giriş ekranı) viewDidLoad denilen kalıcı bir görünüm denetleyicisi için performSegue yapıyorum. İyi yükleniyordu, ama uyarıyı üretiyordu. DispatchQueue zaman uyumsuz çağrısında performSegue çağrısının sarılması uyarıyı ortadan kaldırır. Teşekkürler!
Grant Neufeld

1

Başlamak için bir kök görünüm denetleyiciniz olduğundan emin olun. Ayarlayabilirsiniz didFinishLaunchingWithOptions.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    
    [window setRootViewController:viewController];
}

1

Bu uyarının birçok nedeni var. Benim bir modally sunulacak bir ViewController diğerine bağlı bir segue var çünkü. Ancak, sunuyorum ViewController dinamik bir PageViewController tarafından oluşturulur. Bu yüzden Storyboard'da ayrılmıştır. Uygulamam bu nedenle çökmeyecek; ama uyarıyı susturmak istiyorum.


1

Özel bir Gezinti Çubuğu var ve ben bir AlertViewController aracılığıyla çağırıyordu bu iş parçacığında ulaştı.

Ana görünüm denetleyicime çocuk olarak eklemek zorunda kaldım. O zaman herhangi bir uyarı olmadan onu sunmak diyebilirim.

Eklemelisin Zoomed Image View ControllerAna ViewController alt öğesi olarak .

(Örneğin)

[self addChildViewController:ZoomedImageViewController];

Sonra ZoomedImageViewController'ınızı arayabilirsiniz

[self presentViewController:ZoomedImageViewController];

1

Birçok cevap doğrudur.

  • SunuluyorViewController parentViewController olup olmadığını kontrol edin.
  • Hayırsa, eklenecek bir yere ekleyin
  • Aksi takdirde, parentViewController öğesinde, her viewController öğesinde üst öğe

İş arkadaşım BViewController'a bir AViewController eklediğinde bu sorun bana oldu. Her nasılsa, AViewController'ın görüşünü BViewController'ın görüşüne ekliyor.

Add bViewController.addChild (aViewController) ile düzeltildi


1
Teşekkür ederim! Hero.shared.transition tamamlama bloğuma addChild ekleyerek sorunumu tamamen çözdüm.
landnbloc

0

UIViewController türünün uyarısını veya benzer bir şeyi göstermek isteyip istemediğinize bağlıdır.

Bu kod örneğini kullanabilirsiniz:

UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"Alert" message:@"Example" preferredStyle:UIAlertControllerStyleAlert];

UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleDefault handler:nil];

[alert addAction:cancelAction];


[[[[[UIApplication sharedApplication] delegate] window] rootViewController] presentViewController:alert animated:true completion:nil];

Kodunuzla birlikte, çalışmaz ve bu günlüğü verirAttempt to present <UIAlertController: 0x7fc01a1eb600> on <ViewController: 0x7fc019821e00> whose view is not in the window hierarchy!
Naveed Abbas
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.