“De-Vue-Contrôleur” disparaît à l'aide de UIViewControllerContextTransitioning
J'ai eu un problème et j'ai décrit ci-dessous.
Je suis en utilisant UIViewControllerContextTransitioning pour les transitions personnalisées.
J'ai 2 vue des contrôleurs , à première vue, contrôleur et la seconde vue contrôleur.
Maintenant, je veux ajouter secondview contrôleur à première vue-contrôleur avec animation. J'ai réalisé cela, j'ai maintenant secondview contrôleur transparent , de sorte que nous pouvons voir à première vue-contrôleur ci-dessous secondview contrôleur.
Mais je ne suis pas en mesure de voir à première vue-contrôleur , et je peux voir que du noir de l'écran ci-dessous secondview contrôleur.
Voici le code.
-(void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext{
self.transitionContext = transitionContext;
if(self.isPresenting){
[self executePresentationAnimation:transitionContext];
}
else{
[self executeDismissalAnimation:transitionContext];
}
}
-(void)executePresentationAnimation:(id<UIViewControllerContextTransitioning>)transitionContext{
UIView* inView = [transitionContext containerView];
UIViewController* toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIViewController* fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
CGRect offScreenFrame = inView.frame;
offScreenFrame.origin.y = inView.frame.size.height;
toViewController.view.frame = offScreenFrame;
toViewController.view.backgroundColor = [UIColor clearColor];
fromViewController.view.backgroundColor = [UIColor clearColor];
inView.backgroundColor = [UIColor clearColor];
[inView insertSubview:toViewController.view aboveSubview:fromViewController.view];
//[inView addSubview:toViewController.view];
CFTimeInterval duration = self.presentationDuration;
CFTimeInterval halfDuration = duration/2;
CATransform3D t1 = [self firstTransform];
CATransform3D t2 = [self secondTransformWithView:fromViewController.view];
[UIView animateKeyframesWithDuration:halfDuration delay:0.0 options:UIViewKeyframeAnimationOptionCalculationModeLinear animations:^{
[UIView addKeyframeWithRelativeStartTime:0.0f relativeDuration:0.5f animations:^{
fromViewController.view.layer.transform = t1;
}];
[UIView addKeyframeWithRelativeStartTime:0.5f relativeDuration:0.5f animations:^{
fromViewController.view.layer.transform = t2;
}];
} completion:^(BOOL finished) {
}];
[UIView animateWithDuration:duration delay:(halfDuration - (0.3*halfDuration)) usingSpringWithDamping:0.7f initialSpringVelocity:6.0f options:UIViewAnimationOptionCurveEaseIn animations:^{
toViewController.view.frame = inView.frame;
} completion:^(BOOL finished) {
[self.transitionContext completeTransition:YES];
}];
}
Quand [self.transitionContext completeTransition:YES];
appelé, tout à coup le premier-vue-contrôleur disparaît et l'écran noir s'affiche au-dessous de seconde vue-contrôleur.
Ce que quelqu'un a idée ?
Merci.
Vous devez vous connecter pour publier un commentaire.
J'ai eu le même problème ici – ressemble à un bug dans iOS 8. J'ai déposé un radar.
J'ai utilisé Révéler pour inspecter le point de vue de la hiérarchie après l'écran devient noir. La clé
UIWindow
est entièrement vide, pas de vue de la hiérarchie à tous!J'ai joué un peu et il semble qu'il y est une simple solution de contournement, pour les cas simples. Vous pouvez simplement ajouter de nouveau le
toViewController
's vue comme une sous-vue de la touche de la fenêtre:J'ai vérifié et la clé de la fenêtre
rootViewController
est toujours bien réglé, c'est très bien. Je ne suis pas sûr de ce qui se passerait si vous avez présenté votre contrôleur de dans une déjà présenté modal contrôleur, donc, pour les cas plus complexes, vous aurez à expérimenter autour de.modalPresentationStyle = UIModalPresentationFullScreen
. Bien sûr, vous obtenez toujours votre custom animation de transition.UIModalPresentationOverFullScreen
Je me sens comme le raisonnement derrière cela devrait être mieux expliquée.
La vue disparaît parce que vous sortez de la présentation de la vue du contrôleur de la vue de son emplacement d'origine (afficher la hiérarchie), le mettre à l'intérieur de la containerView que votre animateur fournit, mais ne revient jamais en arrière une fois l'animation terminée. De sorte que la vue du contrôleur de point de vue est enlevée avec sa superview (containerView) à partir de la fenêtre complètement.
Dans iOS 7, le système retourne toujours afficher les contrôleurs de points de vue qui sont impliqués dans la présentation (présentation et présentée) à leur emplacement d'origine après la transition a fini d'animer automatiquement. Qui ne se fait plus pour certains styles de présentation dans iOS 8.
La règle est très simple: l'animateur ne doit manipuler la présentation de la vue du contrôleur de la vue, si ce point de vue du contrôleur de la vue va être cachées (supprimé à partir de la vue de la hiérarchie) complètement par la la fin de la transition. En d'autres termes cela signifie que, après la présentation initiale de l'animation ne finit que la vue du contrôleur de la vue sera visible et pas de présenter en vue du contrôleur de vue. Par exemple, si vous définissez présentés vue du contrôleur de vue de l'opacité à 50% et l'utilisation UIModalPresentationFullScreen vous ne serez pas en mesure de voir la présentation de la vue du contrôleur de la vue de dessous de l'présenté, mais si vous utilisez UIModalPresentationOverFullscreen - vous (UIPresentationController de
shouldRemovePresentersView
méthode est chargé de préciser que).Pourquoi ne pas permettre à l'animateur de manipuler la présentation de la vue du contrôleur de la vue à tout moment? Tout d'abord, si la présentation de la vue du contrôleur de la vue va rester visible après l'animation des finitions au cours de l'ensemble de la présentation du cycle de vie il n'y a pas besoin de l'animer à tous qu'il reste où il est. Deuxièmement, si le droit de propriété pour afficher la barre de contrôle est transféré à la présentation de contrôleur, la présentation de la manette plus susceptibles de ne pas savoir comment la mise en page que la vue du contrôleur de la vue lorsque nécessaire, par exemple lorsque les changements d'orientation, mais le propriétaire original de la présentation de la vue contrôleur n'.
Dans iOS 8
viewForKey:
méthode a été introduite pour obtenir des vues que l'animateur manipule. Tout d'abord, il permet de suivre la règle décrite ci-dessus par le retour de néant à chaque fois que l'animateur ne doit pas toucher la vue. Deuxièmement, il peut retourner un différents vue de l'animateur pour animer. Imaginez que vous êtes à la mise en œuvre d'une présentation similaire à la forme de la feuille. Dans ce cas, vous voulez ajouter un peu de l'ombre ou de la décoration autour de la vue du contrôleur de vue. L'animateur s'animer que la décoration de la place, et la vue du contrôleur de vue d'un enfant de la décoration.viewControllerForKey:
ne disparaît pas, il peut toujours être utilisé si un accès direct à la vue des contrôleurs est nécessaire, mais l'animateur ne doit pas faire d'hypothèses sur le point de vue qu'il doit animer.Il y a plusieurs choses que vous pouvez faire pour correctement résoudre un problème avec la disparition de la présentation de la vue du contrôleur de la vue lorsque vous explicitement le placer à l'intérieur de l'animateur du conteneur affichage:
Si n'avez pas besoin d'animer la présentation de la vue du contrôleur de la vue, de l'utilisation
viewForKey:
pour obtenir des vues d'animer au lieu de tendre la main à vue-contrôleur les vues directement.viewForKey:
peut retourner nil ou même complètement différents points de vue.Si vous souhaitez animer la présentation de la vue des contrôleurs de vue, vous devriez envisager d'utiliser
UIModalPresentationFullScreen
de style ou de continuer à utiliserUIModalPresentationCustom
et de mettre en œuvre votre propre sous-classe de UIPresentationController avecshouldRemovePresentersView
retourYES
. En fait, la mise en œuvre de cette méthode est la principale différence entre la présentation interne des contrôleurs défini parUIModalPresentationFullScreen
etUIModalPresentationCustom
styles en dehors du fait que ce dernier vous permet d'utiliser vos propres présentation des contrôleurs.Dans tous les autres cas rares, vous devez revenir sur la présentation de la vue du contrôleur de la vue à son emplacement d'origine comme d'autres réponses suggérées.
viewControllerForKey:
'sview
seulement quandviewForKey:
retourne nil, et je toujours a l'ajouter de nouveau à la fenêtre manuellement. Avez-vous un exemple de code de travail sans cette solution de contournement?viewForKey:
retourne nil alors pour sûr, vous devrez re-ajouter la présentation de la vue du contrôleur de la vue de la fenêtre si vous le retirez de votre animateur. En cas viewForKey retourne l'opinion du contrôleur de vue, il est sûr de déplacer ce point de vue, car UIKit serait le replacer à sa position initiale après la présentation du cycle de vie est de plus de.Dans iOS 8, vous devez manipuler les vues retourné par
viewForKey:
au lieu de la.view
propriété de la vue des contrôleurs retourné parviewControllerForKey:
. Ce n'est pas particulièrement clair à partir de la documentation de la version bêta, mais si vous regardez dans le code source pour UIViewControllerTransitioning.h vous verrez ce commentaire ci-dessusviewControllerForKey:
:Donc, au lieu de régler etc cadres de
toViewController.view
, utiliser la valeur de retour de[transitionContext viewForKey:UITransitionContextToViewKey]
.Si votre application a besoin de soutien iOS7 et/ou Xcode 5, alors vous pouvez utiliser une simple catégorie de méthode sur UIViewController comme suit:
Puis, obtenez votre
toViewController
etfromViewController
comme d'habitude, mais avoir le point de vue à l'aide de[toViewController viewForTransitionContext:transitionContext]
.Edit: Il semble y avoir un bug, d'où la présentation de la vue du contrôleur de vue est nulle lorsque le retour de
viewForKey
, ce qui vous empêche de faire modale des transitions qui animent la présentation de la vue à tous (comme le glisser, ou flip-horizontal). J'ai déposé un bug pour iOS8 à rdar://17961976 (http://openradar.appspot.com/radar?id=5210815787433984). Voir aussi l'exemple de projet à http://github.com/bcherry/TransitionBugEdit 2: Merci à graveley pour la suggestion, à l'aide de UIModalPresentationFullScreen résout le problème. Peut-être que ce n'est pas un bug. Apple a l'intention que UIModalPresentationCustom modifie seulement le point de vue de l'entrants modal. Si vous souhaitez modifier les sortants de vue, vous avez besoin de garantir le plein écran de présentation de la nouvelle vue? Dans tous les cas, vous devez utiliser
viewForKey
et UIModalPresentationFullScreen.manipulating
le VCs vues ou pas...viewForKey
bug dans le GM ainsi. Sont les autres? Avez-vous trouvé une solution raisonnable pour elle?- viewForKey
// viewForKey: peut retourner nil qui indiquent que l'animateur ne devraient pas manipuler la vue associée du contrôleur de vue. De retournil
n'est pas un bug.viewForKey
ne retour la de la vue et de l'afficher. Alors peut-être que c'est à dessein qu'elle renvoie nil pour UIModalPresentationCustom. Je suis à jour de mon rapport de bug et après revenir ici si j'ai des nouvelles de Apple à ce sujet.De ne pas fixer de
modalPresentationStyle
à UIModalPresentationCustom résolu le problème pour moi.En d'autres termes, en laissant à la valeur par défaut de UIModalPresentationFullScreen au lieu de spécifier UIModalPresentationCustom fixe la disparition de vue en question. Remarque le UIViewControllerTransitioningDelegate encore, le protocole semble être suivie, même en sortant à la valeur par défaut. Si je me souviens bien, une fois UIModalPresentationCustom est une exigence.
Fonctionne jusqu'à présent, ne l'ai essayé ce pour les non-animations interactives.
viewForKey:
au lieu de.view
sur leviewControllerForKey:
résout tous les problèmes pour moi.J'ai trouvé cela très utile de répondre à un sujet par Lefteris:
https://stackoverflow.com/a/27165723/3709173
Pour résumer:
+1 dans votre transition personnalisée, n'ajoutez pas de toView lorsque le licenciement d'animation qui se passe.
Démontré ici:
https://www.dropbox.com/s/7rpkyamv9k9j18v/CustomModalTransition.zip?dl=0
sans hacks! c'est comme de la magie! 🙂
Dans iOS 8, vous avez besoin de créer un UIPresentationController et de mettre en œuvre la méthode ci-dessous, dans la UIViewControllerTransitioningDelegate.
Pour plus d'informations, regardez la WWDC 2014, la vidéo:
https://developer.apple.com/videos/wwdc/2014/?include=228
Il y a aussi un exemple de code à partir de la WWDC appelé "LookInside: Présentation des Contrôleurs d'Adaptabilité et Personnalisé Animateur Objets", que vous pouvez télécharger à partir de la WWDC 2014 exemple de page de code.
Vous devrez peut-être modifier l'exemple de code un peu. Le UIPresentationController méthode init changé:
Avant il a été de présenter et ensuite présenté. Il suffit de le remplacer et cela devrait fonctionner.
au lieu de [inView insertSubview:toViewController.vue aboveSubview:fromViewController.vue];
juste ajouter: [inView addSubview:toViewController.vue];
Vous pouvez voir un exemple ici: lien et il fonctionne sur iOS 7 et iOS 8
Ici est un Objectif de la version C de la Cendre du correctif.
J'ai eu à inverser l'ordre et de l'appel de la [transitionContext completeTransition: la méthode] après l'ajout de la vue arrière pour obtenir la présentation d'un nouveau-vue-contrôleur de la destitution de l'achèvement de bloquer un autre point de vue contrôleur de travailler correctement.
Je ne sais pas si ça va résoudre le problème pour tout le monde, mais il fonctionne dans mon application. Cheers!
J'ai trouvé cela a bien fonctionné pour Obj-C:
Semble fonctionner sur les deux ios7 et ios8.
J'ai trouvé que
viewForKey:UITransitionContextToViewKey
retourne nil sur ios8. Donc, si c'est nul, je prends le point de vue de l' 'à' - vue-contrôleur.Cependant, il semble que ce résultat dans le 'à' vue de ne pas être déplacés à partir du conteneur de la fenêtre lors de la
completeTransition:YES
est appelé. Donc, siviewForKey:UITransitionContextToViewKey
retourne nil, je tombe surtoVC.view
, et de garder trace du fait qu'il est revenu à zéro, et après l'achèvement je le déplacer vers le conteneur initial superview (qui se trouve être la fenêtre).Si ce code fonctionne sur iOS7 ainsi que iOS8, et devrait travail sur iOS9 trop même si ils le réparer ou pas.
J'ai trouvé que ce bug (et bien d'autres!) disparaît si vous définissez
modalPresentationStyle = UIModalPresentationFullScreen
. Bien sûr, vous obtenez toujours votre custom animation de transition.Après avoir rencontré ce problème, j'ai été très confus, parce que j'avais écrit quelque chose de presque identique a pas si longtemps que a bien fonctionné. Venu ici chercher des réponses à trouver des correctifs de regarder assez hacky, et ne semblent pas comprendre la cause... c'est vraiment très facile à corriger.
Quelques réponses mention de changer
modalPresentationStyle
à.overFullScreen
. C'est correct,.overCurrentContext
serait trop de travail. Ce qui est attendu, et le comportement d'Apple documents. Mais pourquoi n'est-ce pas de travail pour tout le monde? Pourquoi tous les hacky code, et les combinaisons de ce avec quelque chose d'autre, et truc de dingue que vous ne devriez pas être en train de faire?S'avère, vous devez définir le style de présentation AVANT LE point de VUE des CHARGES. Pas après. Le faire dans l'init, ou de le faire à partir du contrôleur précédent, ou si vous le souhaitez, tant que c'est avant le point de vue des charges.
.overCurrentContext
avant le point de vue de la charge (dans leinit
de la vue-contrôleur) et le problème se produit toujoursÀ l'aide de la nouvelle UIModalPresentationOverCurrentContext fixe pour moi. Mon premier passage sur iOS 7 était juste pour avoir un flou d'arrière-plan de la vue sous le modal.
Je suis coincé sur cette question. Je cherchais à créer une transition personnalisée avec un fond semi-transparent où je pouvais encore voir le point de vue du contrôleur, j'ai été à venir, mais j'ai seulement eu un arrière-plan noir. J'ai trouvé la Marque de Aron réponse dans ce thread m'a aidé, mais il est écrit en Objective C voici donc une Swift 3 version de cette réponse, qui je l'ai testé pour l'iOS 9 et iOS 10:
Créer une sous-classe de UIPresentationController. Remplacer le shouldRemovePresentersView à faux comme suit:
Dans le lieu que vous l'instanciation de la nouvelle-vue-contrôleur et la fixation de sa transition délégué, indiquez que vous souhaitez qu'il s'affiche personnalisée modal style de présentation comme suit:
Maintenant remplacer le presentationController méthode de votre UIViewControllerTransitioningDelegate et retour personnalisé de votre UIPresentationController. J'ai eu la mienne comme une extension de ma classe actuelle:
Une autre chose à noter est que vous ne devriez pas essayer de référence et de votre fromView dans votre presentAnimator classe. Ce sera nulle, et vous obtiendrez un message d'erreur lors de l'exécution. Autre que cela, si vous implémentez des choses comme des choses, vous obtiendrez votre transition personnalisée avec son animation et un fond semi-transparent, si vous faites un.
presentationController(forPresented presented UIViewController,...
car la précédente swift API n'a pas bouleversé le compilateur, mais ne l'a pas appelée.ajoute une-vue-contrôleur en tant qu'enfant d'un autre point de vue contrôleur.
vérifier les et laissez-moi savoir.