it-swarm.dev

rotazioni di iOS 6: supportatoInterfaceOrientations non funziona?

Sto avendo questo problema con l'SDK di iOS 6: sto avendo alcuni punti di vista che dovrebbero essere autorizzati a ruotare (ad esempio una videoregistrazione), e alcuni che non ... .. Ora capisco che devo controllare tutti gli orientamenti nel app Info.plist e poi riordinare in ogni ViewController, cosa dovrebbe accadere. Ma non funziona! L'app ruota sempre verso gli orientamenti, che sono indicati in Info.plist.

Info.plist:

<key>UISupportedInterfaceOrientations</key>
    <array>
        <string>UIInterfaceOrientationPortrait</string>
        <string>UIInterfaceOrientationLandscapeLeft</string>
        <string>UIInterfaceOrientationLandscapeRight</string>
    </array>

qualsiasi ViewController che non dovrebbe poter ruotare:

//deprecated
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

- (NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortrait;
}

Osservazione: l'app ruota in orizzontale e verticale. Qualche idea del perché o di quello che sto facendo male?

Saluti, Marc

Modifica: I miei ultimi risultati indicano anche che, se si desidera avere la rotazione in un punto della propria app, si ha per attivare tutte e quattro le direzioni di rotazione nelle impostazioni del progetto o in Info.plist. Un'alternativa a questo è l'override 

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window

nel tuo AppDelegate, che sovrascrive Info.plist. Non è più possibile impostare solo Portrait in Info.plist e quindi avere la rotazione in alcuni ViewController ignorando shouldAutorotateToInterfaceOrientation o supportInterfaceOrientations. 

36
stk

Se il tuo ViewController è figlio di un UINavigationController o UITabBarController, allora è il genitore il tuo problema. Potrebbe essere necessario suddividere in sottoclasse il controllore della vista genitore, ignorando semplicemente i metodi di InterfaceOrientation come hai mostrato nella tua domanda

MODIFICARE:

Esempio per TabBarController solo verticale

           @interface MyTabBarController : UITabBarController
            {
            }
            @end

            @implementation MyTabBarController

            // put your shouldAutorotateToInterfaceOrientation and other overrides here        
            - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
                return (interfaceOrientation == UIInterfaceOrientationPortrait);
            }

            - (NSUInteger)supportedInterfaceOrientations{ 
                return UIInterfaceOrientationMaskPortrait; 
            } 

        @end
31
CSmith

Aggiungendo la risposta di CSmith sopra, il codice seguente in una sottoclasse UINavigationController consente la delega al controller di visualizzazione superiore nel modo in cui mi aspettavo che funzionasse in primo luogo:

- (BOOL)shouldAutorotate;
{
    return YES;
}

- (NSUInteger)supportedInterfaceOrientations
{
    if ([[self topViewController] respondsToSelector:@selector(supportedInterfaceOrientations)])
        return [[self topViewController] supportedInterfaceOrientations];
    else
        return [super supportedInterfaceOrientations];
}
27
Evan Schoenberg

Ecco un'altra alternativa all'approccio di CSmith.

Se si desidera replicare il comportamento di pre-iOS 6 in cui tutte le viste nella barra di navigazione/barra delle schede devono concordare un insieme di orientamenti consentiti, inserire questo nella sottoclasse di UITabBarController o UINavigationController:

- (NSUInteger)supportedInterfaceOrientations
{
    NSUInteger orientations = [super supportedInterfaceOrientations];

    for (UIViewController *controller in self.viewControllers)
        orientations = orientations & [controller supportedInterfaceOrientations];

    return orientations;
}
8
Glenn Schmidt

Prova ad aggiungere questa categoria:

@interface UINavigationController(InterfaceOrientation)

@end

@implementation UINavigationController(InterfaceOrientation)

- (NSUInteger) supportedInterfaceOrientations {
    if (self.viewControllers.count > 0)
        return [[self.viewControllers objectAtIndex:0] supportedInterfaceOrientations];
    else
        return UIInterfaceOrientationMaskAll;
}

@end
2
Shimanski Artem

Per le persone che usano UINavigationController e Swift, puoi aggiungere questa estensione al tuo progetto. Successivamente, i controller di navigazione delegano il controllo al proprio controller figlio.

extension UINavigationController {
    override public func supportedInterfaceOrientations()
    -> UIInterfaceOrientationMask {
        if let ctrl = topViewController {
            return ctrl.supportedInterfaceOrientations()
        }
        return super.supportedInterfaceOrientations()
    }

    override public func shouldAutorotate() -> Bool {
        if let ctrl = topViewController {
            return ctrl.shouldAutorotate()
        }
        return super.shouldAutorotate()
    }
}
1
Alvivi

@ La risposta di Alvivi è stata aggiornata per Swift 4 .

extension UINavigationController {

    // Look for the supportedInterfaceOrientations of the topViewController
    // Otherwise, viewController will rotate irrespective of the value returned by the ViewController
    override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        if let ctrl = self.topViewController {
            return ctrl.supportedInterfaceOrientations
        }
        return super.supportedInterfaceOrientations
    }

    // Look for the shouldAutorotate of the topViewController
    // Otherwise, viewController will rotate irrespective of the value returned by the ViewController
    override open var shouldAutorotate: Bool {
        if let ctrl = self.topViewController {
            return ctrl.shouldAutorotate
        }
        return super.shouldAutorotate
    }
}
0
Harikrishna Pai

Ulteriore aggiunta a @CSmith e @EvanSchoenberg.

Se hai alcune viste che ruotano, e alcune viste che non lo fanno, devi creare un'istanza personalizzata di UITabBarController, lasciando comunque decidere ogni UIViewController.

- (BOOL)shouldAutorotate;
{
    return YES;
}

- (NSUInteger)supportedInterfaceOrientations
{
    UIViewController * top;
    UIViewController * tab = self.selectedViewController;
    if([tab isKindOfClass:
        ([UINavigationController class])]) {
        top = [((UINavigationController *)tab)
                 topViewController];
    }

    if ([top respondsToSelector:@selector(supportedInterfaceOrientations)])
        return [top supportedInterfaceOrientations];
    else
        return [super supportedInterfaceOrientations];
}
0
SwiftArchitect