UIViewController - Problem mit benutzerdefiniertem Ablehnungsübergang
Zusammenfassung
Habe ich ein content UIViewController, stellt einen Einstellungen UIViewController mit einem eigenen übergang. Die Präsentation ist mit presentViewController:animated:completion:
.
Als ich dann später schließen Sie die Einstellungen mit dismissViewControllerAnimated:completion:
die Präsentation-controller ist plötzlich sprang zurück zu seiner anfänglichen position vor, um die Einstellungen der controller-Präsentation.
Ich habe eine Arbeit um für diese auf dem Gerät aber nicht der simulator. Allerdings würde ich gerne wissen was ich falsch mache, anstatt hack in einem bodge, macht es Weg. Ich Plane auch, um diese animation interactive, und ich vermute, dass diese Probleme verstärken wird, wenn ich dies tun.
Eigenen Übergang – Öffnung der Haube
Der gewünschte Effekt ist, dass die präsentiert controller-Folien auf dem Bildschirm, und die vorgestellt controller gesehen, dahinter liegend, von wo es sich erhebt, um den Bildschirm zu füllen. Der top des Präsentation-controller bleibt auf dem Bildschirm während der Lebensdauer der Nutzung der vorgestellten controller. Es bleibt am unteren Rand des Bildschirms, aber oben die vorgestellten controller.
Könnte man sich vorstellen, das anheben der Motorhaube bei einem Auto (vorne präsentieren-controller) zu sehen, der Motor hinter (den vorgestellten Einstellungen), aber die Motorhaube bleibt sichtbar an der Unterseite, für ein bisschen der Kontext.
Ich plan zu verfeinern, so dass der präsentierende controller erscheint wirklich zu heben mit Perspektive in einer 3d-Weise, aber ich habe nicht bekommen, weit, noch nicht.
Wenn die Einstellungen so sind entlassen, die original-Präsentation-Steuerung (Motorhaube) schieben sichern Sie den Bildschirm und die vorgestellten controller (Einstellungen) sinken leicht zurück (schließen der Motorhaube).
Code
Hier ist die Methode schaltet die Einstellungen auf und außerhalb des Bildschirms (es ist nur durch einen UIButton). Sie werden bemerken, dass die Darstellung view controller stellt sich als <UIViewControllerTransitioningDelegate>
.
-(void) toggleSettingsViewController
{
const BOOL settingsAreShowing = [self presentedViewController] != nil;
if(!settingsAreShowing)
{
UIViewController *const settingsController = [[self storyboard] instantiateViewControllerWithIdentifier: @"STSettingsViewController"];
[settingsController setTransitioningDelegate: self];
[settingsController setModalPresentationStyle: UIModalPresentationCustom];
[self presentViewController: settingsController animated: YES completion: nil];
}
else
{
[self dismissViewControllerAnimated: YES completion: nil];
}
}
Umzusetzen <UIViewControllerAnimatedTransitioning>
der Darstellung view controller auch nur die Renditen selbst als <UIViewControllerAnimatedTransitioning>
-(id<UIViewControllerAnimatedTransitioning>) animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source
{
return self;
}
-(id<UIViewControllerAnimatedTransitioning>) animationControllerForDismissedController:(UIViewController *)dismissed
{
//Test Point 1.
return self;
}
Also endlich, der Darstellung view controller erhalten animateTransition:
:
-(void) animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
UIViewController *const fromController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *const toController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
const BOOL isUnwinding = [toController presentedViewController] == fromController;
const BOOL isPresenting = !isUnwinding;
UIViewController * presentingController = isPresenting ? fromController : toController;
UIViewController * presentedController = isPresenting ? toController : fromController;
if(isPresenting)
{
//Add the presented controller (settings) to the view hierarchy _behind_ the presenting controller.
[[transitionContext containerView] insertSubview: [presentedController view] belowSubview: [presentingController view]];
//Set up the initial position of the presented settings controller. Scale it down so it seems in the distance. Alpha it down so it is dark and shadowed.
presentedController.view.transform = CGAffineTransformMakeScale(0.9, 0.9);
presentedController.view.alpha = 0.7;
[UIView animateWithDuration: [self transitionDuration: transitionContext] animations:^{
//Lift up the presented controller.
presentedController.view.transform = CGAffineTransformMakeScale(1.0, 1.0);
//Brighten the presented controller (out of shadow).
presentedController.view.alpha = 1;
//Push the presenting controller down the screen – 3d effect to be added later.
presentingController.view.layer.transform = CATransform3DMakeTranslation(0,400,0);
} completion: ^(BOOL finished){
[transitionContext completeTransition: ![transitionContext transitionWasCancelled]];
}];
}
else
{
//Test Point 2.
//!!!This line should not be needed!!!
//It resets the presenting controller to where it ought to be anyway.
presentingController.view.layer.transform = CATransform3DMakeTranslation(0,400,0);
[UIView animateWithDuration: [self transitionDuration: transitionContext] animations:^{
//Bring the presenting controller back to its original position.
presentingController.view.layer.transform = CATransform3DIdentity;
//Lower the presented controller again and put it back in to shade.
presentedController.view.transform = CGAffineTransformMakeScale(0.9, 0.9);
presentedController.view.alpha = 0.4;
} completion:^(BOOL finished) {
[transitionContext completeTransition: ![transitionContext transitionWasCancelled]];
}];
}
}
-(NSTimeInterval) transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext
{
return 0.5;
}
Problem
In dem code oben habe ich darauf hingewiesen,!!!Diese Zeile sollte nicht erforderlich sein!!!.
Was passiert, ist, dass zwischen Test Point 1 und Test Point 2 die position auf dem Bildschirm von der Darstellung view controller zurücksetzen, um die Standard-Vollbild Grenzen. Also, anstatt am unteren Rand des Bildschirms bereit, Sie zu animieren, wieder reibungslos, plötzlich springt der Bildschirm zu positionieren, dass es gemeint ist, um reibungslos zu animieren!
Ich habe versucht, verschiedene Ansätze, um die Animation der Präsentation-view-controller auf dem Bildschirm:
- Ich habe mich verändert seine Sicht auf ' s frame.
- Ich habe mich verändert seine Ansicht zu verwandeln.
- Ich habe mich verändert seine Sicht auf die Ebene ist die 3d-Transformation.
In allen Fällen, in Test Point 1wenn der übergang Delegierte wird gebeten, die Vorlage-controller eingerichtet ist, als ich erwarten würde. Jedoch, in allen Fällen, in Test Point 2der Darstellung view controller verloren hat, die richtige position und wurde "geräumt" zu haben, die normale " full screen position, die ich animieren wollen.
In die Arbeit um oben habe ich ausdrücklich den Standort der Darstellung view controller zurück, wo es sein sollte am Anfang der animation mit !!!Diese Zeile sollte nicht erforderlich sein!!!. Dies scheint zu funktionieren auf dem Gerät mit der aktuellen iOS-version 7. Aber auf den simulator, der controller ist sichtbar in der ausgeglichenen position für mindestens ein frame.
Ich bin misstrauisch, ich mache etwas anderes falsch, und das werde ich bekommen in Schwierigkeiten mit meinem workaround nur Maskierung ein weiteres problem.
Irgendwelche Ideen was Los ist??? Danke!
InformationsquelleAutor der Frage Benjohn | 2014-06-06
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ein paar potentielle Fallstricke, die mit der Entlassung des Modal vorgestellt view-Controller mit übergangs-Animationen:
Angesichts all dieser, ich denke, das sollte funktionieren:
InformationsquelleAutor der Antwort John Scalo
Zunächst, ich dachte über die Verwendung
CATransition
zu haben, der übergangs-Effekt, wennpresentViewController:animated:completion:
unddismissViewControllerAnimated:completion:
einen View-Controller. Aber Sie wollen zeigen, ein Teil der View-Controller bei der Einstellung-Ansicht-Controller vorgestellt wird, dann denke ichCATransition
würde nicht helfen, weil Sie nicht die volle Kontrolle darüber, wie weit Sie wollen, bewegen Sie den View-Controller.Ich denke, der einfachste Weg ist es, eine single-View-Controller mit zwei full-screen-UIView. Für die ersten UIView (View Controller ist der Ansicht, dass, selbst.Ansicht), können Sie das layout der Einstellung, und auf der zweiten UIView, es ist die normale Ansicht. In der ViewDidLoad-fügen Sie die 2. Sicht mit
[self.view addSubview:2ndView];
. Später, wenn Sie möchten, präsentieren die Einstellung anzuzeigen, die Sie tun können,dann Mach den anderen Weg zu bringen, die 2ndView zurück.
InformationsquelleAutor der Antwort Dino Tw