iPhone: solo in orizzontale, dopo la prima aggiunta di Subview, UITableViewController non ruota correttamente

StackOverflow https://stackoverflow.com/questions/1632117

  •  06-07-2019
  •  | 
  •  

Domanda

Un progetto Xcode illustrativo minimo per questo è disponibile su github .

Nella mia UIWindow, quando aggiungo le seconde (e successive) UITableView come visualizzazioni secondarie, non ruotano correttamente e quindi appaiono lateralmente. Questo è testato solo nel simulatore. Ecco un piccolo codice per te:

- (void)applicationDidFinishLaunching:(UIApplication *)application {
    ShellTVC* viewA = [[ShellTVC alloc] initWithTitle:@"View A"];
    ShellTVC* viewB = [[ShellTVC alloc] initWithTitle:@"View B"];

    // The first subview added will rotate to landscape correctly. 
    // Any subsequent subview added will not.

    // You may try this by various commentings and rearranging of these two statements.

    [window addSubview:[viewA tableView]];
    [window addSubview:[viewB tableView]];

    [window makeKeyAndVisible];
}

viewB appare lateralmente. Commenta addSubview per viewB e viewA appare correttamente. Fallo solo per viewA e viewB appare correttamente.

Non sto creando questi UITableViewController tramite NIB, sebbene UIWindow lo sia.

Nel caso vi stiate chiedendo, ShellTVC è un UITableViewController e implementa questo metodo:

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

Inoltre, ho impostato UIInterfaceOrientation nel file plist su UIInterfaceOrientationL landscapeLeft.

Probabilmente relative - e senza risposta - domande SO qui e qui .

È stato utile?

Soluzione

Penso di aver trovato un modo - forse il modo giusto - per farlo.

  1. Crea un " master " Sottoclasse UIViewController, che implementa dovrebbeAutorotare ..., e aggiungilo come unica vista sulla tua finestra.
  2. Per alternare viewA o viewB, usa la combinazione di dismissModalViewControllerAnimated: & amp; presentModalViewController: animato: su questo controller vista master.

Ecco un po 'di codice:

// this doesn't really do much but implement shouldAutorotate...
@interface MasterViewController : UIViewController
@end

@implementation MasterViewController
- (BOOL) shouldAutorotateToInterfaceOrientation(UIInterfaceOrientation)interfaceOrientation {
     return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}
@end

@interface MyAppDelegate : NSObject <UIApplicationDelegate> {
    MasterViewController* masterVC;
    UIViewController* activeTVC;
    UIViewController* onDeckTVC;
}
@end

- (void)applicationDidFinishLaunching:(UIApplication *)application {
    UIViewController* masterVC = [[MasterViewController alloc] init];        
    activeTVC = [[ShellTVC alloc] initWithTitle:@"View A"];
    onDeckTVC = [[ShellTVC alloc] initWithTitle:@"View B"];
    [window addSubview:masterView.view];
    [window makeKeyAndVisible];
    [masterVC presentModalViewController:activeTVC animated:NO];
}

// you would call this to toggle between "View A" and "View B"
- (void)toggleTVC {
    UITableViewController *hold = activeTVC;
    activeTVC = onDeckTVC;
    onDeckTVC = hold;
    [masterVC dismissModalViewControllerAnimated:NO];   
    [masterVC presentModalViewController:activeTVC animated:NO];
}

Perché funziona?

  1. Tutte le modifiche all'orientamento scorrono attraverso i controller di visualizzazione, non le visualizzazioni.

  2. Per quanto ne so, la prima vista o sottoview che aggiungi alla tua finestra ottiene un po 'di salsa speciale. Se quella vista ha un controller di vista, la finestra lo capisce.

Cioè, solo per la prima sottoview, puoi pensare a questo codice:

[window addSubview:masterVC.view];

come fare qualcosa del genere (non un metodo reale!):

[window addSubview:masterVC.view withViewController:masterVC];

Non ne capisco più di così. Trovo il fatto di poterlo fare con la prima sottoview, ma non con altri, estremamente sconcertante. Sono state accolte più informazioni e per favore fatemi sapere se questo vi ha aiutato o meno.

Altri suggerimenti

Apparentemente se aggiungi la vista come figlio di viewS verrà ruotata correttamente. Questa non è un'ottima soluzione per il mio progetto, ma sembra che potrebbe essere l'unica soluzione.

Sfortunatamente alle tue subview vengono chieste solo quali orientamenti supportano quando si verifica un cambiamento di orientamento.

Quindi finisco per impostare l'orientamento prima di spingere il nuovo controller di visualizzazione nello stack se so che è cambiato:

[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationPortrait]; 

Sì, questa è una chiamata non supportata.

Puoi usare l'oggetto UIApplication per forzare un particolare orientamento del dispositivo.

[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO];

Sì, credo che tu debba risolvere questo problema con XIB multipli. Ricordo di aver visto questa soluzione attraverso uno dei libri che ho letto in passato. In caso contrario, hai giocato con Traduzione e posizione dell'oggetto nella vista ... è meglio avere XIB separato.

Questo dovrebbe funzionare.

- (void)viewDidLoad {
    if (([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeLeft) || 
        ([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeRight)) 

    {
        self.view.frame = CGRectMake(0, 0, 1024, 748);

    } else {
        self.view.frame = CGRectMake(0, 0, 768, 1004);
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top