AssistiveTouch热键按钮

作者: Life_小贤 | 来源:发表于2016-07-20 17:31 被阅读143次

    AssistiveTouch热键按钮

    介绍

    • 这是一个挂再界面上的控件,支持自由拖动 isPanMoview 通过这个属性进行设置
    • 这个按钮就是类似于苹果的AssistiveTouch热键按钮一样 可以保留在界面之上

    使用

    • 在使用的时候,要注意的是你把他加在在了哪一个视图上,这会直接影响到使用的效果
    • 创建的时候,首先要注意的就是 setClickBlock 里面的事情 我们看到的效果 都是手动设置的
    • 我们往里面添加 的时候 要注意调用 [- addViewToHotView:] 这个方法来添加

    代码

    HotView.h
    
    //
    //  HotView.h
    //  TouGuApp
    //
    //  Created by tianshikechuang on 16/7/14.
    //  Copyright © 2016年 tianshikechuang. All rights reserved.
    //
    
    #import <UIKit/UIKit.h>
    
    
    
    @class HotView;
    typedef void(^HotViewDidClick)(HotView * hotView,UIButton * button);
    
    
    
    
    @interface HotView : UIView
    
    @property(nonatomic, strong) HotViewDidClick clickBlock;        // 点击的时候调用的block
    
    @property(nonatomic, assign) BOOL isPanMoview;                  // 是否支持拖动(默认为NO)
    @property(nonatomic, assign) BOOL isRotate;                     // 点击的时候是否hot要旋转45°
    @property(nonatomic, assign) CGFloat rotate;                    // 旋转的度数 (默认为 45°)
    @property(nonatomic, assign) CGFloat gapMax;                    // hot按钮与添加的按钮之间的间隙 (默认为 20)
    @property(nonatomic, assign) CGFloat gapMin;                    // 添加的按钮之间的间隙 (默认为 8)
    
    
    /**
     *  创建HotView
     *
     *  @param frame HotView的大小 位置
     *
     *  @return hotView
     */
    + (instancetype)hotViewWithFrame:(CGRect)frame;
    
    
    
    + (HotView *)showHotViewInView:(UIView *)view withFrame:(CGRect)frame;
    + (HotView *)showHotViewInkeyWindowTopWithFrame:(CGRect)frame;
    + (HotView *)showHotViewInVCTop:(UIViewController *)VC withFrame:(CGRect)frame;
    
    
    /**
     *  移动hotView到某个位置
     *
     *  @param point 左上角的位置点
     */
    - (void)moveHotViewTo:(CGPoint)point;
    
    
    
    /**
     *  给展开的HotView添加视图
     *
     *  @param View 要添加的视图/Button
     */
    - (void)addViewToHotView:(UIView *)button;
    
    
    
    /**
     *  热键图片
     *
     *  @param image 热键的背景图片
     */
    - (void)hotViewImage:(UIImage *)image;
    
    
    @end
    
    
    HotView.m
    
    //
    //  HotView.m
    //  TouGuApp
    //
    //  Created by tianshikechuang on 16/7/14.
    //  Copyright © 2016年 tianshikechuang. All rights reserved.
    //
    
    #import "HotView.h"
    
    
    @interface OutRangeView : UIView
    
    @end
    
    @implementation OutRangeView
    
    
    @end
    
    @interface OutRangeButton : UIButton
    
    @end
    
    @implementation OutRangeButton
    
    
    - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event{
        //if内的条件应该为,当触摸点point超出蓝色部分,但在黄色部分时
        if (CGRectContainsPoint(self.bounds, point)){
            return YES;
        }else{
            for (UIView  * view in self.subviews) {
                if ([view isKindOfClass:[OutRangeView class]] && CGRectContainsPoint(view.bounds, [self convertPoint:point toView:view])){
                       return YES;
                }
            }
            
        }
        return NO;
    }
    
    
    ////重写该方法后可以让超出父视图范围的子视图响应事件
    //- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    //    UIView *view = [super hitTest:point withEvent:event];
    //    if (view == nil) {
    //        for (UIView *subView in self.contentView.subviews) {
    //            CGPoint tp = [subView convertPoint:point fromView:self.contentView];
    //            if (CGRectContainsPoint(subView.bounds, tp)) {
    //                view = subView;
    //            }
    //        }
    //    }
    //
    //    return view;
    //}
    
    @end
    
    
    
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ///////////////
    /////////////// 以上为内部内 以方便做按钮超出范围的时候 可以有点击事件
    ///////////////
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    
    
    @interface HotView ()
    
    {
        CGPoint netTranslation;
    }
    @property(nonatomic, strong) OutRangeButton * hotButton;
    
    @property(nonatomic, strong) UIButton * hotPlace;
    @property(nonatomic, strong) UIView * contentView;
    
    
    @property(nonatomic, assign) CGRect orginFrame;
    @property(nonatomic, assign) CGRect screenFrame;
    
    @property(nonatomic, assign) CGRect contentMinFrame;
    @property(nonatomic, assign) CGRect contentMaxFrame;
    
    
    @property(nonatomic, strong) UIPanGestureRecognizer * panGesture;
    @property(nonatomic, strong) NSMutableArray * otherButs;
    
    
    @end
    
    
    
    
    @implementation HotView
    
    
    
    + (HotView *)showHotViewInkeyWindowTopWithFrame:(CGRect)frame{
        UIView * view = [UIApplication sharedApplication].keyWindow;
        return [self showHotViewInView:view withFrame:frame];
    }
    
    
    + (HotView *)showHotViewInVCTop:(UIViewController *)VC withFrame:(CGRect)frame{
        UIView * view;
        if (VC.tabBarController) {
            view = VC.tabBarController.view;
        }else if (VC.navigationController){
            view = VC.navigationController.view;
        }else{
            view = VC.view;
        }
        return [self showHotViewInView:view withFrame:frame];
    }
    
    
    + (HotView *)showHotViewInView:(UIView *)view withFrame:(CGRect)frame{
        HotView * hot = [HotView hotViewWithFrame:frame];
        [view addSubview:hot];
        return hot;
    }
    
    
    + (instancetype)hotViewWithFrame:(CGRect)frame{
        return [[self alloc] initWithFrame:frame];
    }
    
    
    
    
    
    - (void)moveHotViewTo:(CGPoint)point{
        CGRect frame = self.frame;
        frame.origin = point;
        self.frame = frame;
        self.orginFrame = frame;
    }
    
    - (void)addViewToHotView:(UIView *)button{
        
        [self.otherButs addObject:button];
    }
    
    - (void)hotViewImage:(UIImage *)image{
    
        self.hotPlace = [[UIButton alloc] initWithFrame:self.hotButton.bounds];
        self.hotPlace.userInteractionEnabled = NO;
        [self.hotButton addSubview:self.hotPlace];
        [self.hotPlace setBackgroundImage:image forState:UIControlStateNormal];
    }
    
    
    
    - (instancetype)initWithFrame:(CGRect)frame{
        
        if (self = [super initWithFrame:frame]) {
            self.orginFrame = frame;
            self.screenFrame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);
            CGFloat wdith = frame.size.width;
            self.contentMaxFrame = CGRectMake(0, -wdith, frame.size.width, wdith);
            self.contentMinFrame = CGRectMake(0, 0, frame.size.width, 0);
            
            self.gapMax = 20;
            self.gapMin = 8;
            self.isRotate = YES;
            self.rotate = M_PI_4;
            
            [self addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction)]];
            
            [self addSubview:self.hotButton];
            
            [self addGestureRecognizer:self.panGesture];
            
            self.otherButs = [NSMutableArray array];
        }
        return self;
    }
    
    - (OutRangeButton *)hotButton{
        
        if (!_hotButton) {
            _hotButton = [[OutRangeButton alloc] initWithFrame:self.bounds];
            _hotButton.backgroundColor = [UIColor colorWithRed:0.5 green:0.5 blue:0.50 alpha:0.5];
            _hotButton.layer.cornerRadius = self.bounds.size.width/2;
            _hotButton.layer.borderColor = [UIColor colorWithRed:0.8 green:0.8 blue:0.8 alpha:0.8].CGColor;
            _hotButton.layer.borderWidth = 5;
            [_hotButton addTarget:self action:@selector(hotButtonAction:) forControlEvents:UIControlEventTouchUpInside];
            
            self.contentView = [[OutRangeView alloc] initWithFrame:self.contentMinFrame];
    //        self.contentView.backgroundColor = [UIColor grayColor];
            self.contentView.clipsToBounds = YES;
            [_hotButton addSubview:self.contentView];
     
        }
        return _hotButton;
    }
    
    // 开发者自由定义的按钮之类的frame
    - (void)layoutContentViews{
        
        
        __block CGFloat height;
        __block CGFloat width;
        [self.otherButs enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            
            UIView * view = obj;
            CGRect viewFrame = view.frame;
            
            if (idx == 0) {
                height = 0.001;
                width = viewFrame.size.width;
            }
            
            viewFrame.origin = CGPointMake(0, height);
            viewFrame.size = CGSizeMake(width, viewFrame.size.height);
            view.frame = viewFrame;
            height = height + viewFrame.size.height + self.gapMin;
            
            if ([obj isKindOfClass:[UIControl class]]) {
                [(UIControl *)view addTarget:self action:@selector(tapAction) forControlEvents:UIControlEventTouchUpInside];
            }else{
                [view addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction)]];
            }
            
            [self.contentView addSubview:view];
            
        }];
        
        CGRect frame = self.contentMaxFrame;
        CGFloat orginW = self.orginFrame.size.width;
        frame.size = CGSizeMake(width, height + self.gapMin);
        frame.origin = CGPointMake((orginW - width)/2.0, - frame.size.height);
        self.contentMaxFrame = frame;
        self.contentView.frame = frame;
        
        
    }
    
    
    // 定死了的按钮之类的frame
    //- (void)layoutContentViews{
    //    
    //    int count = (int)self.otherButs.count;
    //    CGRect frame = self.contentMaxFrame;
    //    frame.size = CGSizeMake(frame.size.width, (frame.size.width + 10 )* count + 30);
    //    frame.origin = CGPointMake(frame.origin.x, - frame.size.height);
    //    self.contentMaxFrame = frame;
    //    self.contentView.frame = frame;
    //
    //    CGSize equlSize = CGSizeMake(frame.size.width, frame.size.width);
    //    [self.otherButs enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
    //        
    //        UIView * view = obj;
    //        CGRect viewFrame;
    //        viewFrame.origin = CGPointMake(0, idx * (equlSize.width + 10));
    //        viewFrame.size = equlSize;
    //        view.frame = viewFrame;
    //        [view addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction)]];
    //        [self.contentView addSubview:view];
    //        
    //    }];
    //    
    //    
    //}
    
    
    - (UIPanGestureRecognizer *)panGesture{
        if (!_panGesture) {
            _panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGestureAction:)];
        }
        return _panGesture;
    }
    
    
    // 拖转手势的处理事件
    - (void)panGestureAction:(UIPanGestureRecognizer *)sender{
        
        if (!self.isPanMoview) {
            return ;
        }
        
        
        if(sender.state==UIGestureRecognizerStateBegan){
            netTranslation = sender.view.frame.origin;
            
        }
        
        //得到拖的过程中的xy坐标
        CGPoint translation=[sender translationInView:sender.view.superview];
        
        
        CGFloat x = translation.x + netTranslation.x;
        CGFloat y = translation.y + netTranslation.y;
        CGFloat w = self.orginFrame.size.width;
        CGFloat h = self.orginFrame.size.height;
        
        //平移图片CGAffineTransformMakeTranslation
        sender.view.frame = CGRectMake(x, y , w, h);
    
        
        //状态结束,保存数据
        if(sender.state==UIGestureRecognizerStateEnded){
            [self makeViewInSuper:sender.view];
            
            self.orginFrame = sender.view.frame;
            netTranslation = self.orginFrame.origin;
        }
    }
    
    
    
    
    // 接触到空白地方 就缩小到热键
    - (void)tapAction{
        [self hotButtonAction:self.hotButton];
    }
    
    // 热键的点击事件
    - (void)hotButtonAction:(UIButton *)sender{
        
        sender.selected = !sender.selected;
        self.hotPlace.selected = sender.selected;
        netTranslation = self.orginFrame.origin;
        
        if(sender.selected){
            
            [UIView animateWithDuration:0.3 animations:^{
                self.frame = self.screenFrame;
                self.hotButton.frame = self.orginFrame;
                self.contentView.frame = self.contentMaxFrame;
            }];
            
            [self layoutContentViews];
            
            [self removeGestureRecognizer:self.panGesture];
            [self.hotButton addGestureRecognizer:self.panGesture];
        }else{
            
            
            [UIView animateWithDuration:0.3 animations:^{
                self.contentView.frame = self.contentMinFrame;
                self.frame = self.orginFrame;
                self.hotButton.frame = self.bounds;
                [self setBackgroundColor:[UIColor clearColor]];
                
            } completion:^(BOOL finished) {
               
                [self.contentView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
            }];
            
            [self addGestureRecognizer:self.panGesture];
            [self.hotButton removeGestureRecognizer:self.panGesture];
            
        }
        
        // 设置点击的时候 有旋转的效果
        if (self.isRotate) //如果需要 就旋转
        [UIView animateWithDuration:0.5 animations:^{
            
            if (self.hotPlace.selected) {
                self.hotPlace.transform = CGAffineTransformMakeRotation(self.rotate);
            }else{
                self.hotPlace.transform = CGAffineTransformIdentity;
            }
        }];
        
        // block的调用
        if (self.clickBlock) {
            self.clickBlock(self,sender);
        }
    }
    
    
    ////判断某个点在不在 某个视图上
    //+ (BOOL)point:(CGPoint)point isInView:(UIView *)view{
    //    
    //    
    //    CGFloat x = point.x;
    //    CGFloat y = point.y;
    //    CGFloat w = view.frame.size.width;
    //    CGFloat h = view.frame.size.height;
    //
    //    BOOL isOn = NO;
    //    if (x > 0 && y > 0 && x < w && y < h) {
    //        isOn = YES;
    //    }
    //    return isOn;
    //}
    
    
    
    - (void)makeViewInSuper:(UIView *)view{
        
        CGFloat x = view.frame.origin.x;
        CGFloat y = view.frame.origin.y;
        CGFloat w = view.frame.size.width;
        CGFloat h = view.frame.size.height;
        
        if (x < 0 && y < 0) {
            [UIView animateWithDuration:0.5 animations:^{
                view.frame = CGRectMake(5, 5 , w, h);
            }];
        }else if (x + w > view.superview.bounds.size.width && y + h > view.superview.bounds.size.height){
            
            [UIView animateWithDuration:0.5 animations:^{
                view.frame = CGRectMake(view.superview.bounds.size.width - w - 5, view.superview.bounds.size.height - h -5 , w, h);
            }];
            
        }else if (x < 0 && y + h > view.superview.bounds.size.height) {
            [UIView animateWithDuration:0.5 animations:^{
                view.frame = CGRectMake(5, view.superview.bounds.size.height - h -5 , w, h);
            }];
        }else if (x + w > view.superview.bounds.size.width && y < 0){
            
            [UIView animateWithDuration:0.5 animations:^{
                view.frame = CGRectMake(view.superview.bounds.size.width - w - 5, 5, w, h);
            }];
            
        }else if (x < 0) {
            [UIView animateWithDuration:0.5 animations:^{
                view.frame = CGRectMake(5, y , w, h);
            }];
            
        }else if (x + w > view.superview.bounds.size.width){
            
            [UIView animateWithDuration:0.5 animations:^{
                view.frame = CGRectMake(view.superview.bounds.size.width - w - 5, y, w, h);
            }];
            
        }else if (y < 0 ) {
            [UIView animateWithDuration:0.5 animations:^{
                view.frame = CGRectMake(x, 5 , w, h);
            }];
        }else if (y + h > view.superview.bounds.size.height){
            [UIView animateWithDuration:0.5 animations:^{
                view.frame = CGRectMake(x, view.superview.bounds.size.height - h -5 , w, h);
            }];
        }
        
    
    }
    
    @end
    
    

    相关文章

      网友评论

        本文标题:AssistiveTouch热键按钮

        本文链接:https://www.haomeiwen.com/subject/cpwvjttx.html