模仿 UIAlertController 显示动画

Posted

技术标签:

【中文标题】模仿 UIAlertController 显示动画【英文标题】:Mimic UIAlertController show animation 【发布时间】:2015-12-09 15:28:39 【问题描述】:

所以我创建了自己的自定义 UIView,它看起来像一个警报,现在我想添加显示和隐藏动画。

我想为 AlertController 模仿 Apple 的默认动画。解雇是一个简单的淡入淡出动画,但我不知道如何表达显示动画,它几乎就像淡入淡出混合了收缩。

如果有人知道如何重新创建它,我将不胜感激。

这是我的最终结果:

这个 gif 不公平,但它与 UIAlertControllers 动画非常相似。

-(void)alerterShowAnimation 
    self.alpha = 0;
    self.hidden = NO;
    self.transform = CGAffineTransformMakeScale(1.2, 1.2);
    [UIView animateWithDuration:0.3 animations:^
        self.alpha = 1.0f;
        self.containerView.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.5];
    ];
    [UIView animateWithDuration:0.2 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^
        self.transform = CGAffineTransformIdentity;
     completion:nil];

【问题讨论】:

到目前为止你尝试过什么?尝试一下,然后回到这里,就您在此过程中遇到的问题提出具体问题。 “为我编写代码”不是一个可接受的问题。 @Stonz2...我已经添加了到目前为止我尝试过的代码。 尝试使用Core Animation 【参考方案1】:

尝试使用核心动画,而不是UIView 动画。

我创建了一个简单的灰色背景UIView,并在下面添加了动画:

- (void)addAlertPopUpAnimationWithBeginTime:(CFTimeInterval)beginTime andFillMode:(NSString *)fillMode andRemoveOnCompletion:(BOOL)removedOnCompletion completion:(void (^)(BOOL finished))completionBlock

    CAMediaTimingFunction *linearTiming = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];

    if (completionBlock)
    
        CABasicAnimation *representativeAnimation = [CABasicAnimation animationWithKeyPath:@"not.a.real.key"];
        representativeAnimation.duration = 0.200;
        representativeAnimation.delegate = self;
        [self.layer addAnimation:representativeAnimation forKey:@"AlertPopUp"];

    

    CAKeyframeAnimation *proPicOpacityAnimation = [CAKeyframeAnimation animationWithKeyPath:@"opacity"];
    proPicOpacityAnimation.duration = 0.200;
    proPicOpacityAnimation.values = @[@(0.000), @(0.525), @(1.000)];
    proPicOpacityAnimation.keyTimes = @[@(0.000), @(0.500), @(1.000)];
    proPicOpacityAnimation.timingFunctions = @[linearTiming, linearTiming];
    proPicOpacityAnimation.beginTime = beginTime;
    proPicOpacityAnimation.fillMode = fillMode;
    proPicOpacityAnimation.removedOnCompletion = removedOnCompletion;
    [[self layer] addAnimation:proPicOpacityAnimation forKey:@"alertPopUp_Opacity"];

    CAKeyframeAnimation *proPicScaleXAnimation = [CAKeyframeAnimation animationWithKeyPath:@"transform.scale.x"];
    proPicScaleXAnimation.duration = 0.200;
    proPicScaleXAnimation.values = @[@(0.304), @(0.345), @(0.300)];
    proPicScaleXAnimation.keyTimes = @[@(0.000), @(0.500), @(1.000)];
    proPicScaleXAnimation.timingFunctions = @[linearTiming, linearTiming];
    proPicScaleXAnimation.beginTime = beginTime;
    proPicScaleXAnimation.fillMode = fillMode;
    proPicScaleXAnimation.removedOnCompletion = removedOnCompletion;
    [[self layer] addAnimation:proPicScaleXAnimation forKey:@"alertPopUp_ScaleX"];

    CAKeyframeAnimation *proPicScaleYAnimation = [CAKeyframeAnimation animationWithKeyPath:@"transform.scale.y"];
    proPicScaleYAnimation.duration = 0.200;
    proPicScaleYAnimation.values = @[@(0.381), @(0.435), @(0.389)];
    proPicScaleYAnimation.keyTimes = @[@(0.000), @(0.500), @(1.000)];
    proPicScaleYAnimation.timingFunctions = @[linearTiming, linearTiming];
    proPicScaleYAnimation.beginTime = beginTime;
    proPicScaleYAnimation.fillMode = fillMode;
    proPicScaleYAnimation.removedOnCompletion = removedOnCompletion;
    [[self layer] addAnimation:proPicScaleYAnimation forKey:@"alertPopUp_ScaleY"];

    CAKeyframeAnimation *proPicTranslationXAnimation = [CAKeyframeAnimation animationWithKeyPath:@"transform.translation.x"];
    proPicTranslationXAnimation.duration = 0.200;
    proPicTranslationXAnimation.values = @[@(0.000), @(0.194), @(0.683)];
    proPicTranslationXAnimation.keyTimes = @[@(0.000), @(0.500), @(1.000)];
    proPicTranslationXAnimation.timingFunctions = @[linearTiming, linearTiming];
    proPicTranslationXAnimation.beginTime = beginTime;
    proPicTranslationXAnimation.fillMode = fillMode;
    proPicTranslationXAnimation.removedOnCompletion = removedOnCompletion;
    [[self layer] addAnimation:proPicTranslationXAnimation forKey:@"alertPopUp_TranslationX"];

    CAKeyframeAnimation *proPicTranslationYAnimation = [CAKeyframeAnimation animationWithKeyPath:@"transform.translation.y"];
    proPicTranslationYAnimation.duration = 0.200;
    proPicTranslationYAnimation.values = @[@(0.000), @(11.242), @(0.581)];
    proPicTranslationYAnimation.keyTimes = @[@(0.000), @(0.500), @(1.000)];
    proPicTranslationYAnimation.timingFunctions = @[linearTiming, linearTiming];
    proPicTranslationYAnimation.beginTime = beginTime;
    proPicTranslationYAnimation.fillMode = fillMode;
    proPicTranslationYAnimation.removedOnCompletion = removedOnCompletion;
    [[self layer] addAnimation:proPicTranslationYAnimation forKey:@"alertPopUp_TranslationY"];




- (void)addAlertPopUpAnimationWithCompletion:(void (^)(BOOL finished))completionBlock

    [self addAlertPopUpAnimationWithBeginTime:0 andFillMode:kCAFillModeBoth andRemoveOnCompletion:NO completion:completionBlock];

当您想添加动画时,请在将视图添加为子视图后立即调用: 您需要继承 UIView 并将代码放在那里。

稍后您可以调用:

[_yourView addAlertPopUpAnimationWithCompletion:^(BOOL finished) 

    //do your stuff after animation is finished
];

动画是这样的:

【讨论】:

以上是关于模仿 UIAlertController 显示动画的主要内容,如果未能解决你的问题,请参考以下文章

如何同时关闭 UIAlertController 和键盘?

[iOS]过渡动画之高级模仿 airbnb

UIAlertController 不会立即显示

iOS 10:UIAlertController 只显示一个动作

如果已经显示警报,则显示 UIAlertController

从 MSMessagesAppViewController 正确显示 UIAlertController