2

私が収集できることから、View Controller アニメーションを Segue トランジションとして使用することはできません。現在、View Controller 間のアニメーション化されたトランジションを作成する既存のプロジェクトに、一連の View Controller アニメーションがあります。例えば:

モーダル アニメーション .h ファイル:

//
//  MVModalDismissAnimation.h
//

#import "MVBaseAnimation.h"

@interface MVModalAnimation : MVBaseAnimation

@end

モーダル アニメーション .m ファイル:

//
//  MVModalDismissAnimation.m
//

#import "MVModalAnimation.h"

@implementation MVModalAnimation {
UIView *_coverView;
NSArray *_constraints;
}

#pragma mark - Animated Transitioning

-(void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
//The view controller's view that is presenting the modal view
UIView *containerView = [transitionContext containerView];

if (self.type == AnimationTypePresent) {
    //The modal view itself
    UIView *modalView = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey].view;

    //View to darken the area behind the modal view
    if (!_coverView) {
        _coverView = [[UIView alloc] initWithFrame:containerView.frame];
        _coverView.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.6];
        _coverView.alpha = 0.0;
    } else _coverView.frame = containerView.frame;
    [containerView addSubview:_coverView];

    //Using autolayout to position the modal view
    modalView.translatesAutoresizingMaskIntoConstraints = NO;
    [containerView addSubview:modalView];
    NSDictionary *views = NSDictionaryOfVariableBindings(containerView, modalView);
    _constraints = [[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-30-[modalView]-30-|" options:0 metrics:nil views:views] arrayByAddingObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-30-[modalView]-30-|" options:0 metrics:nil views:views]];
    [containerView addConstraints:_constraints];

    //Move off of the screen so we can slide it up
    CGRect endFrame = modalView.frame;
    modalView.frame = CGRectMake(endFrame.origin.x, containerView.frame.size.height, endFrame.size.width, endFrame.size.height);
    [containerView bringSubviewToFront:modalView];

    //Animate using spring animation
    [UIView animateWithDuration:[self transitionDuration:transitionContext] delay:0.0 usingSpringWithDamping:0.8 initialSpringVelocity:1.0 options:0 animations:^{
        modalView.frame = endFrame;
        _coverView.alpha = 1.0;
    } completion:^(BOOL finished) {
        [transitionContext completeTransition:YES];
    }];
} else if (self.type == AnimationTypeDismiss) {
    //The modal view itself
    UIView *modalView = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey].view;

    //Grab a snapshot of the modal view for animating
    UIView *snapshot = [modalView snapshotViewAfterScreenUpdates:NO];
    snapshot.frame = modalView.frame;
    [containerView addSubview:snapshot];
    [containerView bringSubviewToFront:snapshot];
    [modalView removeFromSuperview];

    //Set the snapshot's anchor point for CG transform
    CGRect originalFrame = snapshot.frame;
    snapshot.layer.anchorPoint = CGPointMake(0.0, 1.0);
    snapshot.frame = originalFrame;

    //Animate using keyframe animation
    [UIView animateKeyframesWithDuration:[self transitionDuration:transitionContext] delay:0.0 options:0 animations:^{
        [UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:0.15 animations:^{
            //90 degrees (clockwise)
            snapshot.transform = CGAffineTransformMakeRotation(M_PI * -1.5);
        }];
        [UIView addKeyframeWithRelativeStartTime:0.15 relativeDuration:0.10 animations:^{
            //180 degrees
            snapshot.transform = CGAffineTransformMakeRotation(M_PI * 1.0);
        }];
        [UIView addKeyframeWithRelativeStartTime:0.25 relativeDuration:0.20 animations:^{
            //Swing past, ~225 degrees
            snapshot.transform = CGAffineTransformMakeRotation(M_PI * 1.3);
        }];
        [UIView addKeyframeWithRelativeStartTime:0.45 relativeDuration:0.20 animations:^{
            //Swing back, ~140 degrees
            snapshot.transform = CGAffineTransformMakeRotation(M_PI * 0.8);
        }];
        [UIView addKeyframeWithRelativeStartTime:0.65 relativeDuration:0.35 animations:^{
            //Spin and fall off the corner
            //Fade out the cover view since it is the last step
            CGAffineTransform shift = CGAffineTransformMakeTranslation(180.0, 0.0);
            CGAffineTransform rotate = CGAffineTransformMakeRotation(M_PI * 0.3);
            snapshot.transform = CGAffineTransformConcat(shift, rotate);
            _coverView.alpha = 0.0;
        }];
    } completion:^(BOOL finished) {
        [_coverView removeFromSuperview];
        [containerView removeConstraints:_constraints];
        [transitionContext completeTransition:YES];
    }];
}
}

-(NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext {
if (self.type == AnimationTypePresent) return 1.0;
else if (self.type == AnimationTypeDismiss) return 1.75;
else return [super transitionDuration:transitionContext];
}

@end

上記は、モーダルView Controllerを下から上にスライドさせます。

これをストーリーボードとセグエで動作するように変換したいと思います。

変換したい他の 4 種類のアニメーションがあるので、上記のクラスをセグエ トランジションで動作させる簡単な方法はありますか?

4

2 に答える 2

2

AUIStoryBoardSegueは、遷移アニメーションをラップし、魔法のようにストーリーボードに表示されるオブジェクトです。カスタム セグエでカスタム ビュー コントローラー遷移アニメーションを使用すること可能です。

(上記のように) プロトコルを実装するカスタム アニメーター オブジェクトが既にあると仮定するとUIViewControllerAnimatedTransitioning、次のことを行う必要があります。

  1. カスタム セグエを作成してアニメーターをラップし、サブクラス化してストーリーボードで使用できるようにしますUIStoryBoardSegue

    @interface MYCustomAnimationSegue : UIStoryboardSegue<UIViewControllerTransitioningDelegate>
    @end
    
  2. メソッドを実装しperform:、transitioningdelegate (モーダル トランジションの場合) または navigationController のデリゲート (プッシュまたは置換トランジションの場合) として設定します。

    @implementation MYCustomAnimationSegue
    
    - (void)perform {
        UIViewController *sourceVC = (UIViewController *)self.sourceViewController;
        UIViewController *destVC = (UIViewController *)self.destinationViewController;
    
        //Set the transitioningdelegate (for a modal transition)
        destVC.transitioningDelegate = self;
    
        //strong property, necessary to retain the Segue after perform: is finished
        //only needed if you want the customSegue to be the transitioningDelegate
        sourceVC.customSegue = self;
    
        //Set the modalPresentationStyle
        if (&UITransitionContextFromViewKey) {
            //iOS8
            destVC.modalPresentationStyle = UIModalPresentationFullScreen;
        } else {
            //iOS7
            destVC.modalPresentationStyle = UIModalPresentationCustom;
        }
    
        //Call the presentation
        [sourceVC presentViewController:destVC animated:YES completion:^{
            //release ourselves again
            sourceVC.customSegue = nil;
        }];
    }
    
    @end
    
  3. UIViewControllerTransitioningDelegateカスタム アニメーター オブジェクトを返すメソッドを実装する

    - (id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source {
    
        return [[MyCustomAnimator alloc] init];
    }
    
  4. カスタム セグエ クラスは、あるビュー コントローラーから別のビュー コントローラーに ctrl キーを押しながらドラッグすると、Interface Builder に表示されるようになりました。 ここに画像の説明を入力

興奮する前に、注意点が 1 つあります。これは一方向にしか機能しません。Unwind Segues で機能させるには、viewcontroller クラスに必要なメソッドを実装する必要があります。

于 2014-12-11T13:19:17.793 に答える