首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >IOS/Objective-C:在缺少Storyboard Segue的情况下,是否可以在模式转换中使用自定义Segue?

IOS/Objective-C:在缺少Storyboard Segue的情况下,是否可以在模式转换中使用自定义Segue?
EN

Stack Overflow用户
提问于 2018-09-19 05:37:31
回答 1查看 280关注 0票数 1

我在Storyboard中有两个View控制器,我想使用自定义的向下分段(与常规的封面垂直相反)从第一个开始呈现第二个控制器。

我已经用我希望能工作的代码对故事板segue进行了子类化。

但是,在本例中,我没有将Storyboard中的段从一个视图控制器拖动到另一个视图控制器。相反,我在代码中处理Modal表示。

如果在代码中调用第二个视图控制器,是否可以调用自定义segue?或者你必须在你分配自定义类的故事板中有一个实际的段?

如果可能的话,你会把代码放在哪里?

下面是我用来呈现模式视图控制器的代码

代码语言:javascript
复制
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"chat" bundle:nil];
    UIViewController *myVC = [storyboard instantiateViewControllerWithIdentifier:@"chatVC"];
    [(UINavigationController*)self.window.rootViewController presentViewController:myVC animated:NO completion:nil];
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-09-19 08:43:49

看起来你正试图在你的应用程序中完成许多自定义动画过渡,所以我建议你使用你自己的动画制作类,而不是尝试创建自定义segues。类似于我之前发布给你的例子(链接在我上面的评论中),你需要设置某种类型的委托(在上一个例子中是一个UINavigationControllerDelegate)来决定使用哪些自定义动画制作类来呈现/取消(在上一个例子中是为了推送/弹出)某些视图控制器:

下面是我的意思的一个例子:

ViewController.m (将其用作UIViewControllerTransitioningDelegate):

代码语言:javascript
复制
#import "ViewController.h"
#import "SlideDownAnimator.h"
#import "SlideUpAnimator.h"

@interface ViewController () <UIViewControllerTransitioningDelegate>

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

- (IBAction)_presentCustomDownward:(id)sender {
    // setup a fake view controller we're going to present
    UIViewController *fakeSecondViewController = [[UIViewController alloc] init];
    fakeSecondViewController.view.backgroundColor = [UIColor blueColor];
    // make sure to set the desination view controller's transition delegate
    // this doesn't have to be set to self here, you can set it anything that will implement: UIViewControllerTransitioningDelegate
    fakeSecondViewController.transitioningDelegate = self;
    // when we call present on the view controller it asks the transitioningDelegate for an animation coordinator which we're going to provide below
    [self.navigationController presentViewController:fakeSecondViewController animated:YES completion:^{
        // dismis after a couple seconds to show what the custom dismiss looks like (obviously this is just for the example code, you will handle your own dismissal)
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [self.navigationController dismissViewControllerAnimated:YES completion:nil];
        });
    }];
}

// delegate call for presentation
- (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented
                                                                  presentingController:(UIViewController *)presenting
                                                                      sourceController:(UIViewController *)source {

    // return our own custom Animator class (which adheres to UIViewControllerAnimatedTransitioning protocol)
    return [[SlideDownAnimator alloc] init];
}

// delegate call for dismissal
- (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed {
    // return our own custom Animator class (which adheres to UIViewControllerAnimatedTransitioning protocol)
    return [[SlideUpAnimator alloc] init];
}

SlideDownAnimator.h (自定义向下动画):

代码语言:javascript
复制
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface SlideDownAnimator : NSObject <UIViewControllerAnimatedTransitioning>

@end

NS_ASSUME_NONNULL_END

SlideDownAnimator.m:

代码语言:javascript
复制
#import "SlideDownAnimator.h"

@implementation SlideDownAnimator

- (NSTimeInterval)transitionDuration:(nullable id<UIViewControllerContextTransitioning>)transitionContext {
    return 0.4f;
}

- (void)animateTransition:(nonnull id<UIViewControllerContextTransitioning>)transitionContext {
    // grab the toViewController (the vc being presented)
    UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    // manually add it to our container view
    [[transitionContext containerView] addSubview:toViewController.view];
    // get the frame so we can do some of our own animations on it
    CGRect toVCFrame = toViewController.view.frame;
    CGFloat toVCHeight = toVCFrame.size.height;
    // offset the y coordiante by it's height so that it's completely above our current screen
    toVCFrame.origin.y = -toVCHeight;
    // set the initial frame so it's above our screen
    [toViewController.view setFrame:toVCFrame];

    [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
        // animate the y position to 0 so it slides down
        CGRect finalVCFrame = toViewController.view.frame;
        finalVCFrame.origin.y = 0;
        [toViewController.view setFrame:finalVCFrame];
    } completion:^(BOOL finished) {
        // make sure to call this so we'll call back to our presentViewdController's completion block
        [transitionContext completeTransition:![transitionContext transitionWasCancelled]];
    }];
}

@end

我的猜测是,你也会想要一个自定义的上滑动画,所以你需要多一个实现自定义过渡的动画师:

SlideUpAnimator.h:

代码语言:javascript
复制
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface SlideUpAnimator : NSObject <UIViewControllerAnimatedTransitioning>

@end

NS_ASSUME_NONNULL_END

SlideUpAnimator.m:

代码语言:javascript
复制
#import "SlideUpAnimator.h"

@implementation SlideUpAnimator

- (NSTimeInterval)transitionDuration:(nullable id<UIViewControllerContextTransitioning>)transitionContext {
    return 0.4f;

}

- (void)animateTransition:(nonnull id<UIViewControllerContextTransitioning>)transitionContext {
    // grab our fromViewController (the vc being dismissed)
    UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    // and our toViewController (the vc that will be shown after dismissal)
    UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    // add our toViewController as a subview of our container view (make sure to add it beneath the dismissing view controller so we can let it complete it's animation first)
    [[transitionContext containerView] insertSubview:toViewController.view belowSubview:fromViewController.view];
    [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
        // push the view back up above the screen
        CGRect fromVCFrame = fromViewController.view.frame;
        fromVCFrame.origin.y = -fromVCFrame.size.height;
        [fromViewController.view setFrame:fromVCFrame];
    } completion:^(BOOL finished) {
        // make sure to call this so we'll call back to our presentViewdController's completion block
        [transitionContext completeTransition:![transitionContext transitionWasCancelled]];
    }];

}

@end

完整的动画最终将如下所示:

Custom_Downward_Animation_Transition

这里有一些对你有帮助的链接:

https://developer.apple.com/library/archive/featuredarticles/ViewControllerPGforiPhoneOS/CustomizingtheTransitionAnimations.html

https://developer.apple.com/documentation/uikit/uiviewcontrollertransitioningdelegate?language=objc

https://developer.apple.com/documentation/uikit/uiviewcontrolleranimatedtransitioning?language=objc

编辑:

至于在自己的代码中放在哪里的其他问题:这高度依赖于您的应用程序结构,所以如果没有看到您试图使用它们的类的更多上下文,很难说最好的方法。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52394928

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档