按钮放置窗口上,用户可随便拖动按钮到任意的位置,当位置超出窗口的时候,按钮会自动移动到视图边缘,按钮移动到视图中间的时候,按钮也会往最近的边缘移动,不会产生遮挡其他视图。
1,自定义视图.h文件
#define dragButtonSize60
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@protocolUIDragButtonDelegate
-(void)dragButtonClicked:(UIButton*)sender;
@end
@interfaceUIDragButton :UIButton
/**
*悬浮窗所依赖的根视图
*/
@property(nonatomic,strong)UIView*rootView;
/**
*UIDragButton的点击事件代理
*/
@property(nonatomic,weak)idbtnDelegate;
@end
2,.m文件
// 屏幕高度
#define ScreenH [UIScreen mainScreen].bounds.size.height
// 屏幕宽度
#define ScreenW [UIScreen mainScreen].bounds.size.width
#import"UIDragButton.h"
#import"AppDelegate.h"
@interface UIDragButton()
@property(nonatomic,assign)CGPointstartPos;
@end
@implementation UIDragButton
// 枚举四个吸附方向
typedefenum{
LEFT,
RIGHT,
TOP,
BOTTOM
}Dir;
/**
*开始触摸,记录触点位置用于判断是拖动还是点击
*/
- (void)touchesBegan:(NSSet *)touches withEvent:(nullableUIEvent*)event {
// 获得触摸在根视图中的坐标
UITouch*touch = [touchesanyObject];
_startPos= [touchlocationInView:_rootView];
}
/**
*手指按住移动过程,通过悬浮按钮的拖动事件来拖动整个悬浮窗口
*/
- (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
{
// 获得触摸在根视图中的坐标
UITouch*touch = [touchesanyObject];
CGPointcurPoint = [touchlocationInView:_rootView];
// 移动按钮到当前触摸位置
self.superview.center= curPoint;
}
/**
*拖动结束后使悬浮窗口吸附在最近的屏幕边缘
*/
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent*)event {
// 获得触摸在根视图中的坐标
UITouch*touch = [touchesanyObject];
CGPointcurPoint = [touchlocationInView:_rootView];
// 通知代理,如果结束触点和起始触点极近则认为是点击事件
if(pow((_startPos.x- curPoint.x),2) +pow((_startPos.y- curPoint.y),2) <1) {
[self.btnDelegatedragButtonClicked:self];
// 点击后不吸附
//return;
}
CGFloatleft = curPoint.x;
CGFloatright =ScreenW- curPoint.x;
CGFloattop = curPoint.y;
CGFloatbottom =ScreenH- curPoint.y;
// 计算四个距离最小的吸附方向
DirminDir =LEFT;
CGFloatminDistance = left;
if(right < minDistance) {
minDistance = right;
minDir =RIGHT;
}
if(top < minDistance) {
minDistance = top;
minDir =TOP;
}
if(bottom < minDistance) {
minDir =BOTTOM;
}
//悬浮button的superView的centerY
CGFloatcenter_y =self.superview.center.y;
//拖拽bottom时的centerY;
CGFloatmaxCenter_y =ScreenH-kTabbarHeight-self.superview.frame.size.height/2;
//拖拽top时的centerY;
CGFloatsmallCenter_y =self.superview.frame.size.height/2+64;
if(center_y > maxCenter_y) {
center_y = maxCenter_y;
}
if(center_y < smallCenter_y) {
center_y = smallCenter_y;
}
//悬浮button的superView的centerX
CGFloat center_x =self.superview.center.x;
//拖拽right时的centerX;
CGFloat maxCenter_x =ScreenW-self.superview.frame.size.width/2;
//拖拽left时的centerX;
CGFloatsmall Center_x =self.superview.frame.size.width/2;
if(center_x > maxCenter_x) {
center_x = maxCenter_x;
}
if(center_x < smallCenter_x) {
center_x = smallCenter_x;
}
// 开始吸附
switch(minDir) {
caseLEFT:
{
[UIView animateWithDuration:0.3animations:^{
self.superview.center=CGPointMake(self.superview.frame.size.width/2, center_y);
}];
break;
}
caseRIGHT:
{
[UIView animateWithDuration:0.3animations:^{
self.superview.center=CGPointMake(ScreenW-self.superview.frame.size.width/2, center_y);
}];
break;
}
caseTOP:
{
[UIView animateWithDuration:0.3animations:^{
self.superview.center=CGPointMake(center_x,self.superview.frame.size.height/2+64);
}];
break;
}
caseBOTTOM:
{
[UIView animateWithDuration:0.3animations:^{
self.superview.center=CGPointMake(center_x,ScreenH-self.superview.frame.size.height/2-kTabbarHeight);
}];
break;
}
default:
break;
}
}
@end
3,相对应视图实现方法
// 悬浮按钮
UIDragButton *dragButton= [UIDragButton buttonWithType:UIButtonTypeCustom];
[dragButton setImage:[UIImageimageNamed:@"yhbb-float-icon"]forState:UIControlStateNormal];
// 按钮图片伸缩充满整个按钮
dragButton.imageView.contentMode=UIViewContentModeScaleToFill;
dragButton.frame=CGRectMake(0,0,dragButtonSize,dragButtonSize);
// 按钮点击事件
//[dragButton addTarget:self action:@selector(floatBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
// 初始选中状态
dragButton.selected=NO;
// 禁止高亮
dragButton.adjustsImageWhenHighlighted=NO;
dragButton.rootView=self.view;
dragButton.btnDelegate=self;
4、需要demo后续补充,谢谢!
网友评论