可以拖动并且可以指定贴左还是贴右边, 直接上代码。
LMYHomeServicesButton.h
//
// LMYHomeServicesButton.h
// LMY
//
// Created by 刘明洋 on 2018/1/28.
// Copyright © 2018年 lmy. All rights reserved.
//
#import <UIKit/UIKit.h>
typedef NS_ENUM(NSInteger, LMYAssistiveTouchType)
{
LMYAssistiveTypeNone = 0, //自动识别贴边
LMYAssistiveTypeNearLeft, //拖动停止之后,自动向左贴边
LMYAssistiveTypeNearRight, //拖动停止之后,自动向右贴边
};
@interface LMYHomeServicesButton : UIButton
typedef void (^floatBtnClick)(UIButton *sender);
//任何模式都显示floatBtn
+ (void)show;
//移除
+ (void)hidden;
//按钮点击事件
@property (nonatomic, copy)floatBtnClick btnClick;
@end
LMYHomeServicesButton.m
//
// LMYHomeServicesButton.m
// LMY
//
// Created by 刘明洋 on 2018/1/28.
// Copyright © 2018年 lmy. All rights reserved.
//
#import "LMYHomeServicesButton.h"
@interface LMYHomeServicesButton()
@property (nonatomic, assign, getter=isBuildShowDate) BOOL buildShowDate;
//Build号
@property(nonatomic, copy)NSString *buildStr;
@property(nonatomic, assign)BOOL isShow;
@end
@implementation LMYHomeServicesButton{
LMYAssistiveTouchType _type;
//拖动按钮的起始坐标点
CGPoint _touchPoint;
//起始按钮的x,y值
CGFloat _touchBtnX;
CGFloat _touchBtnY;
}
static LMYHomeServicesButton *_floatBtn;
static CGFloat floatBtnW = 120;
static CGFloat floatBtnH = 49;
#define screenW [UIScreen mainScreen].bounds.size.width
#define screenH [UIScreen mainScreen].bounds.size.height
//系统默认build
#define MNFloatBtnSystemBuild [[[NSBundle mainBundle]infoDictionary]valueForKey:@"CFBundleVersion"]
//系统默认version
#define MNFloatBtnSystemVersion [[[NSBundle mainBundle]infoDictionary]valueForKey:@"CFBundleShortVersionString"]
#pragma mark - lazy
- (NSString *)buildStr{
if (!_buildStr) {
_buildStr = MNFloatBtnSystemBuild;
}
return _buildStr;
}
#pragma mark - private Method
+ (void)show{
[self showWithType:LMYAssistiveTypeNone];
}
+ (void)hidden{
[_floatBtn removeFromSuperview];
}
+ (void)showWithType:(LMYAssistiveTouchType)type{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
LMYHomeServicesButton * floatBtn = [[self alloc]initWithType:LMYAssistiveTypeNearRight frame:CGRectMake(10, 300, floatBtnW, floatBtnH)];
[[UIApplication sharedApplication].keyWindow addSubview:floatBtn];
//让floatBtn在最上层(即便以后还有keywindow add subView,也会在 floatBtn下)
[[UIApplication sharedApplication].keyWindow bringSubviewToFront:floatBtn];
});
}
- (instancetype)initWithType:(LMYAssistiveTouchType)type
frame:(CGRect)frame{
NSString *title = [NSString stringWithFormat:@"Ver:%@ \nBuild:%@\n查看更多",MNFloatBtnSystemVersion, self.buildStr];
if (self = [super initWithFrame:frame]) {
_type = type;
//UIbutton的换行显示
self.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
self.backgroundColor = [UIColor redColor];
self.titleLabel.font = [UIFont systemFontOfSize:13];
[self setTitle:title forState:UIControlStateNormal];
[self addTarget:self action:@selector(p_clickBtn:) forControlEvents:UIControlEventTouchUpInside];
}
return self;
}
- (void)p_clickBtn:(UIButton *)sender{
if (_btnClick) {
_btnClick(sender);
}
}
#pragma mark - button move
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
[super touchesBegan:touches withEvent:event];
//按钮刚按下的时候,获取此时的起始坐标
UITouch *touch = [touches anyObject];
_touchPoint = [touch locationInView:self];
_touchBtnX = self.frame.origin.x;
_touchBtnY = self.frame.origin.y;
}
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
UITouch *touch = [touches anyObject];
CGPoint currentPosition = [touch locationInView:self];
//偏移量(当前坐标 - 起始坐标 = 偏移量)
CGFloat offsetX = currentPosition.x - _touchPoint.x;
CGFloat offsetY = currentPosition.y - _touchPoint.y;
//移动后的按钮中心坐标
CGFloat centerX = self.center.x + offsetX;
CGFloat centerY = self.center.y + offsetY;
self.center = CGPointMake(centerX, centerY);
//父试图的宽高
CGFloat superViewWidth = self.superview.frame.size.width;
CGFloat superViewHeight = self.superview.frame.size.height;
CGFloat btnX = self.frame.origin.x;
CGFloat btnY = self.frame.origin.y;
CGFloat btnW = self.frame.size.width;
CGFloat btnH = self.frame.size.height;
//x轴左右极限坐标
if (btnX > superViewWidth){
//按钮右侧越界
CGFloat centerX = superViewWidth - btnW/2;
self.center = CGPointMake(centerX, centerY);
}else if (btnX < 0){
//按钮左侧越界
CGFloat centerX = btnW * 0.5;
self.center = CGPointMake(centerX, centerY);
}
//默认都是有导航条的,有导航条的,父试图高度就要被导航条占据,固高度不够
CGFloat defaultNaviHeight = 64;
CGFloat judgeSuperViewHeight = superViewHeight - defaultNaviHeight;
//y轴上下极限坐标
if (btnY <= 0){
//按钮顶部越界
centerY = btnH * 0.7;
self.center = CGPointMake(centerX, centerY);
}
else if (btnY > judgeSuperViewHeight){
//按钮底部越界
CGFloat y = superViewHeight - btnH * 0.5;
self.center = CGPointMake(btnX, y);
}
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
CGFloat btnWidth = self.frame.size.width;
CGFloat btnHeight = self.frame.size.height;
CGFloat btnY = self.frame.origin.y;
CGFloat btnX = self.frame.origin.x;
CGFloat minDistance = 2;
//结束move的时候,计算移动的距离是>最低要求,如果没有,就调用按钮点击事件
BOOL isOverX = fabs(btnX - _touchBtnX) > minDistance;
BOOL isOverY = fabs(btnY - _touchBtnY) > minDistance;
if (isOverX || isOverY) {
//超过移动范围就不响应点击 - 只做移动操作
[self touchesCancelled:touches withEvent:event];
}else{
[super touchesEnded:touches withEvent:event];
}
//按钮靠近右侧
switch (_type) {
case LMYAssistiveTypeNone:{
//自动识别贴边
if (self.center.x >= self.superview.frame.size.width/2) {
[UIView animateWithDuration:0.5 animations:^{
//按钮靠右自动吸边
CGFloat btnX = self.superview.frame.size.width - btnWidth;
self.frame = CGRectMake(btnX, btnY, btnWidth, btnHeight);
}];
}else{
[UIView animateWithDuration:0.5 animations:^{
//按钮靠左吸边
CGFloat btnX = 0;
self.frame = CGRectMake(btnX, btnY, btnWidth, btnHeight);
}];
}
break;
}
case LMYAssistiveTypeNearLeft:{
[UIView animateWithDuration:0.5 animations:^{
//按钮靠左吸边
CGFloat btnX = 0;
self.frame = CGRectMake(btnX, btnY, btnWidth, btnHeight);
}];
break;
}
case LMYAssistiveTypeNearRight:{
[UIView animateWithDuration:0.5 animations:^{
//按钮靠右自动吸边
CGFloat btnX = self.superview.frame.size.width - btnWidth;
self.frame = CGRectMake(btnX, btnY, btnWidth, btnHeight);
}];
}
}
}
@end
使用
//
// ViewController.m
// lmy
//
// Created by lmy on 2019/10/27.
// Copyright © 2019 lmy. All rights reserved.
//
#import "ViewController.h"
#import "LMYHomeServicesButton.h"
@interface ViewController ()
@property(nonatomic,strong)UIImage * objImage;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
[LMYHomeServicesButton show];
}
@end
网友评论