iOS悬浮窗口(无论界面跳转、View始终在视图上显示,可移动)

自定义iOS窗口动画
本文介绍了一种在iOS应用中创建自定义窗口的方法,并详细展示了如何实现窗口的移动与动画效果。通过继承 UIWindow 类,作者封装了一个名为 JYCWindow 的自定义类,实现了窗口在不同位置之间的平滑过渡及雷达辐射效果。
2016.09.24 23:52* 字数 71 阅读 5925评论 9

让所有界面都显示,最好还是封装一个继承Window的类:JYCWindow。

先看看效果:

 
mygif.gif

关键代码如下:

- (instancetype)initWithFrame:(CGRect)frame mainImageName:(NSString*)name bgcolor:(UIColor *)bgcolor animationColor:animationColor

{
    if(self = [super initWithFrame:frame])
    {
        NSAssert(name != nil, @"mainImageName can't be nil !");
        
        self.backgroundColor = [UIColor clearColor];
        self.windowLevel = UIWindowLevelAlert + 1;  //如果想在 alert 之上,则改成 + 2
        self.rootViewController = [UIViewController new];
        [self makeKeyAndVisible];
        
        _bgcolor = bgcolor;
        _frameWidth = frame.size.width;
        _animationColor = animationColor;
        
        
        _mainImageButton =  [UIButton buttonWithType:UIButtonTypeCustom];
        [_mainImageButton setFrame:(CGRect){0, 0,frame.size.width, frame.size.height}];
        [_mainImageButton setImage:[UIImage imageNamed:name] forState:UIControlStateNormal];
        //        _mainImageButton.layer.cornerRadius = frame.size.width*0.5;
        //        _mainImageButton.layer.masksToBounds= YES;
        _mainImageButton.alpha = normalAlpha;
        [_mainImageButton addTarget:self action:@selector(click:) forControlEvents:UIControlEventTouchUpInside];
        if (_animationColor) {
            [_mainImageButton addTarget:self action:@selector(mainBtnTouchDown) forControlEvents:UIControlEventTouchDown];
        }
        
        [self addSubview:_mainImageButton];
        
        
         // 增加拖动window的手势
        _pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(locationChange:)];
        _pan.delaysTouchesBegan = NO;
        [self addGestureRecognizer:_pan];
        _tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(click:)];
        [self addGestureRecognizer:_tap];
        

        [self performSelector:@selector(justbegin) withObject:nil afterDelay:statusChangeDuration];

        
    }
    return self;
}

至于怎么移动,怎么动画,直接看.h和.m文件如下:

JYCWindow.h###


#import <UIKit/UIKit.h>

typedef void(^CallTheService)(void);

@interface JYCWindow : UIWindow

//重要:所有图片都要是圆形的,程序里并没有自动处理成圆形

//  warning: frame的长宽必须相等
- (instancetype)initWithFrame:(CGRect)frame mainImageName:(NSString*)name bgcolor:(UIColor *)bgcolor;

// 长按雷达辐射效果
- (instancetype)initWithFrame:(CGRect)frame mainImageName:(NSString*)name bgcolor:(UIColor *)bgcolor animationColor:animationColor;

// 显示(默认)
- (void)showWindow;

// 隐藏
- (void)dissmissWindow;

@property (nonatomic,copy)CallTheService callService;
@end

JYCWindow.m###



#import "JYCWindow.h"
#define kk_WIDTH self.frame.size.width
#define kk_HEIGHT self.frame.size.height

#define kScreenWidth [[UIScreen mainScreen] bounds].size.width
#define kScreenHeight [[UIScreen mainScreen] bounds].size.height

#define animateDuration 0.3       //位置改变动画时间
#define showDuration 0.1          //展开动画时间
#define statusChangeDuration  3.0    //状态改变时间
#define normalAlpha  1.0           //正常状态时背景alpha值
#define sleepAlpha  0.5           //隐藏到边缘时的背景alpha值
#define myBorderWidth 1.0         //外框宽度
#define marginWith  5             //间隔

#define WZFlashInnerCircleInitialRaius  20

@interface JYCWindow ()

@property(nonatomic)NSInteger frameWidth;
@property(nonatomic,strong)UIPanGestureRecognizer *pan;
@property(nonatomic,strong)UITapGestureRecognizer *tap;
@property(nonatomic,strong)UIButton *mainImageButton;
@property(nonatomic,strong)UIColor *bgcolor;
@property(nonatomic,strong)CAAnimationGroup *animationGroup;
@property(nonatomic,strong)CAShapeLayer *circleShape;
@property(nonatomic,strong)UIColor *animationColor;

@end
@implementation JYCWindow
- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
    }
    return self;
}

- (instancetype)initWithFrame:(CGRect)frame mainImageName:(NSString*)name bgcolor:(UIColor *)bgcolor{
    return [self initWithFrame:frame mainImageName:name bgcolor:bgcolor animationColor:nil];
}

- (instancetype)initWithFrame:(CGRect)frame mainImageName:(NSString*)name bgcolor:(UIColor *)bgcolor animationColor:animationColor

{
    if(self = [super initWithFrame:frame])
    {
        NSAssert(name != nil, @"mainImageName can't be nil !");
        
        self.backgroundColor = [UIColor clearColor];
        self.windowLevel = UIWindowLevelAlert + 1;  //如果想在 alert 之上,则改成 + 2
        self.rootViewController = [UIViewController new];
        [self makeKeyAndVisible];
        
        _bgcolor = bgcolor;
        _frameWidth = frame.size.width;
        _animationColor = animationColor;
        
        
        _mainImageButton =  [UIButton buttonWithType:UIButtonTypeCustom];
        [_mainImageButton setFrame:(CGRect){0, 0,frame.size.width, frame.size.height}];
        [_mainImageButton setImage:[UIImage imageNamed:name] forState:UIControlStateNormal];
        //        _mainImageButton.layer.cornerRadius = frame.size.width*0.5;
        //        _mainImageButton.layer.masksToBounds= YES;
        _mainImageButton.alpha = normalAlpha;
        [_mainImageButton addTarget:self action:@selector(click:) forControlEvents:UIControlEventTouchUpInside];
        if (_animationColor) {
            [_mainImageButton addTarget:self action:@selector(mainBtnTouchDown) forControlEvents:UIControlEventTouchDown];
        }
        
        [self addSubview:_mainImageButton];
        
//        [self doBorderWidth:myBorderWidth color:nil cornerRadius:_frameWidth/2];
        
        _pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(locationChange:)];
        _pan.delaysTouchesBegan = NO;
        [self addGestureRecognizer:_pan];
        _tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(click:)];
        [self addGestureRecognizer:_tap];
        

        [self performSelector:@selector(justbegin) withObject:nil afterDelay:statusChangeDuration];

        
    }
    return self;
}

- (void)dissmissWindow{
    self.hidden = YES;
}
- (void)showWindow{
    self.hidden = NO;
}

- (void)justbegin{
    
    [self performSelector:@selector(changeStatus) withObject:nil afterDelay:statusChangeDuration];

    CGPoint panPoint = CGPointMake(kScreenWidth-80, kScreenHeight-150);
    
    [self changBoundsabovePanPoint:panPoint];
}

- (void)changBoundsabovePanPoint:(CGPoint)panPoint{
    
    if(panPoint.x <= kScreenWidth/2)
    {
        if(panPoint.y <= 40+kk_HEIGHT/2 && panPoint.x >= 20+kk_WIDTH/2)
        {
            [UIView animateWithDuration:animateDuration animations:^{
                self.center = CGPointMake(panPoint.x, kk_HEIGHT/2);
            }];
        }
        else if(panPoint.y >= kScreenHeight-kk_HEIGHT/2-40 && panPoint.x >= 20+kk_WIDTH/2)
        {
            [UIView animateWithDuration:animateDuration animations:^{
                self.center = CGPointMake(panPoint.x, kScreenHeight-kk_HEIGHT/2);
            }];
        }
        else if (panPoint.x < kk_WIDTH/2+20 && panPoint.y > kScreenHeight-kk_HEIGHT/2)
        {
            [UIView animateWithDuration:animateDuration animations:^{
                self.center = CGPointMake(kk_WIDTH/2, kScreenHeight-kk_HEIGHT/2);
            }];
        }
        else
        {
            CGFloat pointy = panPoint.y < kk_HEIGHT/2 ? kk_HEIGHT/2 :panPoint.y;
            [UIView animateWithDuration:animateDuration animations:^{
                self.center = CGPointMake(kk_WIDTH/2, pointy);
            }];
        }
    }
    else if(panPoint.x > kScreenWidth/2)
    {
        if(panPoint.y <= 40+kk_HEIGHT/2 && panPoint.x < kScreenWidth-kk_WIDTH/2-20 )
        {
            [UIView animateWithDuration:animateDuration animations:^{
                self.center = CGPointMake(panPoint.x, kk_HEIGHT/2);
            }];
        }
        else if(panPoint.y >= kScreenHeight-40-kk_HEIGHT/2 && panPoint.x < kScreenWidth-kk_WIDTH/2-20)
        {
            [UIView animateWithDuration:animateDuration animations:^{
                self.center = CGPointMake(panPoint.x, kScreenHeight-kk_HEIGHT/2);
            }];
        }
        else if (panPoint.x > kScreenWidth-kk_WIDTH/2-20 && panPoint.y < kk_HEIGHT/2)
        {
            [UIView animateWithDuration:animateDuration animations:^{
                self.center = CGPointMake(kScreenWidth-kk_WIDTH/2, kk_HEIGHT/2);
            }];
        }
        else
        {
            CGFloat pointy = panPoint.y > kScreenHeight-kk_HEIGHT/2 ? kScreenHeight-kk_HEIGHT/2 :panPoint.y;
            [UIView animateWithDuration:animateDuration animations:^{
                self.center = CGPointMake(kScreenWidth-kk_WIDTH/2, pointy);
            }];
        }
    }

}
//改变位置
- (void)locationChange:(UIPanGestureRecognizer*)p
{
    CGPoint panPoint = [p locationInView:[[UIApplication sharedApplication] keyWindow]];
    if(p.state == UIGestureRecognizerStateBegan)
    {
        [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(changeStatus) object:nil];
        _mainImageButton.alpha = normalAlpha;
    }
    if(p.state == UIGestureRecognizerStateChanged)
    {
        self.center = CGPointMake(panPoint.x, panPoint.y);
    }
    else if(p.state == UIGestureRecognizerStateEnded)
    {
        [self stopAnimation];
        [self performSelector:@selector(changeStatus) withObject:nil afterDelay:statusChangeDuration];
        
        [self changBoundsabovePanPoint:panPoint];

    }
}
//点击事件
- (void)click:(UITapGestureRecognizer*)p
{
    [self stopAnimation];
    
    _mainImageButton.alpha = normalAlpha;
    
    

转载于:https://www.cnblogs.com/sundaysgarden/p/9241697.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值