仿照苹果自带的吸附按钮


哈哈好久没有写了,抽点空闲时间写一个简单的Demo

上个星期的版本迭代,产品经理提出一个需求,就是页面上要有一个悬浮按钮。就和苹果系统自带的小白色按钮一样。还带吸附的效果,我觉得直接放在window 的上不就ok ,然后然后等我做完以后说只需要三个主页面有这个效果。尼玛这下我就要改呀改,想想appdelegate不是单利吗,直接给他一个button 的属性,不就可以了设置下隐藏的效果,然后自己测试的时候,乱七八糟的小问题,之后觉得这方案太垃圾了,还要判断好多的隐藏和显示,而且后台的接口还不是在配置文件中的而是在第一个主界面里面给定的接口。。最后无奈之下写一个单利,什么连七八糟的问题都解决了。。小白一个,代码分享给大家。。有问题多多指点。。求大神轻喷。。《代码还需要优化》

废话就不多说了直接上效果图,这是我公司项目中加的
这个只是为了符合产品需求写的,有需要的小伙伴可以自己修改修改放在window上或者view 上都有方法
#######效果

6月-26-2017 13-44-28.gif

最好真机测试比较好,因为模拟器移动的时候会触发点击的事件
########代码

CBBDraggableButton.h

@protocol CBBDragButtonDelegate 

- (void)cbb_DraggableButtonClicked:(UIButton *)button;

@end
@interface CBBDraggableButton : UIButton
+(instancetype)sharedInstance;

/** 点击 */
@property (nonatomic,copy) void (^clickBlock) (CBBDraggableButton *clickButton) ;
/** 拖拽 */
@property (nonatomic,copy) void (^draggbleBlock) (CBBDraggableButton*draggbleButton) ;

/** 代理 */
@property (nonatomic,weak) id dragButtonDelegate;

- (void)showWindow;


@property (nonatomic) BOOL draggable;
@property (nonatomic) BOOL autoDocking;
----

CBBDraggableButton.m
#import "CBBDraggableButton.h"

@interface CBBDraggableButton ()
{
    CGPoint _beginLocation;
    UILongPressGestureRecognizer *_longPressGestureRecognizer;
}

@end

@implementation CBBDraggableButton

@synthesize draggable = _draggable;
@synthesize autoDocking = _autoDocking;
@synthesize clickBlock = _clickBlock;

######CBBDraggableButton.m
/** 单利 */
+ (instancetype)sharedInstance
{
    static CBBDraggableButton *manager;
    
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
       
        manager = [[self alloc]init];
    });
    return manager;
}


- (instancetype)initWithFrame:(CGRect)frame
{
    if (self = [super initWithFrame:frame]) {
        [self setUpSubViews];
    }
    return self;
}

- (instancetype)init {
    self = [super init];
    if (self) {
        [self setUpSubViews];
    }
    return self;
}

- (instancetype)initAtView:(id)view WithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        [view addSubview:self];
        [self setUpSubViews];
    }
    return self;
}
- (instancetype)initInKeyWindowWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        [self performSelector:@selector(addToKeyWindow) withObject:nil afterDelay:0.1];
        self.hidden = YES;
        [self setUpSubViews];
    }
    return self;
}


- (void)setUpSubViews
{
     [self.layer setMasksToBounds:YES];
    _autoDocking = YES;
    _draggable = NO;
}

- (void)addToKeyWindow
{
    
    [[UIApplication sharedApplication].keyWindow addSubview:self];

}

- (void)setClickBlock:(void (^)(CBBDraggableButton *))clickBlock
{
    _clickBlock = clickBlock;
    
    if (_clickBlock && _draggable) {
        [self addTarget:self action:@selector(buttonTouched) forControlEvents:UIControlEventTouchUpInside];
    }
}

- (void)buttonTouched {
    [self performSelector:@selector(executeButtonTouchedBlock) withObject:nil afterDelay:0];
}

- (void)executeButtonTouchedBlock {
    
    _clickBlock(self);
    
}

#pragma mark  ------ touth 代理 ------
/** 开始 */
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    
    [super touchesBegan:touches withEvent:event];
    /** 获取 开始位置 */
    _beginLocation = [[touches anyObject] locationInView:self];
}


/** 移动 */
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{

    UITouch *touch = [touches anyObject];
    CGPoint currentLocation = [touch locationInView:self];
    
    float offsetX = currentLocation.x - _beginLocation.x;
    float offsetY = currentLocation.y - _beginLocation.y;
    self.center = CGPointMake(self.center.x + offsetX, self.center.y + offsetY);
 
    CGRect superviewFrame = self.superview.frame;
    CGRect frame = self.frame;
    CGFloat leftLimitX = frame.size.width / 2;
    CGFloat rightLimitX = superviewFrame.size.width - leftLimitX;
    CGFloat topLimitY = frame.size.height / 2;
    CGFloat bottomLimitY = superviewFrame.size.height - topLimitY - 49 ;
    if (self.center.x > rightLimitX) {
        self.center = CGPointMake(rightLimitX, self.center.y);
    }else if (self.center.x <= leftLimitX) {
        self.center = CGPointMake(leftLimitX, self.center.y);
    }
    if (self.center.y > bottomLimitY) {
        self.center = CGPointMake(self.center.x, bottomLimitY );
    }else if (self.center.y <= topLimitY){
        self.center = CGPointMake(self.center.x, topLimitY);
    }
    
    
}

/** 结束 */
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesEnded: touches withEvent: event];
    UITouch *touch = [touches anyObject];
    CGPoint currentLocation = [touch locationInView:self];
    
    /** 获取偏移 */
    float offsetX = currentLocation.x - _beginLocation.x;
    float offsetY = currentLocation.y - _beginLocation.y;
    
    NSLog(@"----%f-----%f",offsetY,offsetY);
    if (pow(offsetX,2) + pow(offsetY,2) <0.1) {
        /** 判断 如果拖拽  间距 < 0.1  进行点击 */
        _draggable = NO;
        [self executeButtonTouchedBlock];
        return;
    }
    
    
    CGRect superviewFrame = self.superview.frame;
    CGRect frame = self.frame;
    CGFloat middleX = superviewFrame.size.width / 2;
    if (self.center.x >= middleX) {
        [UIView animateWithDuration:0.2f animations:^{
            self.center = CGPointMake(superviewFrame.size.width - frame.size.width / 2, self.center.y);
            
        } completion:^(BOOL finished) {
            
        }];
    } else {
        [UIView animateWithDuration:0.4 animations:^{
            self.center = CGPointMake(frame.size.width / 2, self.center.y);
            
        } completion:^(BOOL finished) {
            
        }];
    }
    
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesCancelled:touches withEvent:event];
}







/** 删除 */
+ (void)removeAllFromView:(id)superView {
    for (id view in [superView subviews]) {
        if ([view isKindOfClass:[CBBDraggableButton class]]) {
            [view removeFromSuperview];
        }
    }
}
/** 显示 隐藏 */
- (void)showWindow
{
    self.hidden = NO;
}
- (void)dissMissWindow;
{
    self.hidden = YES;
}
初始化
  CBBDraggableButton *draggableButton = [CBBDraggableButton sharedInstance];
    draggableButton.frame = CGRectMake( [UIScreen mainScreen].bounds.size.width - 90, [UIScreen mainScreen].bounds.size.height - 49 - 15 - 75, 75, 75) ;
    [draggableButton setAutoDocking:YES];
    draggableButton.hidden = YES;
    [self.view addSubview:draggableButton];
    
    draggableButton.backgroundColor = [UIColor redColor];
    draggableButton.layer.cornerRadius = 75/2;
    draggableButton.clipsToBounds = YES;
    [[CBBDraggableButton sharedInstance ] showWindow];
    [CBBDraggableButton sharedInstance].clickBlock = ^(CBBDraggableButton *clickBlock) {
       
        UIAlertController*alertController = [[UIAlertController alloc] init];
        
        UIAlertAction*alertAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
            
        }];
        
        [alertController addAction:alertAction];
        
        [alertController addAction:({
            
            UIAlertAction*action = [UIAlertAction actionWithTitle:@"拍照" style:UIAlertActionStyleDefault handler:^(UIAlertAction *  action) {
                
            }];
            
            action;
            
        })];
        
        [alertController addAction:({
            
            UIAlertAction*action = [UIAlertAction actionWithTitle:@"从相册选择" style:UIAlertActionStyleDefault handler:^(UIAlertAction *  action) {
                
                //UIAlertActionStyleDestructive字体是红色的  
                
                
                
            }];  
            
            action;  
            
        })];  
        
          [self presentViewController:alertController animated:YES completion:nil];  
    };

2017年06月26日 未完待续。。 有什么问题可以提出意见。。基本上就是所有代码了,需要源码留下邮箱。。后续上传Git

很多问题不见得会出在你身上,但你亦需要想法解决问题,否则就会变成你的问题。

你可能感兴趣的:(仿照苹果自带的吸附按钮)