【问题标题】:Remove custom UIStoryboardSegue with custom animation使用自定义动画删除自定义 UIStoryboardSegue
【发布时间】:2012-10-26 08:12:05
【问题描述】:

我已经看到了几个如何使用自定义动画呈现自定义UIStoryboardSegue 的示例。基本上,您将UIStoryBoardSegue 子类化并覆盖“执行”方法,即像这样:

- (void)perform
{
    UIViewController *source = self.sourceViewController;
    UIViewController *destination = self.destinationViewController;

    // Create a UIImage with the contents of the destination
    UIGraphicsBeginImageContext(destination.view.bounds.size);
    [destination.view.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *destinationImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    // Add this image as a subview to the tab bar controller
    UIImageView *destinationImageView = [[UIImageView alloc] initWithImage:destinationImage];
    [source.parentViewController.view addSubview:destinationImageView];

    // Scale the image down and rotate it 180 degrees (upside down)
    CGAffineTransform scaleTransform = CGAffineTransformMakeScale(0.1, 0.1);
    CGAffineTransform rotateTransform = CGAffineTransformMakeRotation(M_PI);
    destinationImageView.transform = CGAffineTransformConcat(scaleTransform, rotateTransform);

    // Move the image outside the visible area
    CGPoint oldCenter = destinationImageView.center;
    CGPoint newCenter = CGPointMake(oldCenter.x - destinationImageView.bounds.size.width, oldCenter.y);
    destinationImageView.center = newCenter;

    // Start the animation
    [UIView animateWithDuration:0.5f
                          delay:0
                        options:UIViewAnimationOptionCurveEaseOut
                     animations:^(void) {
                         destinationImageView.transform = CGAffineTransformIdentity;
                         destinationImageView.center = oldCenter;
                     }
                     completion: ^(BOOL done) {
                         // Remove the image as we no longer need it
                         [destinationImageView removeFromSuperview];

                         // Properly present the new screen
                         [source presentViewController:destination animated:NO completion:nil];
                     }];
}

但是如果我想要自定义动画同时从屏幕上移除 Segue,我该怎么办?覆盖这个类中的一些其他方法并调用它。或者在我叫“dismissViewController”的地方做动画,感觉不合逻辑?

不胜感激,

阿尔乔姆

【问题讨论】:

    标签: iphone ios uistoryboard


    【解决方案1】:

    要更改dismissViewController 上的动画,您必须将presentedViewController 上的modalTransitionStyle 设置为UIModalTransitionStyle

    - (IBAction)dismiss:(id)sender {
        self.presentingViewController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
        [self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
    }
    

    【讨论】:

    • tnx 的答案,但我问我应该创建动画的地方。当我呈现一个视图(模态或推送)时,我在 perform 方法中执行它,但是当我想解除它时,我通常在父代理中调用dismissViewController,它是在那里创建动画的合适位置吗?
    • 好的,现在我看到你的意见了。但是在 Segue 子类中设置当前动画并在 VC 类中关闭动画是否是一种好习惯,您怎么看?
    • 据我所知,关闭 viewController 时没有其他可能性。如果需要,您可以使用相同的技术来呈现视图控制器。缺点是没有做一些技巧就没有自定义动画的选项。
    • 但我认为对于自定义动画,您可以使用与我的示例代码相同的技巧。没试过,但我认为应该可以。
    【解决方案2】:

    为避免任何转换,这是我成功使用的代码(顺便说一句,Subview has wrong orientation 的答案):

    #include <QuartzCore/QuartzCore.h>
    
    @implementation HorizontalSwipingSegue
    
    - (void) perform {
        UIViewController *source = self.sourceViewController;
        UIViewController *destination = self.destinationViewController;    
        UIView *sourceView = source.view;
        UIView *destinationView = destination.view;
    
        // Create a UIImageView with the contents of the source
        UIGraphicsBeginImageContext(sourceView.bounds.size);
        [sourceView.layer renderInContext:UIGraphicsGetCurrentContext()];
        UIImage *sourceImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        UIImageView *sourceImageView = [[UIImageView alloc] initWithImage:sourceImage];
    
        [[self sourceViewController] presentViewController:[self destinationViewController] animated:NO completion:NULL];
    
        CGPoint destinationViewFinalCenter = CGPointMake(destinationView.center.x, destinationView.center.y);
        CGFloat deltaX = destinationView.frame.size.width;
        CGFloat deltaY = destinationView.frame.size.height;
    
        switch (((UIViewController *)self.sourceViewController).interfaceOrientation) {
           case UIDeviceOrientationPortrait:
                destinationView.center = CGPointMake(destinationView.center.x - deltaX, destinationView.center.y);                
                sourceImageView.center = CGPointMake(sourceImageView.center.x + deltaX, sourceImageView.center.y);
                break;
            case UIDeviceOrientationPortraitUpsideDown:
                destinationView.center = CGPointMake(destinationView.center.x + deltaX, destinationView.center.y);
                sourceImageView.center = CGPointMake(sourceImageView.center.x + deltaX, sourceImageView.center.y);
                break;
            case UIDeviceOrientationLandscapeLeft:
                destinationView.center = CGPointMake(destinationView.center.x, destinationView.center.y - deltaY);                
                sourceImageView.center = CGPointMake(sourceImageView.center.x + deltaY, sourceImageView.center.y);
                break;
            case UIDeviceOrientationLandscapeRight:
                destinationView.center = CGPointMake(destinationView.center.x, destinationView.center.y + deltaY);
                sourceImageView.center = CGPointMake(sourceImageView.center.x + deltaY, sourceImageView.center.y);
                break;
        }
    
        [destinationView addSubview:sourceImageView];
    
        [UIView animateWithDuration:0.6f
                         animations:^{
                             destinationView.center = destinationViewFinalCenter; 
                         }
                         completion:^(BOOL finished){
                             [sourceImageView removeFromSuperview];
                         }];
    }
    
    @end
    

    【讨论】:

    • 谢谢你的回答,我想我做的有点类似
    猜你喜欢
    • 1970-01-01
    • 2014-11-26
    • 2012-07-02
    • 1970-01-01
    • 1970-01-01
    • 2014-11-10
    • 1970-01-01
    • 2015-09-30
    • 1970-01-01
    相关资源
    最近更新 更多