ios centro - Come forzare l'orientamento del controller di visualizzazione in iOS 8?




12 Answers

Per iOS 7 - 10:

Objective-C:

[[UIDevice currentDevice] setValue:@(UIInterfaceOrientationLandscapeLeft) forKey:@"orientation"];
[UINavigationController attemptRotationToDeviceOrientation];

Swift 3:

let value = UIInterfaceOrientation.landscapeLeft.rawValue
UIDevice.current.setValue(value, forKey: "orientation")
UINavigationController.attemptRotationToDeviceOrientation()

Basta chiamarlo - viewDidAppear: del controller di visualizzazione presentato.

controllo ipad

Prima di iOS 8, abbiamo utilizzato il codice riportato di seguito insieme a SupportInterfaceOrientations e dovremmo eseguire i metodi di delega di AutoPost per forzare l'orientamento delle app su qualsiasi orientamento particolare. Ho utilizzato sotto lo snippet di codice per ruotare l'app a livello di programmazione all'orientamento desiderato. Innanzitutto, sto cambiando l'orientamento della barra di stato. E quindi solo presentando e immediatamente ignorando una vista modale, la vista ruota all'orientamento desiderato.

[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:YES];
UIViewController *c = [[UIViewController alloc]init];
[self presentViewController:vc animated:NO completion:nil];
[self dismissViewControllerAnimated:NO completion:nil];

Ma questo non funziona in iOS 8. Inoltre, ho visto alcune risposte nello in cui le persone hanno suggerito di evitare sempre questo approccio da iOS 8 in poi.

Per essere più specifici, la mia applicazione è un tipo universale di applicazione. Ci sono tre controller in totale.

  1. Controller First View - Dovrebbe supportare tutti gli orientamenti in iPad e solo portrait (pulsante home down) in iPhone.

  2. Controller Vista Secondaria - Dovrebbe supportare solo l'orizzontale in tutte le condizioni

  3. Controller Third View - Dovrebbe supportare solo l'orizzontale in tutte le condizioni

Stiamo utilizzando il controller di navigazione per la navigazione della pagina. Dal primo controller di visualizzazione, in un'azione di clic del pulsante, stiamo spingendo il secondo in pila. Quindi, quando arriva il secondo controller di visualizzazione, indipendentemente dall'orientamento del dispositivo, l'app dovrebbe bloccarsi solo in orizzontale.

Di seguito sono riportati i metodi shouldAutorotate e supportedInterfaceOrientations nel secondo e terzo controller di visualizzazione.

-(NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskLandscapeRight;
}

-(BOOL)shouldAutorotate {
    return NO;
}

C'è qualche soluzione per questo o qualsiasi altro modo migliore di bloccare un controller di visualizzazione in particolare orientamento per iOS 8. Per favore aiutatemi !!




Ho scoperto che se si tratta di un controller di visualizzazione presentato, è possibile sovrascrivere preferredInterfaceOrientationForPresentation

Swift:

override func supportedInterfaceOrientations() -> Int {
  return Int(UIInterfaceOrientationMask.Landscape.rawValue)
}

override func preferredInterfaceOrientationForPresentation() -> UIInterfaceOrientation {
  return UIInterfaceOrientation.LandscapeLeft
}

override func shouldAutorotate() -> Bool {
  return false
}



In questo modo lavoro per me in Swift 2 iOS 8.x:

PS (questo metodo non richiede di sovrascrivere le funzioni di orientamento come dovrebbeautorotato su ogni viewController, solo un metodo su AppDelegate)

Controlla "richiede schermo intero" nelle informazioni generali del progetto.

Quindi, su AppDelegate.swift crea una variabile:

var enableAllOrientation = false

Quindi, metti anche questa funzione:

func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> UIInterfaceOrientationMask {
        if (enableAllOrientation == true){
            return UIInterfaceOrientationMask.All
        }
        return UIInterfaceOrientationMask.Portrait
}

Quindi, in ogni classe del tuo progetto puoi impostare questa var in viewWillAppear:

override func viewWillAppear(animated: Bool)
{
        super.viewWillAppear(animated)
        let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
        appDelegate.enableAllOrientation = true
}

Se devi fare una scelta in base al tipo di dispositivo puoi farlo:

override func viewWillAppear(animated: Bool)
    {
        super.viewWillAppear(animated)
        let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
        switch UIDevice.currentDevice().userInterfaceIdiom {
        case .Phone:
        // It's an iPhone
           print(" - Only portrait mode to iPhone")
           appDelegate.enableAllOrientation = false
        case .Pad:
        // It's an iPad
           print(" - All orientation mode enabled on iPad")
           appDelegate.enableAllOrientation = true
        case .Unspecified:
        // Uh, oh! What could it be?
           appDelegate.enableAllOrientation = false
        }
    }



Questo è un feedback ai commenti nella risposta di Sid Shah , riguardo a come disabilitare le animazioni usando:

[UIView setAnimationsEnabled:enabled];

Codice:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:NO];
    [UIView setAnimationsEnabled:NO];

    //  #26357162 to force orientation
    NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeRight];
    [[UIDevice currentDevice] setValue:value forKey:@"orientation"];
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:NO];
    [UIView setAnimationsEnabled:YES];
}



Se si utilizza navigationViewController, è necessario creare la propria superclasse per questo e sovrascrivere:

- (BOOL)shouldAutorotate {
  id currentViewController = self.topViewController;

  if ([currentViewController isKindOfClass:[SecondViewController class]])
    return NO;

  return YES;
}

ciò disabiliterà la rotazione in SecondViewController ma se si spinge SecondViewController quando il dispositivo è in orientamento verticale, il SecondViewController apparirà in modalità verticale .

Supponi di utilizzare lo storyboard. Devi creare manuale segue ( Come fare ) e nel tuo metodo "onClick":

- (IBAction)onPlayButtonClicked:(UIBarButtonItem *)sender {
  NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft];
  [[UIDevice currentDevice] setValue:value forKey:@"orientation"];
  [self performSegueWithIdentifier:@"PushPlayerViewController" sender:self];
}

Questo forzerà l'orientamento orizzontale prima che la superclasse disabiliti la funzione di autorotazione.




La combinazione di risposte Sids e Koreys ha funzionato per me.

Estensione del controller di navigazione:

extension UINavigationController {
    public override func shouldAutorotate() -> Bool {
        return visibleViewController.shouldAutorotate()
    }
}

Quindi disabilitando la rotazione sulla singola vista

class ViewController: UIViewController {
    override func shouldAutorotate() -> Bool {
        return false
    }
}

E ruotando fino all'orientamento appropriato prima dei passaggi

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if (segue.identifier == "SomeSegue")
    {
        let value = UIInterfaceOrientation.Portrait.rawValue;
        UIDevice.currentDevice().setValue(value, forKey: "orientation")
    }
}



I miei requisiti sono

  1. bloccare tutte le viste in modalità verticale
  2. utilizzare AVPlayerViewController per riprodurre video

Quando il video è in riproduzione, se si tratta di un paesaggio, consentire allo schermo di ruotare il paesaggio a destra e a sinistra del paesaggio. Se si tratta di un ritratto, bloccare la vista solo in modalità verticale.

Innanzitutto, definire supportedInterfaceOrientationsForWindow AppDelegate.swift per AppDelegate.swift in AppDelegate.swift

var portrait = true
func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> UIInterfaceOrientationMask {
    if portrait {
        return .Portrait
    } else {
        return .Landscape
    }
}

In secondo luogo, nel controller della vista principale, definire le seguenti funzioni

override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
    print("\(#function)")
    return .Portrait
}

override func preferredInterfaceOrientationForPresentation() -> UIInterfaceOrientation {
    return .Portrait
}

override func shouldAutorotate() -> Bool {
    return false
}

Quindi, è necessario sottoclasse AVPlayerViewController

class MyPlayerViewController: AVPlayerViewController {

    var size: CGSize?

    var supportedOrientationMask: UIInterfaceOrientationMask?
    var preferredOrientation: UIInterfaceOrientation?

    override func viewDidLoad() {
        super.viewDidLoad()

        if let size = size {
            if size.width > size.height {
                self.supportedOrientationMask =[.LandscapeLeft,.LandscapeRight]
                self.preferredOrientation =.LandscapeRight
            } else {
                self.supportedOrientationMask =.Portrait
                self.preferredOrientation =.Portrait
            }
        }
    }

Sostituisci queste tre funzioni in MyPlayerViewController.swift

override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
    return self.supportedOrientationMask!
}

override func preferredInterfaceOrientationForPresentation() -> UIInterfaceOrientation {
    return self.preferredOrientation!
}

Poiché l'utente può ruotare il paesaggio del dispositivo a sinistra o orizzontale a destra, è necessario impostare la rotazione automatica per essere vero

override func shouldAutorotate() -> Bool {
    return true
}

Infine, crea MyPlayerViewController istanza MyPlayerViewController nel controller di visualizzazione e imposta il valore della dimensione della proprietà.

let playerViewController = MyPlayerViewController()

// Get the thumbnail  
let thumbnail = MyAlbumFileManager.sharedManager().getThumbnailFromMyVideoMedia(......)

let size = thumbnail?.size
playerViewController.size = size

Avvia il tuo giocatore con videoUrl corretto, quindi assegna il tuo giocatore a playerViewController . Buona programmazione!




- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    [UIViewController attemptRotationToDeviceOrientation];
}



Ho provato alcune soluzioni qui e la cosa importante da capire è che è il controller della vista radice che determinerà se ruoterà o meno.

Ho creato il seguente progetto obiettivo-c github.com/GabLeRoux/RotationLockInTabbedViewChild con un esempio funzionante di TabbedViewController cui è possibile ruotare una vista figlio e l'altra vista TabbedViewController è bloccata in verticale.

Non è perfetto ma funziona e la stessa idea dovrebbe funzionare per altri tipi di visualizzazioni di root come NavigationViewController . :)




Secondo la soluzione mostrata da @ sid-sha devi mettere tutto nel viewDidAppear: metodo, altrimenti non otterrai la didRotateFromInterfaceOrientation: licenziata, quindi qualcosa del tipo:

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    UIInterfaceOrientation interfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation];
    if (interfaceOrientation == UIInterfaceOrientationLandscapeLeft ||
        interfaceOrientation == UIInterfaceOrientationLandscapeRight) {
        NSNumber *value = [NSNumber numberWithInt:interfaceOrientation];
        [[UIDevice currentDevice] setValue:value forKey:@"orientation"];
    }
}



Usalo per bloccare l'orientamento del controller di visualizzazione, testato su IOS 9:

// Blocca l'orientamento in orizzontale

-(UIInterfaceOrientationMask)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskLandscapeRight;
}

-(NSUInteger)navigationControllerSupportedInterfaceOrientations:(UINavigationController *)navigationController {
    return UIInterfaceOrientationMaskLandscapeRight;
}



Ho lo stesso problema e spreco così tanto tempo per questo. Quindi ora ho la mia soluzione. L'impostazione della mia app è supportata solo da portrait.Tuttavia, alcune schermate nella mia app devono avere solo un panorama. Correggo il problema disponendo di una variabile su Ruota di appDelegate . E la funzione in AppDelegate :

func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> Int {
    if isShouldRotate == true {
        return Int(UIInterfaceOrientationMask.Landscape.rawValue)
    }
    return Int(UIInterfaceOrientationMask.Portrait.rawValue)
}

E infine quando un ViewControllerA necessita di uno stato orizzontale. Basta farlo: prima di spingere / presentare a ViewControllerA assegna isShouldRotate a true . Non dimenticare quando pop / ignori che il controller assegna isShouldRotate a false at viewWillDisappear .




Related

ios objective-c ios8 uinavigationcontroller autorotate