1、本章博客主要实现几个不同类型的浮动框。第一种:EasyThouch (苹果的小白点):功能近是苹果。第二种:是一种不可移动的浮动按钮,就一个单一的点击事件。第三:是扇形按钮浮动。这是公司App里面使用到三个情况,然后就自己写了一下。茹克满足您的需求,不防Mark一下。
2、效果图:
3、上代码,不多说,大部分注释很详细。
//
// FloatingButton.h
// FloatingButton
//
// Created by MAC on 2016/10/28.
// Copyright © 2016年 NetworkCode小贱. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "BlackView.h"
typedef NS_ENUM(NSInteger,FloatingButtonType) {
/* 类似苹果的小白点*/
FloatingButtonType_Default = 0,
/* 左边固定扇形按钮*/
FloatingRightDownType,
/* 中间*/
FloatingCenterType
};
@interface FloatingButton : UIImageView<BlackViewDelegate>{
/* 判断是否还在移动*/
UIView * backView;
/*存储按钮*/
NSMutableArray * BtnArray;
}
/* 移动的类型*/
@property(assign,nonatomic)FloatingButtonType FloatingType;
/* 判断是否可以移动*/
@property(assign,nonatomic) BOOL isMove;
/* 创建对象的方法*/
-(instancetype)initWithFrame:(CGRect)frame type:(FloatingButtonType)type;
@end
//
// FloatingButton.m
// FloatingButton
//
// Created by MAC on 2016/10/28.
// Copyright © 2016年 NetworkCode小贱. All rights reserved.
//
#import "FloatingButton.h"
#import <objc/runtime.h>
@implementation FloatingButton
/* 创建对象*/
-(instancetype)initWithFrame:(CGRect)frame type:(FloatingButtonType)type{
if (self = [super initWithFrame:frame]) {
/*默认移动开启*/
self.userInteractionEnabled = YES;
self.contentMode = UIViewContentModeScaleAspectFit;
/* 添加单机手势*/
[self addTapGestureRecognizer:self sel:@selector(tapClick:)];
self.FloatingType = type;
}
return self;
}
#pragma mark -- 添加单机手势
-(void)addTapGestureRecognizer:(id)tager sel:(SEL)sel{
UITapGestureRecognizer * TapGestureRecognizer = [[UITapGestureRecognizer alloc]initWithTarget:self action:sel];
[tager addGestureRecognizer:TapGestureRecognizer];
}
/* 点击的事件处理*/
-(void)tapClick:(UITapGestureRecognizer*)TapGesturerecognizer{
/*图标的变换处理*/
if (self.FloatingType == FloatingButtonType_Default) {
/* 创建一个背景层*/
if (backView==nil) {
backView = [[UIView alloc]initWithFrame:[UIScreen mainScreen].bounds];
[[UIApplication sharedApplication].keyWindow addSubview:backView];
}
/*隐藏图标*/
[self addTapGestureRecognizer:backView sel:@selector(showClick:)];
self.hidden = YES;
/* 弹出黑色的图片*/
BlackView * BlackView2 = [[BlackView alloc]initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width * 0.5, [UIScreen mainScreen].bounds.size.width * 0.5)];
BlackView2.delegate = self;
BlackView2.center = backView.center;
BlackView2.backgroundColor = [UIColor blackColor];
BlackView2.layer.masksToBounds =YES;
BlackView2.layer.cornerRadius = 8;
BlackView2.center = self.center;
[backView addSubview:BlackView2];
[UIView animateWithDuration:0.5 animations:^{
BlackView2.center = backView.center;
}];
}else if (self.FloatingType==FloatingRightDownType){
/* 获取这个对象*/
NSString * ClickStr = @"isClick";
id objectPram =objc_getAssociatedObject(self, &ClickStr);
if (objectPram) {
self.transform = CGAffineTransformMakeRotation(0);
/*
objc_removeAssociatedObjects : 是内联属性,没权删除。只能删除与之相关的所有对象
*/
objc_setAssociatedObject(self, &ClickStr, nil, OBJC_ASSOCIATION_ASSIGN);
objc_removeAssociatedObjects(objectPram);
/* 收起按钮*/
[self setThreeBtnHidden];
}else{
objc_setAssociatedObject(self, &ClickStr, @"Click", OBJC_ASSOCIATION_COPY_NONATOMIC);
self.transform = CGAffineTransformMakeRotation(M_2_PI);
/* 展示按钮*/
[self createThreeBtn];
}
}else if (self.FloatingType==FloatingCenterType){
UIAlertView * Al = [[UIAlertView alloc]initWithTitle:@"提示" message:@"我被点击了!" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:nil, nil];
[Al show];
}
}
-(void)createThreeBtn{
NSArray * ImageArray = @[[UIImage imageNamed:@"timePic"],[UIImage imageNamed:@"timesPic"],[UIImage imageNamed:@"wenPic"]];
BtnArray = [NSMutableArray arrayWithCapacity:0];
for (int i =0 ; i<3; i++) {
UIButton * btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.frame = CGRectMake([UIScreen mainScreen].bounds.size.width-55, [UIScreen mainScreen].bounds.size.height-55, 40, 40);
[btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
btn.tag = i;
[btn setBackgroundImage:ImageArray[i] forState:UIControlStateNormal];
[[UIApplication sharedApplication].keyWindow addSubview:btn];
[self rotationAnimation:btn isDrain:YES];
[UIView animateWithDuration:0.5 animations:^{
if (i==0) {
btn.frame = CGRectMake([UIScreen mainScreen].bounds.size.width-155, [UIScreen mainScreen].bounds.size.height - 55, 40, 40);
}else if (1==i){
btn.frame = CGRectMake([UIScreen mainScreen].bounds.size.width-(sqrt(2)*50+20)-35, [UIScreen mainScreen].bounds.size.height -(sqrt(2)*50+20)-35, 40, 40);
}else{
btn.frame = CGRectMake([UIScreen mainScreen].bounds.size.width-55, [UIScreen mainScreen].bounds.size.height - 155, 40, 40);
}
}];
[BtnArray addObject:btn];
}
}
/*收起动画*/
-(void)setThreeBtnHidden{
for (UIButton * temp in BtnArray) {
[self rotationAnimation:temp isDrain:NO];
[UIView animateWithDuration:0.25 animations:^{
temp.frame = CGRectMake([UIScreen mainScreen].bounds.size.width-55, [UIScreen mainScreen].bounds.size.height-55, 40, 40);
} completion:^(BOOL finished) {
[temp removeFromSuperview];
}];
}
BtnArray = nil;
}
/* 设置按钮的旋转*/
- (void)rotationAnimation:(UIButton*)animBtnView isDrain:(BOOL)isD{
CABasicAnimation* Animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
[animBtnView.layer setAnchorPoint:CGPointMake(0.5, 0.5)];
if (isD) {
[Animation setToValue:@(M_PI*2)];
}else{
[Animation setToValue:@(-M_PI*2)];
}
[Animation setRepeatCount:1];
[Animation setDuration:0.5f];
[animBtnView.layer addAnimation:Animation forKey:@"rotationAnim"];
}
/* 扇形按钮的点击事件*/
-(void)btnClick:(UIButton*)Btn{
NSString * Str = nil;
if (Btn.tag==0) {
Str = @"钟表";
}else if (Btn.tag==1){
Str = @"闹钟";
}else if (Btn.tag ==2){
Str = @"问答";
}
UIAlertView * Al = [[UIAlertView alloc]initWithTitle:@"提示" message:Str delegate:self cancelButtonTitle:@"取消" otherButtonTitles:nil, nil];
[Al show];
}
#pragma mark -- 上方的点击事件
-(void)actionClick:(NSInteger)actionTag{
NSString * Str = nil;
if (actionTag==0) {
Str = @"主屏幕";
}else if (actionTag==1){
Str = @"通知中心";
}else if (actionTag ==2){
Str = @"语音";
}else{
Str = @"收藏";
}
UIAlertView * Al = [[UIAlertView alloc]initWithTitle:@"提示" message:Str delegate:self cancelButtonTitle:@"取消" otherButtonTitles:nil, nil];
[Al show];
}
#pragma mark -- 显示图标
-(void)showClick:(UITapGestureRecognizer*)TapGesturerecognizer{
[backView removeFromSuperview];
backView = nil;
self.hidden = NO;
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
}
*/
#pragma mark -- 移动处理
/* 图标的移动处理*/
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
/* 开始触摸*/
if (self.FloatingType==FloatingButtonType_Default) {
/* 白点变量*/
}
}
-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
/* 获取手指*/
UITouch * Touch = [[touches allObjects] firstObject];
/*获取手指和屏幕的结合点*/
CGPoint CurrentPoint = [Touch locationInView:self];
/* 获取上一次手指和屏幕的结合点*/
CGPoint PreviousPoint = [Touch previousLocationInView:self];
/* 获取当前图标的大小*/
float halfWidth = self.bounds.size.width * 0.5;
float halfHight = self.bounds.size.height * 0.5;
float AppWidth = [UIScreen mainScreen].bounds.size.width;
float AppHigth = [UIScreen mainScreen].bounds.size.height;
/*移动开始*/
if (self.FloatingType == FloatingButtonType_Default) {
float x_offset =0.0, y_Offset=0.0;
CGPoint TempPoint = CGPointZero ;
CGPoint selfCenterPoint = self.center;
x_offset =selfCenterPoint.x - PreviousPoint.x + CurrentPoint.x ;
y_Offset =selfCenterPoint.y - PreviousPoint.y + CurrentPoint.y ;
if (x_offset<=halfWidth && y_Offset<=halfHight) {
TempPoint = CGPointMake(halfWidth, halfHight);
}else if (x_offset<=halfWidth && y_Offset>=AppHigth-halfHight){
TempPoint = CGPointMake(halfWidth, AppHigth - halfHight);
}else if (x_offset>=AppWidth - halfWidth && y_Offset<=halfHight){
TempPoint = CGPointMake(AppWidth-halfWidth,halfHight);
}else if (x_offset>=AppWidth - halfWidth && y_Offset>=AppHigth-halfHight){
TempPoint = CGPointMake(AppWidth-halfWidth,AppHigth-halfHight);
}else if (x_offset<=halfWidth){
TempPoint = CGPointMake(halfWidth,y_Offset);
}else if (y_Offset<=halfHight){
TempPoint = CGPointMake(x_offset,halfHight);
}else if (x_offset>=AppWidth-halfWidth){
TempPoint = CGPointMake(AppWidth - halfWidth ,y_Offset);
}else if (y_Offset>AppHigth-halfHight){
TempPoint = CGPointMake(x_offset, AppHigth-halfHight);
}else if (x_offset>halfWidth&&x_offset<AppWidth&&y_Offset>halfHight&&y_Offset<AppHigth){
TempPoint = CGPointMake(x_offset, y_Offset);
}
self.center = TempPoint;
}else if (self.FloatingType==FloatingRightDownType){
return;
}
}
-(void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
/* 移动取消*/
}
-(void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
/* 移动结束*/
}
@end
//右下角的按钮
FloatingButton * RightDownBtn = [[FloatingButton alloc]initWithFrame:CGRectMake([UIScreen mainScreen].bounds.size.width-55, [UIScreen mainScreen].bounds.size.height-55 , 40, 40) type:FloatingRightDownType];
RightDownBtn.isMove = NO;
RightDownBtn.image = [UIImage imageNamed:@"addPic"];
[self.view addSubview:RightDownBtn];