web-dev-qa-db-fra.com

Erreur "Les fenêtres d'application doivent comporter un contrôleur de vue racine à la fin du lancement de l'application" uniquement sur iPad

J'essaie de convertir uniquement mon application iPhone en application universelle. J'ai basculé les appareils sur Universal et laissé Xcode créer un MainWindow-iPad.xib pour moi. Désormais, lorsque je lance l'application dans le simulateur iPhone, cela fonctionne bien, mais lorsque je l'exécute dans le simulateur iPad, je reçois un blanc. l'écran et l'erreur Application windows are expected to have a root view controller at the end of application launch. J'ai lu d'autres articles sur le même problème, mais aucun d'entre eux ne se limite à un seul appareil.

Voici ma méthode application:didFinishLaunchWithOptions::

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

 /* some dropbox setup stuff */


// INIT VIEW AND CORE DATA
RootViewController *rootViewController = [[RootViewController alloc] initWithNibName:@"RootViewController" bundle:nil];

NSManagedObjectContext *context = [self managedObjectContext];
if (!context) {
    // Handle the error.
}

rootViewController.managedObjectContext = context;

UINavigationController *aNavigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController];
self.navigationController = aNavigationController;

[_window addSubview:[_navigationController view]];
[_window makeKeyAndVisible];

[rootViewController release];
[aNavigationController release];

return YES;
}

EDIT: Je n'ai qu'un contrôleur de vue racine de la taille d'un iPhone, appelé RootViewController. Mais il devrait quand même se charger, n'est-ce pas? Ou si cela ne devrait pas, comment en créer un pour iPad?

19
Josh Sherick

Changer la ligne suivante:

[_window addSubview:[_navigationController view]];

à:

_window.rootViewController = _navigationController;

ou, si vous avez besoin de la compatibilité avec iOS 3:

if ([_window respondsToSelector:@selector(setRootViewController:)]) {
    _window.rootViewController = _navigationController;
} else {
    [_window addSubview:_navigationController.view];
}
52
hoshi

Vous devez créer un RootViewController avec le fichier xib pour iPad, sinon vous obtiendrez cette erreur. Vous trouverez ci-dessous le modèle de code fourni par Xcode pour l'application universelle. Si vous déboguez l'application dans le simulateur iPad et que vous indiquez au débogueur de créer le contrôleur de vue avec le fichier xib de l'iPhone, vous verrez l'erreur exacte.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
        self.viewController = [[SYKViewController alloc] initWithNibName:@"SYKViewController_iPhone" bundle:nil];
    } else {
        self.viewController = [[SYKViewController alloc] initWithNibName:@"SYKViewController_iPad" bundle:nil];
    }
    self.window.rootViewController = self.viewController;
    [self.window makeKeyAndVisible];
    return YES;
}
2
Ken W

Dans iOS 4 et versions ultérieures, UIWindow a la propriété configurable rootViewController. C'est le UINavigationController qui pousse le UIViewController affiché au lancement de l'application. Dans Xcode IB, la sélection Scène initiale: le contrôleur de vue initial pour UINavigationController configure tout, sans code.

2
paul.lander

À partir du fichier MainWindow-iPad.xib généré, dans Interface Builder, ajoutez un objet View Controller dans IB, ainsi qu'un objet situé sous la vue. Pour l'objet, définissez sa classe sur AppDelegate, pour le contrôleur de vue, définissez la classe sur ViewController (dans l'inspecteur d'identité) et spécifiez le nom du nib dans l'inspecteur des attributs. Vous pouvez consulter le fichier MainWindow.nib du périphérique à partir duquel vous effectuez la conversion pour connaître les différences.

Edit: J'ai oublié de mentionner quelques étapes importantes. Vous devrez également définir la classe Propriétaire du fichier sur "UIApplication" dans IB, ainsi que les sorties référencées de manière appropriée pour le délégué d'application et le contrôleur d'affichage. Là encore, dans IB, il est plus facile de consulter l'inspecteur de connexions de la plume MainWindow que vous avez eu et de l'imiter. Si vous avez une autre nib spécifique à l'iPad, autre que MainWindow-iPad.nib (c'est-à-dire ViewController-iPad.nib), assurez-vous de sélectionner le propriétaire de son fichier, de le pointer vers la vue et de définir correctement sa classe.

2
Ed Lau

J'ai essayé vos suggestions, mais aucune d'entre elles n'a fonctionné pour moi, désolée. :/J'ai fini par créer la vue manuellement dans le code sans le constructeur d'interface:

if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
    // Setup view for iPad
} else
    // Setup view for iPhone and iPod Touch
}

que je pensais être beaucoup plus difficile qu’il ne l’était en réalité.

Notez que si vous utilisez cette méthode, vous pouvez toujours tout brancher dans le générateur d'interface et modifier simplement le cadre des objets dans ces blocs si vous allez avoir les mêmes objets sur iPhone et iPad.

0
Josh Sherick