2014-09-13 25 views
23

Ho un'applicazione che viene configurato tramite il file plist per sostenere ritratto, paesaggio a sinistra, e gli orientamenti del paesaggio di destra (cioè UISupportedInterfaceOrientations è impostato su UIInterfaceOrientationPortrait, UIInterfaceOrientationLandscapeLeft, e UIInterfaceOrientationLandscapeRight). Ma ho limitato gli orientamenti supportati al solo ritratto all'interno di un controller di visualizzazione. Se presento un UIActionSheet sulla vista del controller della vista e quindi ruoto il dispositivo, UIActionSheet ruota verso il nuovo orientamento. Questo succede solo su dispositivi con iOS 8 (GM Seed).iOS 8 UIActionSheet ignora vista supportedInterfaceOrientations controller e shouldAutorotate

Desidero che UIActionSheet segua le regole del controller della vista contenente e non ruoti. Pensieri?

non voglio che questo accada: screenshot http://oi58.tinypic.com/20tgto2.jpg

UIViewController codice di esempio:

- (IBAction)onTouch:(id)sender 
{ 
    UIActionSheet * actionSheet = [[UIActionSheet alloc] initWithTitle:@"hi" 
                 delegate:nil 
               cancelButtonTitle:@"Cancel" 
             destructiveButtonTitle:nil 
               otherButtonTitles:@"Open", nil]; 

    [actionSheet showInView:self.view]; 
} 

#pragma mark - Rotation methods 

- (BOOL)shouldAutorotate 
{ 
    return NO; 
} 

- (NSUInteger)supportedInterfaceOrientations 
{ 
    return UIInterfaceOrientationMaskPortrait; 
} 

risposta

5

è stato informato che UIAlertController sostituisce UIActionSheet in iOS 8.

"La nuova classe UIAlertController sostituisce le classi UIActionSheet e UIAlertView come modo preferito per visualizzare gli avvisi nella tua app. "

https://developer.apple.com/library/prerelease/ios/releasenotes/General/WhatsNewIniOS/Articles/iOS8.html

UIAlertController * alertController = [UIAlertController alertControllerWithTitle:@"hi" 
                      message:nil 
                    preferredStyle:UIAlertControllerStyleActionSheet]; 

[alertController addAction:[UIAlertAction actionWithTitle:@"Open" 
                style:UIAlertActionStyleDefault 
               handler:^(UIAlertAction *action) { 
                // open something 
               }]]; 

[alertController addAction:[UIAlertAction actionWithTitle:@"Cancel" 
                style:UIAlertActionStyleCancel 
               handler:nil]]; 

[self presentViewController:alertController animated:YES completion:nil]; 
+5

Certo, c'è un nuovo modo "preferito", ma perché cambiare/rompere le vecchie funzionalità di lavoro solo perché viene introdotto un nuovo modo? Questo nuovo modo è l'unico modo per ottenere il comportamento originale? – Bushrod

+0

No, perché gli utenti iOS7 devono ancora gestire i vecchi avvisi/fogli. Chiaramente un bug che ha bisogno di essere risolto. – Morrowless

+2

Su iOS7 il vecchio UIActionSheet non presenta il problema di rotazione. Usa UIActionSheet su iOS7 e precedenti. Utilizzare UIAlertController su iOS8 e versioni successive. Cerca NSClassFromString (@ "UIAlertController") per determinare quale codice utilizzare. – Awesomeness

11

Ho avuto un problema simile con iOS 8 e trovato una soluzione che può aiutare se si vuole attaccare con UIAlertView e UIActionSheet per ora, invece di migrare a UIAlertController.

La mia app consente di visualizzare Orizzontale e Verticale, ma solo su alcune visualizzazioni. Il più delle volte consente solo Portrait. Voglio che UIAlertView e UIActionSheet appaiano solo in Portrait (perché le viste in cui si trovano consentono solo Portrait).

Sfortunatamente, con iOS 8 gli avvisi e i fogli di azione ora ruotano, ignorando il metodo shouldAutorotate del controller della vista radice della finestra. La vista e la barra di stato sotto l'avviso rimangono visibili in Ritratto anche se l'avviso ruota. Se l'avviso prende un input, la tastiera rimane anche Portrait, quindi è davvero poco attraente.

Stavo per arrendermi, ma alla fine ho trovato qualcosa che funziona, anche se non è l'ideale. Metti questo nel tuo delegato dell'app e adattalo secondo necessità. Non vedo l'ora di trovare una soluzione migliore (probabilmente usando solo le nuove classi). Il confronto delle stringhe qui è ovviamente zoppo, e questo sovrascriverà qualsiasi cosa tu abbia impostato come orientamento supportato in Info.plist. Almeno è qualcosa per andare avanti ...

-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window 
{ 
    NSString *viewControllerClassName = [NSString stringWithUTF8String:object_getClassName(window.rootViewController)]; 
    if ([viewControllerClassName isEqualToString:@"_UIAlertShimPresentingViewController"]) { 
     return UIInterfaceOrientationMaskPortrait; 
    } 
    else { 
     return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight; 
    } 
} 

Per saperne di più su questo delegato qui:

https://developer.apple.com/library/prerelease/iOS/documentation/UIKit/Reference/UIApplicationDelegate_Protocol/index.html#//apple_ref/occ/intfm/UIApplicationDelegate/application:supportedInterfaceOrientationsForWindow:

+0

Ciò comporterà il rifiuto di un App Store poiché utilizza una classe privata? – sethfri

+0

Se sei preoccupato per "_UI ...", prova la variazione di user3750435 di seguito. "Usare" il nome della classe per determinare quando non ruotare non è la cosa più sicura, ma non dovrebbe essere una violazione poiché non sta chiamando alcun metodo/proprietà della classe. Come altra alternativa, potresti abbinare la finestra alla tua finestra conosciuta. Il mio uso è solo per l'impresa, quindi nessun rischio di rifiuto. – Bushrod

21

ecco la mia soluzione basata sulla soluzione da Busrod con alcune modifiche perché ho avuto alcuni problemi nel UIActionSheet utilizzando la sua soluzione:

-(UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window 
{ 
    UIViewController *presentedViewController = window.rootViewController.presentedViewController; 
    if (presentedViewController) { 
     if ([presentedViewController isKindOfClass:[UIActivityViewController class]] || [presentedViewController isKindOfClass:[UIAlertController class]]) { 
      return UIInterfaceOrientationMaskPortrait; 
     } 
    } 
    return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight; 
} 
+0

Sì, questo funzionerebbe. Grazie! Ho optato per utilizzare il nuovo UIAlertController se disponibile. L'uso dei blocchi è abbastanza bello e presto svanirò il supporto per iOS 7. – Awesomeness

+2

Questo fallisce con il ritratto capovolto. – Vignesh

+0

se si desidera supportare sottosopra, restituire invece UIInterfaceOrientationMaskAll. –

0

Aggiungendo a @ user3750435 's risposta

Poiché l'OP ha definito le maschere di rotazione che desidera nello Info.plist, non è necessario ridefinire le maschere qui.UIApplication può restituirci tali maschere tramite supportedInterfaceOrientationsForWindow:. Così, il metodo può essere resa più semplice in questo modo:

-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window 
{ 
    UIViewController *presentedViewController = window.rootViewController.presentedViewController; 
    if (presentedViewController) { 
     if ([presentedViewController isKindOfClass:[UIActivityViewController class]] || [presentedViewController isKindOfClass:[UIAlertController class]]) { 
      return UIInterfaceOrientationMaskPortrait; 
     } 
    } 
    return [application supportedInterfaceOrientationsForWindow:window]; 
} 
0

- (NSUInteger) applicazione: (UIApplication *) applicazione supportedInterfaceOrientationsForWindow: (UIWindow *) Finestra {

UIViewController *presentedViewController = window.rootViewController.presentedViewController; 
if (presentedViewController) { 
    if ([presentedViewController isKindOfClass:[UIActivityViewController class]] || [presentedViewController isKindOfClass:[UIAlertController class]]) { 
     return UIInterfaceOrientationMaskPortrait; 
    } 
} 
return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight; 

}

grazie per me ha funzionato per me