前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >自定义一个浮层弹窗视图

自定义一个浮层弹窗视图

作者头像
拉维
发布2019-08-12 15:51:18
1.3K0
发布2019-08-12 15:51:18
举报
文章被收录于专栏:iOS小生活iOS小生活

早在2017年年初,我就用七八篇文章的篇幅系统介绍过Objective-C中的CoreAnimation框架。CoreAnimation是iOS中实现动画的框架,整个iOS中的动画(比如UIView中封装的动画、UIViewController切换时的转场动画、UITableViewCell移除增添时的动画等,都是对CoreAnimation的封装)都是通过CoreAnimation实现的。

UIView动画

代码语言:javascript
复制
@interface UIView(UIViewAnimationWithBlocks)

+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^ __nullable)(BOOL finished))completion NS_AVAILABLE_IOS(4_0);

+ (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations completion:(void (^ __nullable)(BOOL finished))completion NS_AVAILABLE_IOS(4_0); // delay = 0.0, options = 0

+ (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations NS_AVAILABLE_IOS(4_0); // delay = 0.0, options = 0, completion = NULL

+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay usingSpringWithDamping:(CGFloat)dampingRatio initialSpringVelocity:(CGFloat)velocity options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^ __nullable)(BOOL finished))completion NS_AVAILABLE_IOS(7_0);

+ (void)transitionWithView:(UIView *)view duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void (^ __nullable)(void))animations completion:(void (^ __nullable)(BOOL finished))completion NS_AVAILABLE_IOS(4_0);

+ (void)transitionFromView:(UIView *)fromView toView:(UIView *)toView duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options completion:(void (^ __nullable)(BOOL finished))completion NS_AVAILABLE_IOS(4_0); // toView added to fromView.superview, fromView removed from its superview

+ (void)performSystemAnimation:(UISystemAnimation)animation onViews:(NSArray<__kindof UIView *> *)views options:(UIViewAnimationOptions)options animations:(void (^ __nullable)(void))parallelAnimations completion:(void (^ __nullable)(BOOL finished))completion NS_AVAILABLE_IOS(7_0);

@end

@interface UIView (UIViewKeyframeAnimations)

+ (void)animateKeyframesWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewKeyframeAnimationOptions)options animations:(void (^)(void))animations completion:(void (^ __nullable)(BOOL finished))completion NS_AVAILABLE_IOS(7_0);

+ (void)addKeyframeWithRelativeStartTime:(double)frameStartTime relativeDuration:(double)frameDuration animations:(void (^)(void))animations NS_AVAILABLE_IOS(7_0); 

@end

上面的代码展示了UIView动画的相关接口,它能够实现我们日常开发中80%以上的动画效果,可以处理frame、alpha、transform等,但是UIView的内置动画是不能自定义中间状态的,也就是说,不能实现关键帧动画。这些UIView内置动画,实际上都是对CoreAnimation动画的封装

实现一个自定义弹窗视图

我们平时在开发的时候,经常会遇到这样的需求:在页面中弹出一个自定义视图,除了弹出的自定义视图之外,页面的其他位置都置灰态。比如下图这样:

要实现这样的效果,基本思路是:

1,新建一个弹窗背景视图,背景颜色设置为黑色,透明度设置为0.5;

2,将自定义弹窗视图加在弹窗背景视图上;

3,触发弹出弹窗视图的时候,将弹窗背景视图添加到程序的根窗口上;

4,移除弹窗视图的时候,就将弹窗背景视图从父视图上移除即可。

代码如下:

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

NS_ASSUME_NONNULL_BEGIN

@interface NormanHudView : UIView
/**
 灰色背景上方的展示视图。该视图为用户自定义。
 required
 */
@property (nonatomic, strong)UIView *customView;

/**
 决定hud视图是否展示的开关
 required
 */
@property (nonatomic, assign)BOOL showCustomView;

@end

NS_ASSUME_NONNULL_END


//NormanHudView.m
#import "NormanHudView.h"

@interface NormanHudView()

@end

@implementation NormanHudView

- (instancetype)initWithFrame:(CGRect)frame
{
    if (self = [super initWithFrame:frame]) {
        
        self.backgroundColor = [UIColorcolorWithWhite:0 alpha:0.5];
        
        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:selfaction:@selector(tapAction:)];
        [self addGestureRecognizer:tap];
        
    }
    return self;
}

#pragma mark - tapAction
- (void)tapAction:(UIGestureRecognizer *)recognizer
{
    CGPoint tapPoint = [recognizer locationInView:self];
    if (CGRectContainsPoint(self.customView.frame, tapPoint)) {
        return;//点击点在自定义视图范围之外才会使提示视图消失~
    }
    self.showCustomView = NO;
}

#pragma mark - setter && Getter
- (void)setShowCustomView:(BOOL)showCustomView
{
    if (showCustomView) {
        [[UIApplication sharedApplication].keyWindowaddSubview:self];
        //这里是展示customView的时候的动画,可根据自己的情况自定义
        [UIView animateWithDuration:2.f delay:0 usingSpringWithDamping:0.5 initialSpringVelocity:0.5 options:UIViewAnimationOptionCurveEaseInOut animations:^{
            self.customView.alpha = 1;
        } completion:^(BOOL finished) {
            NSLog(@"completion");
        }];
    } else {
        [self removeFromSuperview];
    }
}

- (void)setCustomView:(UIView *)customView
{
    _customView = customView;
    [self addSubview:_customView];
    _customView.center = self.center;
    _customView.alpha = 0;
}

@end

上述代码是我封装的一个浮层视图。

展示浮层上的自定义提示视图的时候,我使用了UIView的动画,可以在这里实现浮层上的自定义提示视图展示时候的动画

给浮层的背景视图添加一个点击手势,以在点击的时候移除该浮层。

写在最后

UIKit框架中各组件自带的各种动画效果,实际上都是对CoreAnimation这个框架中相关接口的封装。

通过UIView的系统封装好的动画,我们可以实现日常开发中80%的动画需求,剩下的一些较复杂的动画,可以使用CoreAnimation来自定义。

关于CoreAnimation,我之前写过一系列的文章,在这里罗列一下:

  1. 通过重写drawRect方法在UIView中进行绘图
  2. 通过重写drawLayer:InContext:方法在CALayer中进行绘图
  3. CALayer的属性及其与UIView的联系和区别
  4. iOS 框架之 Core Animation
  5. CoreAnimation 之 BasicAnimation & <CAMediaTiming>
  6. CoreAnimation 之 CAKeyFrameAnimation(关键帧动画)
  7. CoreAnimation 之 CAAnimationGroup(动画组)
  8. CoreAnimation 之 CATransition(转场动画)以及动画的暂停和恢复

其实,除了上面提到的相关动画,还有一个动画相关的类是有必要跟大家提一下的,那就是CAEmitterLayer(粒子发射器)。QQ点赞效果、红包雨、下雪、火焰等等都是通过该类来实现的。可以参考这篇文章:

代码语言:javascript
复制
https://www.jianshu.com/p/c54ffd7412e7

除了上述原生动画,有一个开源动画项目也是经常使用的,那就是Lottie。Lottie是Airbnb开源的一个面向iOS、Android、React Native的动画库,能分析Adobe After Effects导出的动画,并且能让原生App像使用静态素材一样使用这些动画,完美实现动画效果。

设计师设计出一组动画效果,然后导成JSON文件,我使用Lottie解析该JSON文件就可以将动画效果展示出来,使用非常简单。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-06-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 iOS小生活 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档