Taille personnalisée iPad du contrôleur de vue modal

J’ai quelques contrôleurs de vue modale d’une certaine taille. J’essaie d’éviter l’utilisation de vues personnalisées (création de superpositions transparentes en plein écran sur la vue en cours, ajout de la vue modale sur cette vue, animation, etc.) pour le présenter car il n’y a pas de modalPresentationStyle contrôleurs.

Maintenant, j’utilise UIModalPresentationPageSheet mais ma vue est plus petite en hauteur et j’ai un espace vide

Présentation souhaitée

_______________ | _______ | | | | | | | MyVC | | | | | | | ------- | --------------- 

Présentation réelle

  _______________ | | | | | | MyVC | | | | | | | |-------| | | | blank | | --------------- 

Si j’utilise la feuille UIModalPresentationFormSheet, la taille du conteneur est plus petite.

J’essaie de comprendre comment le faire mais je ne sais pas si c’est possible. Quelle est la solution au problème de la présentation d’un VC modal plus petit que n’importe lequel des presentationStyles? La seule solution consiste à organiser un “moteur de contrôleur de vue modal personnalisé”? Popovers ne correspond pas à mes exigences de conception 🙁

Comme certains autres utilisateurs ici, j’avais également le problème que l’origine du contrôleur de vue modal n’était pas correcte. Après quelques expériences, j’ai trouvé une solution qui a fonctionné pour moi:

 - (void)viewWillLayoutSubviews{ [super viewWillLayoutSubviews]; self.view.superview.bounds = CGRectMake(0, 0, , ); } 

J’ai obtenu le résultat suivant ( texte du lien ) en utilisant:

 self.modalPresentationStyle = UIModalPresentationFormSheet; 

et en le présentant comme un contrôleur de vue modal. Faites-moi savoir si vous avez besoin d’aide supplémentaire.

Toutes ces réponses ne fonctionneront pas sur le SDK ios8.

Cela fonctionnera:

 AboutViewController * _aboutViewController = [[AboutViewController alloc] init]; _aboutViewController.modalPresentationStyle = UIModalPresentationFormSheet; if(IS_IOS8) { _aboutViewController.preferredContentSize = CGSizeMake(300, 300); } [self presentViewController:_aboutViewController animated:YES completion:nil]; 

Dans AboutViewController.m

 - (void)viewWillLayoutSubviews{ [super viewWillLayoutSubviews]; if(!IS_IOS8) { self.view.superview.bounds = CGRectMake(0, 0, 300, 300); } } 

IS_IOS8

 #define IS_IOS8 ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8) 

Dans iOS 8, vous pouvez également utiliser UIPresentationController, qui vous offre davantage d’options de personnalisation.

J’ai eu un problème pour centrer le modal de taille personnalisée jusqu’à ce que je ViewController.view.superview.frame quoi ViewController.view.superview.frame était initialement destiné. Il est déterminé en fonction du type UIModalPresentation. superview.center n’est même pas nécessaire (pour autant que mes tests le montrent).

De plus, je configure les coordonnées dynamicment à l’aide de [UIScreen mainScreen].applicationFrame , en prenant uniquement en charge l’orientation paysage pour le moment. Vous devez effectuer une vérification conditionnelle pour prendre en charge les modes portrait et paysage en inversant les valeurs X / Y et Height / Width.

Voici ma première solution de travail pour iOS 6.0:

 ViewController.modalPresentationStyle = UIModalPresentationFormSheet; ViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve; [self presentViewController:ViewController animated:YES completion:nil]; ViewController.view.superview.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin; ViewController.view.superview.frame = CGRectMake( // Calcuation based on landscape orientation (width=height) ([UIScreen mainScreen].applicationFrame.size.height/2)-(320/2),// X ([UIScreen mainScreen].applicationFrame.size.width/2)-(320/2),// Y 320,// Width 320// Height ); 

Et puis j’ai regardé la réponse précédente et le visage pâli. Raccourcit ma solution en remplaçant la dernière ligne par:

 ViewController.view.superview.bounds = CGRectMake(0, 0, 320, 320); 

EDIT pour la solution finale et remarques.

La meilleure façon de procéder consiste à modifier la propriété bounds de la vue de la vue présentée dans la feuille de formulaire. Lorsque vous présentez une vue modalement, la vue présentée est intégrée à une autre vue.

Vous devez définir la propriété bounds de la superview sur le même rect que les limites de la vue. Ajoutez d’abord un ivar privé dans votre classe:

 @implementation MySpecialFormsheet { CGRect _realBounds; } 

Il est préférable de le faire dans viewWillAppear: Ajoutez le code suivant au contrôleur de vue présenté de manière modale:

 - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; self.view.superview.bounds = _realBounds; } 

Vous devez mettre en cache _realBounds dans votre méthode viewDidLoad :

 - (void)viewDidLoad { _realBounds = self.view.bounds; [super viewDidLoad]; } 

C’est ma solution pour une vue NON autolayout (jamais essayée avec autolayout) et compatible avec iOS 7 et iOS 8.

Assurez-vous d’abord d’appeler la vue modale de la manière suivante:

 CloudSettingsViewController *cloudController = [[CloudSettingsViewController alloc] initWithNibName:@"CloudSettingsView" bundle:nil]; CGRect originalBounds = cloudController.view.bounds; cloudController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve; cloudController.modalPresentationStyle = UIModalPresentationFormSheet; [self presentViewController:cloudController animated:YES completion:nil]; 

Avec iOS 8, définissez preferredContentSize dans la méthode viewDidLoad de la vue modale.

 - (void)viewDidLoad { [super viewDidLoad]; // backup of the original size (selected in interface builder) height = self.view.frame.size.height; width = self.view.frame.size.width; if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8) // versioni successive ios 8 self.preferredContentSize = CGSizeMake(width, height); // this is necessary to get the correct size of the modal view } 

Cela fonctionne également lorsque la vue modale doit afficher le clavier sur iPad .

Avec les versions précédentes d’iOS 8, vous devez définir les limites après l’appel presentViewController:

 [currentController presentViewController:controlPanelController animated:YES completion:nil]; if ([[[UIDevice currentDevice] systemVersion] floatValue] < 8) cloudController.view.superview.bounds = originalBounds;//it's important to do this after 

même pour réduire la hauteur et la largeur de la feuille de forma que vous pouvez utiliser

 [self.view.superview setBounds:CGRectMake(0, 0, 450, 480)]; 

Les approches décrites ci-dessus doivent être modifiées pour iOS7:

 // set desired bounds, then call -presentFromViewController: @implementation PresentedViewController { CGRect _presentationBounds; } - (void)presentFromViewController:(UIViewController *)viewController { self.modalTransitionStyle = UIModalTransitionStyleCoverVertical; self.modalPresentationStyle = UIModalPresentationFormSheet; _presentationBounds = self.view.bounds; [viewController presentViewController:self animated:YES completion:nil]; } - (void)viewWillLayoutSubviews { [super viewWillLayoutSubviews]; if (!CGRectIsEmpty(_presentationBounds)) { self.view.superview.bounds = _presentationBounds; _presentationBounds = CGRectZero; } } 

(Ce code fonctionne également sur iOS6.)

Même moi, je me débattais avec le même problème depuis un certain temps. Après avoir donné quelques essais sur plusieurs des réponses données ici, j’ai trouvé une solution qui a très bien fonctionné pour moi.

Voici le code lors de la présentation du contrôleur de vue.

  SomeViewController *sovcObj = [[SomeViewController alloc] initWithNibName:@"SyncOptionsViewController" bundle:nil]; someObj.modalPresentationStyle = UIModalPresentationFormSheet; someObj.modalTransitionStyle = UIModalTransitionStyleCrossDissolve; [self presentViewController:someObj animated:YES completion:nil]; someObj.view.superview.bounds = CGRectMake(0, 0, 400, 400); // whatever width and height you want 

Dans le fichier xib (si vous en utilisez un) dans la section “Mésortingques simulées”, sélectionnez la taille “Freeform”.

En dehors de cela, vous devez écrire le code ci-dessous dans votre contrôleur de vue présenté (par exemple, SomeViewController dans cet exemple)

 - (void)viewWillLayoutSubviews{ [super viewWillLayoutSubviews]; self.view.superview.bounds = CGRectMake(0, 0, 400, 400); // whatever width and height you want 

}

Ce code fonctionne aussi pour iOS 7

Une solution consiste à utiliser UIModalPresentationPageSheet pour présenter une feuille de page, puis à redimensionner immédiatement la vue modale. Ceci est expliqué en détail dans cette réponse à une autre question .

Redimensionnez la vue modale “après” elle est présentée en utilisant la méthode presentModalViewController.Voir ce lien pour redimensionner la vue modale https://coderwall.com/p/vebqaq

Vous pouvez utiliser MZFormSheetController comme ceci:

 MZFormSheetController *formSheet = [[MZFormSheetController alloc] initWithSize:customSize viewController:presentedViewController]; [presentingViewController mz_presentFormSheetController:formSheet animated:YES completionHandler:nil]; 

Cette solution a fonctionné pour moi car j’avais le même problème.

Ma structure de vue modale est la suivante (j’utilise UIModalPresentationCurrentContext à la fois pour présenter et présenter les contrôleurs pour obtenir la transparence dans la VC présentée)

 ModalViewController > UIView (view) - resized to the same size as the presenting controller but has semi-translucent background - done automatically >> UIView (contentView) - the true view with the content of the popup - this is the one that got consistently placed at the top of the screen all the time 

Dans ModalViewController, j’ai remplacé la méthode suivante pour résoudre le problème de positionnement:

 - (void) viewWillLayoutSubviews(){ [super viewWillLayoutSubviews]; CGRect r = self.view.bounds(); self.contentView.center = CGPointMake(r.size.width/2,r.size.height/2); } 

En fait, je crée et redimensionne l’affichage du contenu en premier, mais avec une méthode différente.

J’espère que cela aide quelqu’un.