IOS / Objective-C: возможно ли использовать пользовательский переход в модальном переходе в отсутствие перехода от раскадровки? - PullRequest
0 голосов
/ 19 сентября 2018

У меня есть два контроллера вида в раскадровке, и я хотел бы представить второй из первого модально, используя пользовательский нисходящий переход (противоположность обычной вертикальной обложке).

У меня есть переход с подклассамикод, который, я надеюсь, будет работать.

Однако в этом случае я не перетаскивал переход в раскадровке с одного контроллера представления на другой.Вместо этого я обрабатываю модальное представление в коде.

Возможно ли вызвать пользовательский переход, если вы вызываете второй контроллер представления в коде?Или у вас должен быть фактический переход в раскадровке, которому вы назначаете пользовательский класс?

Если возможно в коде, куда бы вы поместили код?

Вот код, который я использую дляпредставить модальный View Controller

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"chat" bundle:nil];
    UIViewController *myVC = [storyboard instantiateViewControllerWithIdentifier:@"chatVC"];
    [(UINavigationController*)self.window.rootViewController presentViewController:myVC animated:NO completion:nil];

1 Ответ

0 голосов
/ 19 сентября 2018

Кажется, что вы пытаетесь выполнить множество пользовательских переходов анимации в своем приложении, поэтому я рекомендую вам использовать собственные классы аниматоров, а не пытаться создавать собственные переходы.Как и в примере, который я опубликовал на предыдущем вопросе (ссылка которого приведена в моем комментарии выше), вы захотите настроить своего рода делегат (в предыдущем примере это был UINavigationControllerDelegate) для обработки определения, какие пользовательские классы аниматоров использовать дляпредставление / отклонение (в предыдущем примере это было для нажатия / выталкивания) определенных контроллеров представления:

Вот пример того, что я имею в виду:

ViewController.m (используя это как UIViewControllerTransitioningDelegate):

#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 (Custom Down Animator):

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface SlideDownAnimator : NSObject <UIViewControllerAnimatedTransitioning>

@end

NS_ASSUME_NONNULL_END

SlideDownAnimator.m:

#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:

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface SlideUpAnimator : NSObject <UIViewControllerAnimatedTransitioning>

@end

NS_ASSUME_NONNULL_END

SlideUpAnimator.m:

#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

Редактировать:

Что касается вашего второго вопроса относительно того, где поместить это в ваш собственный код: это сильно зависит от структуры вашего приложения, поэтому, не видя больше контекста классов, на которых вы пытаетесь их использовать,Трудно сказать лучший подход.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...