Vraag Hoe zou ik beginnen met het repliceren van de overgang van de aangepaste weergavecontroller die Apple als standaard gebruikt in iOS 7?


Met behulp van de overgangen van de aangepaste view controller van iOS 7 wil ik een visueel effect bereiken vergelijkbaar met de standaard view controller-overgang van Apple in iOS 7.

(De plek waar je kunt schuiven om een ​​view-controller uit de stapel te laten springen door deze van links naar rechts te schuiven, waar de bovenaanzicht-controller met een schaduw van de bovenkant van de andere glijdt en de navigatiebalk verschuift.)

enter image description here

Ik heb echter veel moeite om dit te implementeren. Het merendeel van de zelfstudies over controllers voor aangepaste weergaven gaat met heel andere effecten dan de standaard, om te laten zien wat de API kan, maar ik wil deze repliceren.

In mijn subklasse voor implementatie <UIViewControllerAnimatedTransitioning> Ik heb de volgende code voor de interactieve animatie:

- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
    UIViewController* toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    UIViewController* fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];

    [transitionContext.containerView addSubview:toViewController.view];
    [transitionContext.containerView addSubview:fromViewController.view];

    fromViewController.view.layer.shadowOffset = CGSizeMake(0.0, 0.0);
    fromViewController.view.layer.shadowColor = [UIColor blackColor].CGColor;
    fromViewController.view.layer.shadowRadius = 5.0;
    fromViewController.view.layer.shadowOpacity = 0.5;

    [UIView animateWithDuration:[self transitionDuration:transitionContext] delay:0.0 options:UIViewAnimationOptionCurveLinear animations:^{
        CGRect newFrame = fromViewController.view.frame;
        newFrame.origin.x = CGRectGetWidth(fromViewController.view.bounds);

        fromViewController.view.frame = newFrame;
    } completion:^(BOOL finished) {
        [transitionContext completeTransition:!transitionContext.transitionWasCancelled];
    }];
}

Door de schaduwcode blijft het echter enorm achter (zelfs als ik het nieuwe gebruik snapshot methoden) en ik kan er niet achter komen hoe je de navigatiebalk helemaal kunt manipuleren.

Heeft iemand geprobeerd om iets soortgelijks te doen en kunnen we voorbeeldcode geven?

Voorbeeldproject voor testen als u wilt: http://cl.ly/0B3q1b390x0D

Met dank aan objc.io voor de basiscode.


18
2018-03-25 03:14


oorsprong


antwoorden:


Het instellen van shadowPath verhoogt de prestaties van deze schaduw enorm.

Voeg dit gewoon toe in uw animateTransition: methode nadat u de schaduweigenschappen hebt ingesteld. Dit vermijdt de dure offscreen-rendering die schaduw normaal veroorzaakt.

[fromViewController.view.layer setShadowPath:[[UIBezierPath bezierPathWithRect:fromViewController.view.bounds] CGPath]];

Ik heb je voorbeeldproject gedownload en dat heb ik gedaan, het stotteren is nu helemaal weg.

Wat info over wat dit doet hier.

BEWERK:

Het antwoord over het manipuleren van de navigatiebalkanimatie is dat het niet lijkt alsof je kunt. Om dit te doen, moet je je eigen NavigationController-klasse helemaal opnieuw implementeren. De overgangsanimatie voor de navigatiebalk wordt intern uitgevoerd door de containerzichtcontroller (de UINavigationController) en is nergens in de code opgedoken.


2
2018-04-01 03:49



Kijk even naar ECSlidingViewController Ik heb het een paar keer gebruikt, als je begrijpt hoe het werkt, kun je gemakkelijk iets soortgelijks implementeren.

Als je het wiel opnieuw wilt uitvinden, heeft mijn antwoord geen zin, sorry.


0
2018-03-28 01:40



Ik maak het effect met Dynamics Ik maak mijn eigen ViewController-subklasse met de volgende methoden.

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil forMultipleDirections:(BOOL)isTwoDirections;
- (void)addVelocityForGesture:(UIPanGestureRecognizer *)recognizer;
- (UIDynamicItemBehavior*) itemBehaviourForView;

Daarna heb ik fysica en een gebarenherkenner toegevoegd om het paniekgebaar af te handelen. om het in de top te laten lijken, voeg je gewoon een schaduwverschuiving toe.

_animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.parentViewController.view];
        _gravity = [[UIGravityBehavior alloc] init];
        _gravity.gravityDirection = CGVectorMake(-1.5, 0);
        [_animator addBehavior:_gravity];

        UICollisionBehavior *collision = [[UICollisionBehavior alloc] initWithItems:@[self.view]];
        [collision addBoundaryWithIdentifier:@1 fromPoint:CGPointMake(0, 0) toPoint:CGPointMake(0, self.parentViewController.view.frame.size.height)];
        [_animator addBehavior:collision];
        [_gravity addItem:self.view];

        UIDynamicItemBehavior *itemBehavior = [[UIDynamicItemBehavior alloc] initWithItems:@[self.view]];
        [itemBehavior setElasticity:0.2];
        [_animator addBehavior:itemBehavior];

Je hebt meer methoden nodig om velocity toe te voegen volgens de richting van de panning, dan zul je een punt moeten vinden waar je de childViewController wilt sluiten of verbergen, afhankelijk van je use case, enz. ... Ik deed het en het werkt behoorlijk goed voor mij, omdat het Dynamics gebruikt, ondersteunt het gewoon iOS7 +


0
2018-04-01 20:54