dismissModalViewControllerAnimated kullanımdan kaldırıldı


103

İOS uygulamamı iPhone 5 için 4 inçlik ekranda çalışacak şekilde güncellemek için XCode 4.5'e yeni yükselttim, ancak dismissModalViewControllerAnimated:' is deprecatedsatırda şunu söyleyen bir yapı hatası alıyorum :

[self dismissModalViewControllerAnimated:NO];

Aşağıdaki gibi bir tamamlama işleyicisiyle (ancak NULL olarak ayarlanmış) önerilen aşırı yüklemeye güncellemeyi denedim:

[self dismissModalViewControllerAnimated:NO completion:NULL];

Ama sonra bu satır iki hata veriyor:

warning: 'TabBarController' may not respond to '-presentModalViewController:animated:completion:'
Instance method '-presentModalViewController:animated:completion:' not found (return type defaults to 'id')

Teşekkürler!

Yanıtlar:


307

Yeni yöntem şudur:

[self dismissViewControllerAnimated:NO completion:nil];

Modal kelimesi kaldırılmıştır; Sunum API çağrısı için olduğu gibi:

[self presentViewController:vc animated:NO completion:nil];

Sebepler 2012 WWDC Oturum 236 - iOS Videoda Görüntü Denetleyicilerinin Evrimi'nde tartışıldı . Esasen, bu API tarafından sunulan görünüm denetleyicileri artık her zaman kalıcı değildir ve bir tamamlama işleyicisi ekledikleri için yeniden adlandırmak için iyi bir zamandı.

Marc'ın yorumuna yanıt olarak:

4.3 ve üzeri tüm cihazları desteklemenin en iyi yolu nedir? Yeni yöntem iOS4'te çalışmaz, ancak eski yöntem iOS6'da kullanımdan kaldırılmıştır.

Bunun neredeyse ayrı bir soru olduğunun farkındayım, ancak herkesin her 3 yılda bir tüm cihazlarını yükseltecek parası olmadığı için birçoğumuzun bazı eski (5.0 öncesi) cihazları var. Yine de bunu söylemek bana acı verse de 5.0'ın altında hedeflemeye değip değmeyeceğini düşünmelisiniz. 5.0'ın altında bulunmayan birçok yeni ve havalı API vardır. Ve Apple sürekli olarak onları hedef almayı zorlaştırıyor; armv6 desteği, örneğin Xcode 4.5'ten çıkarılır.

5.0'ın altında hedeflemek için (tamamlama bloğu sıfır olduğu sürece) kullanışlı respondsToSelector: yöntemini kullanın .

if ([self respondsToSelector:@selector(presentViewController:animated:completion:)]){
    [self presentViewController:test animated:YES completion:nil];
} else {
    [self presentModalViewController:test animated:YES];
}

Marc'ın başka bir yorumuna cevaben:

Bu, başvurumdaki çok fazla If ifadesi olabilir! ... Bu kodu içeren bir kategori oluşturmayı düşünüyordum, UIViewControler'da bir kategori oluşturmak reddedilmeme neden olur mu?

ve Full Decent'ten biri:

... bunun bir derleyici uyarısı göstermemesini manuel olarak sağlamanın bir yolu var mı?

İlk olarak, hayır, UIViewControllerkendi başına bir kategori oluşturmak , uygulamanızı reddedmez; bu kategori yöntemi özel API'leri veya benzer bir şeyi çağırmadıkça.

Kategori yöntemi, bu tür bir kod için son derece iyi bir yerdir. Ayrıca, kullanımdan kaldırılan API'ye yalnızca bir çağrı olacağından, yalnızca bir derleyici uyarısı olacaktır.

Full Decent'in yorumunu (soruyu) ele almak için, evet, derleyici uyarılarını manuel olarak bastırabilirsiniz. İşte tam da bu konuda SO ile ilgili bir yanıtın bağlantısı . Bir kategori yöntemi aynı zamanda bir derleyici uyarısını bastırmak için harika bir yerdir çünkü uyarıyı yalnızca tek bir yerde bastırırsınız. Kesinlikle derleyiciyi susturmak istemezsiniz.

Bunun için basit bir kategori yöntemi yazacak olsaydım, bunun gibi bir şey olabilirdi:

@implementation UIViewController (NJ_ModalPresentation)
-(void)nj_presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion{
    NSAssert(completion == nil, @"You called %@ with a non-nil completion. Don't do that!",NSStringFromSelector(_cmd));
    if ([self respondsToSelector:@selector(presentViewController:animated:completion:)]){
        [self presentViewController:viewControllerToPresent animated:flag completion:completion];
    } else {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
        [self presentModalViewController:viewControllerToPresent animated:flag];
#pragma clang diagnostic pop
    }
}
@end

2
4.3 ve üzeri tüm cihazları desteklemenin en iyi yolu nedir? Yeni yöntem iOS4'te çalışmaz, ancak eski yöntem iOS6'da kullanımdan kaldırılmıştır. Rock ve sert bir yer mi?
Marc

@Marc Endişenizi gidermek için cevabıma ekledim.
NJones

Teşekkürler. Bu, başvurumda epeyce If ifadesi olabilir! Sanırım aynı yaklaşım 'modalViewController' özelliğini kullanırken işe yarayabilir. Bu kodu içeren bir kategori oluşturmayı düşünüyordum, UIViewControler'da bir kategori oluşturmak reddedilmeme neden olur mu?
Marc

Kod için if ([self respondsToSelector:@selector(presentViewController:animated:completion:)]){ [self presentViewController:test animated:YES completion:nil]; } else { [self presentModalViewController:test animated:YES]; }, bunun bir derleyici uyarısı göstermemesini manuel olarak sağlamanın bir yolu var mı?
William Entriken

@FullDecent Evet yapabilirsiniz. Cevabımı bununla ilgili bazı bilgilerle düzenledim.
NJones

6

Artık iOS 6 ve üzeri sürümlerde şunları kullanabilirsiniz:

[[Picker presentingViewController] dismissViewControllerAnimated:YES completion:nil];

Onun yerine:

[[Picker parentViewControl] dismissModalViewControllerAnimated:YES];

... Ve şunları kullanabilirsiniz:

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

Onun yerine

[self presentModalViewController:picker animated:YES];    

4

[self dismissModalViewControllerAnimated:NO]; kullanımdan kaldırıldı.

[self dismissViewControllerAnimated:NO completion:nil];Bunun yerine kullanın .


4

Kullanım

[self dismissViewControllerAnimated:NO completion:nil];

3

Uyarı hala orada. Ondan kurtulmak için şöyle bir seçiciye koydum:

if ([self respondsToSelector:@selector(dismissModalViewControllerAnimated:)]) {
    [self performSelector:@selector(dismissModalViewControllerAnimated:) withObject:[NSNumber numberWithBool:YES]];
} else {
    [self dismissViewControllerAnimated:YES completion:nil];
}

Benim gibi OKB'si olan insanlara fayda sağlar;)


Kullanımdan kaldırılmış bir yöntemin respondsToSelectoryanlış döndürmesine neden olmayacağına inandığım için if ifadesini değiştirmelisiniz . Bu nedenle yeni dismissViewControllerAnimated:, muhtemelen dismissModalViewControllerAnimated:tamamen kaldırılabilecekleri gelecekteki bir güncellemeye kadar çağrılmayacaktır .
Jsdodgers

0

İşte benim gibi diğer yeni başlayanlara yardımcı oluyorsa kullandığım ilgili presentViewController sürümü:

if ([self respondsToSelector:@selector(presentModalViewController:animated:)]) {
    [self performSelector:@selector(presentModalViewController:animated:) withObject:testView afterDelay:0];
} else {
    [self presentViewController:configView animated:YES completion:nil];
}
[testView.testFrame setImage:info]; //this doesn't work for performSelector
[testView.testText setHidden:YES];

ViewController'ı 'genel' olarak kullandım ve modal Görünüm'ün ne yapmak için çağrıldığına bağlı olarak farklı görünmesini sağladım (setHidden ve setImage kullanarak). ve işler daha önce güzel çalışıyordu, ancak performSelector 'set' öğelerini görmezden geliyor, bu yüzden sonunda denediğim gibi verimli olmaya çalışırsanız kötü bir çözüm gibi görünüyor ...

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.