web-dev-qa-db-fra.com

iOS - Comment contrôlez-vous la taille d'un contrôleur de vue modale?

Je présente un contrôleur de vue modale. Si cela est important, il défile vers le bas. Comment puis-je contrôler quelle partie de l'écran il occupe?

EDIT: J'ai le suivant dans le contrôleur de vue modale. Ça n'aide pas.

- (void)viewDidLoad {
    TestResultView *trv = [[TestResultView alloc]initWithTest: [Model m].currentTest];
    self.view = trv;
    trv.frame = CGRectMake(0, 320, 320, 160);
    [trv release];
    [super viewDidLoad];
}
30
William Jockusch

Vous pouvez modifier le cadre du contrôleur de vue, mais si vous utilisez la méthode -presentModalViewController: animated de UIViewController: la vue derrière sera déchargée une fois que votre vue modale aura fini de s'animer sur l'écran (cela suppose que vous êtes sur un iPhone) et vous verrez un écran blanc où votre vue d'arrière-plan devrait être. iOS suppose que votre contrôleur de vue modale sera un contrôleur de vue plein écran et vide l'autre vue pour économiser de la mémoire.

Si vous voulez vraiment afficher une vue sur une partie de l'écran, vous devez à la place ajouter la vue UIView (pas de UIViewController) à la vue actuelle de votre UIViewController en tant que sous-vue, puis l'animer vous-même à l'écran. Je pense que quelque chose comme ça fonctionnerait dans votre classe UIViewController qui présentera la vue:

// Add the view as a subview and position it offscreen just below the current view
UIView *myHalfView = [[UIView alloc] initWithFrame:someAppropriateFrame];
[self.view addSubview:myHalfView];
CGRect offScreenFrame = myHalfView.bounds;
offScreenFrame.Origin = CGPointMake(0.0, CGRectGetMaxY(self.view.frame));

// Now animate the view upwards
[UIView beginAnimations:nil context:nil];
// Move the view upwards the height of your sliding view so it's entirely onscreen
myHalfView.center = CGPointMake(myHalfView.center.x, myHalfView.center.y - myHalfView.bounds.size.height);
[UIView commitAnimations];
[myHalfView release];

Pour les points bonus, vous pouvez estomper la vue en définissant

myHalfView.alpha = 0.0;

avant le bloc d'animation UIView et définition

myHalfView.alpha = 1.0;

à l'intérieur du bloc après avoir animé la propriété center.

Lorsque vous avez terminé, vous pouvez faire quelque chose de similaire mais en sens inverse pour faire glisser la vue hors écran. Vous pouvez ajouter un sélecteur animationDidStop au bloc d'animation UIView pour être averti lorsque la vue a glissé hors de l'écran afin de pouvoir la supprimer de la hiérarchie des vues.

D'un point de vue esthétique, vous devez également faire attention à la façon dont vous faites cela, car avoir une vue coulissante vers le haut est un comportement standard, et si votre vue ressemble à une vue normale mais s'arrête à mi-chemin, les utilisateurs peuvent sentir (même brièvement) que l'application a gelé. Ils le découvriront, mais cela laissera un mauvais pressentiment sur votre application si elle n'est pas gérée avec soin. Surtout, j'éviterais d'utiliser des repères plein écran standard comme l'inclusion d'un UINavigationController en haut de votre vue pour aider les utilisateurs à comprendre ce qui se passe. Les demi-feuilles ont tendance à être UIActionSheets sur l'iPhone, alors pensez dans cette direction.

38
atticus

C'est Nice, la réponse acceptée ci-dessus explique un hack de Nice pour présenter des sous-vues qui ressemblent à ModalViews, mais que se passe-t-il si c'est un iPad, et je peux en effet lui donner un modalViewController qui ne couvre pas tout l'écran.

Dans le cas des iPads, je ne pense pas que la vue en dessous sera déchargée. (car il existe des options où nous pouvons présenter le modalView sur iPad, qui ne couvre pas tout l'écran)

ModalViewController est à la fin un contrôleur lui-même, et comme tout autre contrôleur a une vue racine, dont les propriétés peuvent être modifiées, si nous pouvons nous en emparer.

Voici ce qui vous donnera un cadre personnalisé du ModalView:

MyViewController *viewController = [[MyViewController alloc] init];
viewConroller.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentModalViewController:viewController animated:YES];
    //superView of viewController's view is modalViewController's view, which we were after
viewController.view.superview.frame = CGRectMake(x,y,w,h);
    //x y w h - can have desired values.
26
dsaw

J'ajouterais à la réponse de @ dsaw que la vue d'ensemble de la vue modale ne semble pas faire pivoter son système de coordonnées en mode paysage. Voici le code que j'ai utilisé dans ma propre application:

MyViewController* modalVC = [[MyViewController alloc] init];        
modalVC.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentModalViewController:modalVC animated:NO];
CGRect r = CGRectMake(self.view.bounds.size.width/2 - 236,
                      self.view.bounds.size.height/2 - 130,
                      472, 260);
r = [self.view convertRect:r toView:modalVC.view.superview.superview];
modalVC.view.superview.frame = r;

Bien que la vue d'ensemble ne puisse pas se tourner avec l'iPad, elle semble faire la bonne chose et garder la vue modale centrée si je tourne l'iPad après avoir montré la vue modale.

20
bugloaf