İOS 6'da UIViewController'ı Dikey yönlendirmeye zorlama


85

As ShouldAutorotateToInterfaceOrientationiOS 6 kullanımdan kaldırılmış ve bunun için belirli bir görünüm zorlamak için kullanılır portre yalnızca iOS 6'da bunu yapmanın doğru yolu nedir? Bu, uygulamamın yalnızca bir alanı içindir, diğer tüm görünümler dönebilir.

Yanıtlar:


117

Tüm gezinme denetleyicilerimizin üstten görünüm denetleyicisine saygı göstermesini istiyorsanız, bir grup sınıf adını gözden geçirip değiştirmek zorunda kalmamak için bir kategori kullanabilirsiniz.

@implementation UINavigationController (Rotation_IOS6)

-(BOOL)shouldAutorotate
{
    return [[self.viewControllers lastObject] shouldAutorotate];
}

-(NSUInteger)supportedInterfaceOrientations
{
    return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}

@end

Yorumlardan birkaçının işaret ettiği gibi, bu, soruna hızlı bir çözümdür. Daha iyi bir çözüm, UINavigationController alt sınıfıdır ve bu yöntemleri oraya koyar. Bir alt sınıf da 6 ve 7'yi desteklemeye yardımcı olur.


3
Bunun işe yaradığını teyit edebilirim. Ayrıca isterseniz "[self.viewControllers lastObject]" öğesini "self.topViewController" ile değiştirebilirsiniz.
Wayne Liu

3
Bu UINavigationController kategorisinden daha UITabBarController kullanıyorsanız yardımcı olmaz. Bunun yerine UITabBarController'da kategori yapmalısınız ...
Borut Tomazin

46
Bu çözümle ilgili sorun, manzarada olan denetleyiciyi açtığınızda çalışmaması ve yeni üst denetleyicinizin yalnızca portreyi (veya tam tersini) desteklemesi, bu geri aramalar bu durumda çağrılmıyor ve henüz nasıl yapılacağını bulamadım. yeni üst denetleyiciyi doğru yönlendirmeye zorlayın. Herhangi bir fikir?
Lope

4
UINavigationController'ı alt sınıflandırdım ve window.rootController olarak ayarladım. 3 yöntemi de uyguladım, cihazın dönüşünü değiştirdiğinizde harika çalışıyor, sorun şu ki bu yöntemler (ve döndürmeyle ilgili hiçbir şey) görüntüleme denetleyicisini açtığınızda çağrılıyor
Lope

4
Yatay görünüm denetleyicisinden itme veya pop yapıyorsam, bu UIViewController kuvveti Yatay olarak değişir. Ancak portreye döndürürsem, o zaman iyi çalışıyor ve asla manzaraya dönüşmeyecek. Manzaradan itme veya patlatma sırasında tek sorun. Lütfen yardım edin
Tarık

63

İOS6 için en iyi yol, Ray Wenderlich ekibi tarafından "iOS6 Tarafından Öğreticiler" bölümünde belirtilmiştir - http://www.raywenderlich.com/ ve UINavigationControllerçoğu durumda alt sınıflamadan daha iyidir .

UINavigationControllerİlk görünüm denetleyicisi olarak bir set içeren bir storyboard ile iOS6 kullanıyorum .

//AppDelegate.m - bu yöntem maalesef iOS6 öncesi kullanılamıyor

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
NSUInteger orientations = UIInterfaceOrientationMaskAllButUpsideDown;

if(self.window.rootViewController){
    UIViewController *presentedViewController = [[(UINavigationController *)self.window.rootViewController viewControllers] lastObject];
    orientations = [presentedViewController supportedInterfaceOrientations];
}

return orientations;
}

//MyViewController.m - her biri için desteklemek istediğiniz yönü döndürür UIViewController

- (NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskPortrait;
}

1
Bu, iOS 6 için en iyi çözümdür
Homam,

2
@Phil, iOS 6 için gayet iyi çalışıyor. Ancak bazı durumlarda, örneğin manzaradan portreye geçerseniz, o zaman çalışmaz. Neden olduğu hakkında bir fikriniz var mı?
Kirti Nikam

1
Çok kullanışlı bir çözüm. Benim için en iyisi.
oscar castellon

1
İOS 7 beta 6'da çalışmak. Benim durumumda manzaradan portreye geçerken çalışıyor.
Martin Berger

İOS 6'dayım ama bu çalışmıyor. "UIViewController * presentViewController" satırında kesilir.
Marcel Marino

39

Bu cevap, OP'nin gönderisinin yorumlarında sorulan sorularla ilgilidir:

Bir görünümü belirli bir yönde görünmeye zorlamak için aşağıdakileri viewWillAppear'a koyun:

UIApplication* application = [UIApplication sharedApplication];
if (application.statusBarOrientation != UIInterfaceOrientationPortrait)
{
    UIViewController *c = [[UIViewController alloc]init];
    [self presentModalViewController:c animated:NO];
    [self dismissModalViewControllerAnimated:NO];
}

Bu biraz hile, ancak bu UIViewController, önceki kontrol cihazı yatay olsa bile, onu portre olarak sunulmaya zorluyor

İOS7 için GÜNCELLEME

Yukarıdaki yöntemler artık kullanımdan kaldırılmıştır, bu nedenle iOS 7 için aşağıdakileri kullanın:

UIApplication* application = [UIApplication sharedApplication];
if (application.statusBarOrientation != UIInterfaceOrientationPortrait)
{
     UIViewController *c = [[UIViewController alloc]init];
     [c.view setBackgroundColor:[UIColor redColor]];
     [self.navigationController presentViewController:c animated:NO completion:^{
            [self.navigationController dismissViewControllerAnimated:YES completion:^{
            }];
     }];
}

İlginç bir şekilde, yazı yazılırken, ya şu an ya da reddedilme animasyonlu olmalıdır. İkisi de değilse, beyaz bir ekran alacaksınız. Bunun neden işe yaradığını bilmiyorum, ama işe yarıyor! Görsel efekt, hangisinin canlandırıldığına bağlı olarak farklılık gösterir.


Teşekkürler, birkaç dakikalık boş zaman bulduğumda bir deneyeceğim
Lope 13

@RohanAgarwal reklamı yapıldığı gibi çalışıyor, burada kullanıyorum. Ancak, kabul edilen yanıt kodunun da uygulanmış olması gerekir, yoksa işe yaramaz.
Dennis Munsie

2
Bunun aynı anda doğru döndürme animasyonuyla nasıl çalıştırılacağını bilen var mı? Animasyon olmadan portreden manzaraya geçtiğini görmek biraz sarsıcı. İşe yarıyor, sadece biraz daha iyi çalışmasını umarak.
Dennis Munsie

@Craig Watkinson Film şeridinde çalışmıyor. and presentModalViewController and dismissModalViewControllerAnimated, eğer presentVirecontroller'ı kullanırsam, çalışmaz. Lütfen bana yardım et
Kalpesh

1
İos8 için dismissViewControllerAnimated sadece çöküyor. [NWSAppDelegate sharedInstance] .window.rootViewController = nil; [NWSAppDelegate sharedInstance] .window.rootViewController = previousRootController iyi çalışıyor.
Alexey

36

Bu yüzden sadece portre modal görünümleri görüntülerken aynı problemle karşılaştım. Normalde, bir oluşturmak istiyorum UINavigationController, set viewControllerolarak rootViewControllerdaha sonra görüntülemek UINavigationControllerkalıcı bir görünüm olarak. Ancak iOS 6 ile, viewControllerartık navigationController'den desteklenen arayüz yönlerini soracaktır (varsayılan olarak bu, artık iPad ve her şey için, ancak iPhone için baş aşağı).

Çözüm : UINavigationControllerOtorotasyon yöntemlerini alt sınıfa ayırmak ve geçersiz kılmak zorunda kaldım . Biraz ezik.

- (BOOL)shouldAutorotate {
    return NO;
}

- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskPortrait;
}
// pre-iOS 6 support 
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
    return (toInterfaceOrientation == UIInterfaceOrientationPortrait);
}

1
benimki üzerinde çalışmıyor. Bu kodu global olarak tüm
yönlere ayarladım

2
supportedInterfaceOrientations BOOL değil, NSUInteger döndürmelidir. Bkz developer.apple.com/library/ios/#featuredarticles/...
tomwhipple

işe yaradı, benim için tabbarcontroller, cevap için tekrar teşekkürler
otakuProgrammer

FWIW, bu rotaya da gitmem gerekiyordu ... Başka hiçbir şey işe yaramadı. Teşekkürler.
Steve N

15

İOS 5

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{

    return (interfaceOrientation == UIInterfaceOrientationPortrait);

}

İOS 6

-(BOOL)shouldAutorotate{
    return YES;
}

-(NSInteger)supportedInterfaceOrientations{

    //    UIInterfaceOrientationMaskLandscape;
    //    24
    //
    //    UIInterfaceOrientationMaskLandscapeLeft;
    //    16
    //
    //    UIInterfaceOrientationMaskLandscapeRight;
    //    8
    //
    //    UIInterfaceOrientationMaskPortrait;
    //    2

    //    return UIInterfaceOrientationMaskPortrait; 
    //    or
          return 2;
}

Mükemmel! En fazla bu konunun en üstünde olması gerekiyor. Çünkü sorunu çözmenin en basit yolu
Alex

@Roshan Jalgaonkar In ios 6 Benim için çalışmıyor Sadece aşağı ana düğmeli portreye ihtiyacım var bu UIO Yönlendirmesini nasıl ayarlayabilirim ....
Karthik

@Karthik, bunun çalışması için Uygulamanızın hedefinde desteklenen rotasyonları etkinleştirmeniz gerekir.
Alejandro Iván

10

@Aprato cevabına katılmıyorum, çünkü UIViewController rotasyon yöntemleri kategorilerin kendisinde bildirilmiştir, bu nedenle başka bir kategoride geçersiz kılarsanız tanımsız davranışla sonuçlanır. Bunları bir UINavigationController (veya UITabBarController) alt sınıfında geçersiz kılmak daha güvenlidir

Ayrıca bu, Yatay görünümden yalnızca dikey VC'ye veya tam tersi yönde ittiğiniz / sunduğunuz / açtığınız senaryoyu kapsamaz. Bu zor sorunu çözmek için (asla Apple tarafından ele alınmadı) şunları yapmalısınız:

İOS <= 4 ve iOS> = 6'da:

UIViewController *vc = [[UIViewController alloc]init];
[self presentModalViewController:vc animated:NO];
[self dismissModalViewControllerAnimated:NO];
[vc release];

İOS 5'te:

UIWindow *window = [[UIApplication sharedApplication] keyWindow];
UIView *view = [window.subviews objectAtIndex:0];
[view removeFromSuperview];
[window addSubview:view];

Bunlar GERÇEKTEN UIKit'i tüm gerekliAutorotate, supportedInterfaceOrientations, vb. Bilgilerinizi yeniden değerlendirmeye zorlayacaktır.


2
Bunlardan ilki, iOS sürümünden bağımsız olarak benim için çöküyor. Görevden alınma zamanı bitmeden çağrılmaması gerektiğini söylüyor.
arsenius

@arsenius Nasıl kullandığınıza dair bir pasaj gönderebilir misiniz? Animasyon yapılmadığı sürece bahsettiğiniz sorunu içermemelidir
Rafael Nobre

Ayrıca ikinci pasajı viewDidAppear'a koydum ve iOS 6'daki durumuma yardımcı olacak hiçbir şey yapmıyor. Soru burada: stackoverflow.com/questions/15654339/…
arsenius

Üzgünüm, son bir yorum burada. İOS 5 kodunu viewDidAppear'a taşımak, bu çıktıyla bir çeşit sonsuz döngü oluşturur: - [UIApplication beginIgnoringInteractionEvents] taşması. Görmezden geliyor.
arsenius

3

Https://stackoverflow.com/a/13982508/2516436 ve https://stackoverflow.com/a/17578272/2516436'yı karıştıran çok iyi bir yaklaşımım var

-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
    NSUInteger orientations = UIInterfaceOrientationMaskAllButUpsideDown;


    if(self.window.rootViewController){
        UIViewController *presentedViewController = [self topViewControllerWithRootViewController:self.window.rootViewController];
        orientations = [presentedViewController supportedInterfaceOrientations];
    }

    return orientations;
}

- (UIViewController*)topViewControllerWithRootViewController:(UIViewController*)rootViewController {
    if ([rootViewController isKindOfClass:[UITabBarController class]]) {
        UITabBarController* tabBarController = (UITabBarController*)rootViewController;
        return [self topViewControllerWithRootViewController:tabBarController.selectedViewController];
    } else if ([rootViewController isKindOfClass:[UINavigationController class]]) {
        UINavigationController* navigationController = (UINavigationController*)rootViewController;
        return [self topViewControllerWithRootViewController:navigationController.visibleViewController];
    } else if (rootViewController.presentedViewController) {
        UIViewController* presentedViewController = rootViewController.presentedViewController;
        return [self topViewControllerWithRootViewController:presentedViewController];
    } else {
        return rootViewController;
    }
}

ve her UIViewController için desteklemek istediğiniz yönleri geri verin

- (NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskPortrait;
}

1

UISplitViewController ve UISegmentedController'ı kullanan nispeten karmaşık bir evrensel uygulamaya sahibim ve Landscape içinde şu şekilde sunulması gereken birkaç görünüme sahibim presentViewController . Yukarıda önerilen yöntemleri kullanarak, iPhone ios 5 & 6'yı kabul edilebilir bir şekilde çalıştırmayı başardım, ancak bazı nedenlerden dolayı iPad Manzara olarak sunmayı reddetti. Son olarak, hem cihazlar hem de ios 5 & 6 için çalışan basit bir çözüm (saatlerce okuma ve deneme yanılma sonrasında uygulanan) buldum.

Adım 1) Kontrol cihazında, gerekli yönü belirtin (yukarıda belirtildiği gibi aşağı yukarı)

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}

-(BOOL)shouldAutorotate
{
    return YES;
}

-(NSUInteger)supportedInterfaceOrientations
{
    NSInteger mask = UIInterfaceOrientationMaskLandscape;
    return mask;

}

Adım 2) Basit bir UINavigationController alt sınıfı oluşturun ve aşağıdaki yöntemleri uygulayın

-(BOOL)shouldAutorotate {
        return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
        return UIInterfaceOrientationMaskLandscape;
}

Adım 3) viewController'ınızı sunun

vc = [[MyViewController alloc]init];
MyLandscapeNavigationController *myNavigationController = [[MyLandscapeNavigationController alloc] initWithRootViewController:vc];
[self myNavigationController animated:YES completion:nil];

Umarım bu birine yardımcı olur.


1

Burada sıkıcı olmamak için, ama alt sınıfınızı paylaşır mısınız? Teşekkür ederim.

düzenleme: iyi, sonunda yaptım, alt sınıf yapmak çok basitti. Sadece beyan etmek zorunda navigationControlleriçinde AppDelegateolarak UINavigationControllerSubclassyerine varsayılan UINavigationController, sonra alt sınıf ile değiştirilme:

- (BOOL)shouldAutorotate {
    return _shouldRotate;
}

Böylece döndürmek isteyip istemediğim herhangi bir görünümü şu numarayı arayarak ayarlayabilirim viewDidLoad

_navController = (UINavigationController *)self.navigationController;
[_navController setShouldRotate : YES / NO]

Umarım bu ince ayar başkalarına da yardımcı olur, bahşişiniz için teşekkürler!

İpucu: Kullanın

- (NSUInteger)supportedInterfaceOrientations

görünüm denetleyicilerinizde, böylece yatayda istediğiniz bir portreye veya tam tersine bir portre elde etmek zorunda kalmazsınız.


0

Kendim test etmedim, ancak belgeler artık bu yöntemleri geçersiz kılabileceğinizi belirtiyor: supportedInterfaceOrientationsve preferredInterfaceOrientationForPresentation.

Muhtemelen, yalnızca bu yöntemlerde istediğiniz yönü ayarlayarak istediğinizi elde edebilirsiniz.


0

UINavigationController ve UITabBarController sınıfları içindeki VC'lere izin vermek için alt sınıfları veya kategorileri kullanan yanıtlar iyi çalışır. Bir yatay sekme çubuğu denetleyicisinden yalnızca dikey bir modal başlatılamadı. Bunu yapmanız gerekiyorsa, animasyonsuz mod görünümü gösterme ve gizleme hilesini kullanın, ancak bunu viewDidAppear yönteminde yapın . ViewDidLoad veya viewWillAppear'da benim için işe yaramadı.

Bunun dışında yukarıdaki çözümler iyi çalışıyor.


0

Monotouch için bunu şu şekilde yapabilirsiniz:

public override UIInterfaceOrientationMask GetSupportedInterfaceOrientations()
    {
    return UIInterfaceOrientationMask.LandscapeRight;
}

public override UIInterfaceOrientation PreferredInterfaceOrientationForPresentation()
    {
    return UIInterfaceOrientation.LandscapeRight;
}


-1

Sadece project.plist'e gidin, ardından Desteklenen arayüz yönünü ekleyin ve ardından yalnızca Dikey (alt ana sayfa düğmesi) ve Dikey (üst ana sayfa düğmesi) ekleyin.

Proje gereksiniminize göre orada yönlendirme ekleyebilir veya kaldırabilirsiniz.

Teşekkürler


1
tüm uygulama için değil, belirli bir görünüm denetleyicisi ile ilgili.
Muhammad Rizwan

-2

1) Proje ayarlarınızı ve info.plist'i kontrol edin ve yalnızca istediğiniz yönlerin seçildiğinden emin olun.

2) En üstteki görünüm denetleyicinize aşağıdaki yöntemleri ekleyin (gezinme denetleyicisi / sekme çubuğu denetleyicisi)

- (NSUInteger) supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait;

}

3) Uygulama temsilcinize aşağıdaki yöntemleri ekleyin

- (NSUInteger) supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait;

}

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
    return UIInterfaceOrientationMaskPortrait;

}

-3

Bunu her birinin .m dosyasına koyun ViewControllerBunu, döndürmek istemediğiniz :

- (NSUInteger)supportedInterfaceOrientations
{
    //return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft;
    return UIInterfaceOrientationMaskPortrait;
}

Daha fazla bilgi için buraya bakın .

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.