gpt4 book ai didi

uistoryboard - 如何将 View Controller 动画过渡转换为 Segue 动画过渡

转载 作者:行者123 更新时间:2023-12-02 21:44:35 25 4
gpt4 key购买 nike

据我所知,不可能使用 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

上面的代码将模态视图 Controller 从底部向上滑动。

我现在想将其转换为与 Storyboard和转场一起使用。

我想要转换四种其他类型的动画,那么有没有一种简单的方法可以使上述类与 segue 过渡一起使用?

最佳答案

我可能误解了你的意思,但这里有一个与自定义转场一起使用的转场示例...

@interface TestSegue : UIStoryboardSegue

@end

@implementation TestSegue
-(void)perform
{
UIView *sv = ((UIViewController *)self.sourceViewController).view;
UIView *dv = ((UIViewController *)self.destinationViewController).view;

UIWindow *window = [[[UIApplication sharedApplication] delegate] window];
[window insertSubview:dv aboveSubview:sv];
[dv enterRight:0.1 then:^
{
[self.sourceViewController
presentViewController:self.destinationViewController
animated:NO completion:nil];
}];

}
@end

注意我的例程“enterRight:”只是 UIView 上的一个类别

使用自定义转场的便捷教程... http://www.bencz.com/hacks/2014/02/07/custom-ios-segues-in-xcode-5/

我在UIView上的类别的一个例子,这只是 View 的移动动画......

请注意您确实并且必须有一个“after” block ,以便能够在自定义转场中使用它。

注意 - 这里有一个关于将 block 作为属性的完整解释,供任何不熟悉该内容的人阅读 https://stackoverflow.com/a/20760583/294884

-(void)enterRight:(float)delay then:(void(^)(void))after
{
CGPoint moveTo = self.center;
CGPoint moveFrom = self.center;

CGFloat simpleOffscreen = [UIScreen mainScreen].bounds.size.width;

moveFrom.x = moveFrom.x + simpleOffscreen;

self.center = moveFrom;
self.hidden = NO;

[UIView animateWithDuration:0.5
delay:delay
usingSpringWithDamping:0.4
initialSpringVelocity:0.1
options:0
animations:^
{
self.center = moveTo;
}
completion:^(BOOL finished)
{
if (after) after();
}
];
}

所以,如果您从类别开始......

在 Xcode 中单击添加新文件,然后选择类别。有两个盒子。

所以,一个类别是“在”某个类上的。在本例中,它位于“UIView”上。在底部框中,输入 UIView。

在顶部框中,只需输入一些方便的简短名称即可。事实上,使用的名称并不重要。例如,典型的选择是“实用程序”、“助手”、“技巧”、“动画”或类似选项。

现在转到 .h 文件并添加此内容

-(void)enterRight:(float)delay then:(void(^)(void))after;

现在转到 .m 文件并添加上面的函数。您现在可以在代码中的任何位置使用该函数。这是使用它的示例

-(void)viewDidLoad
{
[super viewDidLoad];
[PFAnalytics trackEvent:@"harvestFBPage"];

[self.slideOff showMessage:@"Next step..."];
[self.slideOff enterRight:0.0 then:nil];
}

因此,对于任何 UIView,您都可以使用 [anyUIView EnterRight...]; 这很棒。在示例中 self.slideOff 是一个 UIView。

请注意,在该示例中,“之后无需执行任何操作”。这是一个“事后要做的事情”的示例。

-(void)viewDidLoad
{
[super viewDidLoad];
[PFAnalytics trackEvent:@"harvestFBPage"];

[self.slideOff showMessage:@"Next step..."];
[self.slideOff enterRight:0.0 then:^
{
NSLog(@"do this afterwards!");
self.slideOff.alpha = 0.5;
etc;
etc;
}];
}

希望对分类有所帮助。别忘了去这里https://stackoverflow.com/a/20760583/294884如果您不太熟悉 block 作为参数。


回到手头的问题。

在自定义转场中不可能使用任何类型的动画,除非它包含“完成后运行此 block ”的概念,因为您必须向presentViewController发送消息:(带有动画:NO)仅当您完成时

假设我已经理解了你的问题,这就是关键。

关于uistoryboard - 如何将 View Controller 动画过渡转换为 Segue 动画过渡,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19755208/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com