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



photobox coque (11)

Comme d'autres utilisateurs ici, j'ai aussi eu le problème que l'origine du contrôleur de vue modale 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, <width>, <height>);
}

J'ai un couple de contrôleurs de vue modale de certaine taille. J'essaie d'éviter l'utilisation de vues personnalisées (création de superposition noire translucide en plein écran sur la vue actuelle, ajout de la vue modale sur cette vue, faire les animations, etc.) pour la présenter car il n'y a pas de modalPresentationStyle qui correspond à la taille de mon contrôleurs.

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

Présentation souhaitée

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

Présentation réelle

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

Si j'utilise UIModalPresentationFormSheet, le conteneur est plus petit en largeur.

J'essaie de comprendre comment le faire mais je ne sais pas si c'est possible. Quelle est la solution au problème de présenter un VC modal plus petit que l'un des styles de présentation? La seule solution est d'organiser un "moteur de contrôleur de vue modale personnalisé"? Popovers ne correspond pas à mes exigences de conception :(


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.)


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

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 donne plus d'options de personnalisation.


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 sur les contrôleurs présent et présenté pour obtenir la transparence dans le VC présenté)

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 taille la vue de contenu d'abord mais dans une méthode différente.

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


J'ai eu un problème pour centrer le modal de taille personnalisée jusqu'à ce que je découvre ce que ViewController.view.superview.frame était initialement défini. 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, j'ai défini les coordonnées dynamiquement en utilisant [UIScreen mainScreen].applicationFrame , en ne prenant en charge que l'orientation paysage pour l'instant. Vous devez effectuer une vérification conditionnelle pour prendre en charge le portrait et le 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 palmé. Raccourcit un peu 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 les remarques.


Ceci est ma solution pour une vue PAS autolayout (jamais essayé avec autolayout) et compatible avec iOS 7 et iOS 8.

Assurez-vous d'abord d'appeler la vue modale de cette manière:

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 aussi 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 de 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 moi, je me débattais avec le même problème pendant un bon moment. Après avoir donné quelques essais de nombreuses réponses données ici, j'ai trouvé une solution qui a plutôt 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 xib (si vous en utilisez un), dans la section «Métriques 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é (c'est-à-dire, 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 également pour iOS 7


Redimensionner la vue modale "après" il est présenté en utilisant la méthode presentModalViewController. Voir ce lien pour redimensionner modal Voir https://coderwall.com/p/vebqaq


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


Le meilleur moyen de le faire est de modifier la propriété bounds dans la présentation de la vue présentée dans la feuille de formulaire. Lorsque vous présentez une vue de manière modale, la vue présentée est intégrée dans une autre vue.

Vous devez définir la propriété bounds de la vue supérieure 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 qui est 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];
}

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 modale. Faites-moi savoir si vous avez besoin d'aide supplémentaire.





modalviewcontroller