美文网首页
小窗播放基础图层展示和处理笔记

小窗播放基础图层展示和处理笔记

作者: 数字d | 来源:发表于2021-07-29 11:33 被阅读0次

    需求:
    直播观众端退出直播间时候,进行小窗播放
    小窗能够随手指长按拖拽移动(以下用红色图层的拖拽实现)
    小窗上的按钮能够进行操作关闭(以下用灰色图层的点击事件实现)
    小窗的点击事件能够进入到直播详情页面(以下用红色图层的点击事件实现)
    小窗的区域限制在状态栏和导航栏中间(以下用透明的blueview实现)
    效果:

    IMG1
    另外:红色图层位置如果如果被拖拽到了能遮住住了下层的绿色图层,那么绿色图层点击无效,如果没有被遮盖,那么绿色图层点击有效实现见
    效果:
    IMG2.png

    1.拖拽手势的实现(红色view)

    YZDraggeMoveView.h

    #import <UIKit/UIKit.h>
    #define RCDRAGGABLEBUTTON_VERSION @"0.4"
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface YZDraggeMoveView : UIView {
        BOOL _isDragging;
        BOOL _singleTapCanceled;
        BOOL _skipTapEventOnce;
        BOOL _willBeRemoved;
        BOOL _draggableAfterLongPress;
        BOOL _isRecordingDraggingPathEnabled;
        
        CGPoint _touchBeginPoint;
        CGPoint _moveBeginPoint;
        
        UIBezierPath *_draggingPath;
        
        NSMutableArray *_traceButtons;
        NSTimer *_autoAddTraceButtonTimer;
        NSTimer *_traceDismissTimer;
    }
    @property (nonatomic) BOOL draggable;
    @property (nonatomic) BOOL autoDocking;
    @property (nonatomic) BOOL isTraceEnabled;
    @property (nonatomic) BOOL dragOutOfBoundsEnabled;
    
    @property (nonatomic) CGPoint dockPoint;
    @property (nonatomic) CGFloat limitedDistance;
    
    @property (nonatomic, copy) void(^longPressBlock)(YZDraggeMoveView *button);
    @property (nonatomic, copy) void(^longPressEndedBlock)(YZDraggeMoveView *button);
    
    @property (nonatomic, copy) void(^tapBlock)(YZDraggeMoveView *button);
    @property (nonatomic, copy) void(^doubleTapBlock)(YZDraggeMoveView *button);
    
    @property (nonatomic, copy) void(^draggingBlock)(YZDraggeMoveView *button);
    @property (nonatomic, copy) void(^dragEndedBlock)(YZDraggeMoveView *button);
    @property (nonatomic, copy) void(^dragCancelledBlock)(YZDraggeMoveView *button);
    
    @property (nonatomic, copy) void(^autoDockingBlock)(YZDraggeMoveView *button);
    @property (nonatomic, copy) void(^autoDockEndedBlock)(YZDraggeMoveView *button);
    
    @property (nonatomic, copy) void(^layerConfigBlock)(YZDraggeMoveView *button);
    
    @property (nonatomic, copy) void(^willBeRemovedBlock)(YZDraggeMoveView *button);
    
    - (id)initInView:(id)view WithFrame:(CGRect)frame;
    
    - (BOOL)isDragging;
    
    + (NSString *)version;
    
    + (NSArray *)itemsInView:(id)view;
    - (BOOL)isInView:(id)view;
    
    - (BOOL)isInsideRect:(CGRect)rect;
    - (BOOL)isIntersectsRect:(CGRect)rect;
    - (BOOL)isCrossedRect:(CGRect)rect;
    
    - (void)cleanAllCodeBlocks;
    
    + (void)removeAllFromView:(id)view;
    
    + (void)removeFromView:(id)view withTag:(NSInteger)tag;
    + (void)removeFromView:(id)view withTags:(NSArray *)tags;
    
    + (void)removeAllFromView:(id)view insideRect:(CGRect)rect;
    - (void)removeFromSuperviewInsideRect:(CGRect)rect;
    
    + (void)removeAllFromView:(id)view intersectsRect:(CGRect)rect;
    - (void)removeFromSuperviewIntersectsRect:(CGRect)rect;
    
    + (void)removeAllFromView:(id)view crossedRect:(CGRect)rect;
    - (void)removeFromSuperviewCrossedRect:(CGRect)rect;
    
    + (void)allInView:(id)view moveToPoint:(CGPoint)point animatedWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options completion:(void (^)())completion;
    + (void)inView:(id)view withTag:(NSInteger)tag moveToPoint:(CGPoint)point animatedWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options completion:(void (^)())completion;
    + (void)inView:(id)view withTags:(NSArray *)tags moveToPoint:(CGPoint)point animatedWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options completion:(void (^)())completion;
    - (void)moveToPoint:(CGPoint)point animatedWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options completion:(void (^)())completion;
    
    + (void)allInView:(id)view moveToPoint:(CGPoint)point;
    + (void)inView:(id)view withTag:(NSInteger)tag moveToPoint:(CGPoint)point;
    + (void)inView:(id)view withTags:(NSArray *)tags moveToPoint:(CGPoint)point;
    - (void)moveToPoint:(CGPoint)point;
    
    - (CGFloat)distanceFromPoint:(CGPoint)point;
    
    - (CGFloat)distanceFromRect:(CGRect)rect;
    
    - (void)setDraggableAfterLongPress:(BOOL)draggableAfterLongPress;
    
    - (void)startRecordDraggingPath;
    - (UIBezierPath *)stopRecordDraggingPath;
    - (BOOL)isRecordingDraggingPath;
    - (UIBezierPath *)draggingPath;
    
    - (BOOL)checkIfExceedingLimitedDistanceThenFixIt:(BOOL)fixIt;
    - (BOOL)checkIfOutOfBoundsThenFixIt:(BOOL)fixIt;
    @end
    
    NS_ASSUME_NONNULL_END
    
    

    YZDraggeMoveView.m

    #import "YZDraggeMoveView.h"
    
    
    #define RC_DEFAULT_DELAY_TIME 0.f
    #define RC_DEFAULT_ANIMATE_DURATION 0.2f
    #define RC_DOUBLE_TAP_TIME_INTERVAL 0.36f
    
    #define RC_TRACES_NUMBER 10
    #define RC_TRACE_DISMISS_TIME_INTERVAL 0.05f
    
    #define RC_POINT_NULL CGPointMake(MAXFLOAT, -MAXFLOAT)
    @interface YZDraggeMoveView()<UIGestureRecognizerDelegate>
    
    @end
    
    @implementation YZDraggeMoveView
    
    - (id)init {
        self = [super init];
        
        if (self) {
            [self defaultSetting];
        }
        return self;
    }
    
    - (id)initWithFrame:(CGRect)frame {
        self = [super initWithFrame:frame];
        
        if (self) {
            [self defaultSetting];
        }
        return self;
    }
    
    - (id)initInView:(id)view WithFrame:(CGRect)frame {
        self = [super initWithFrame:frame];
        
        if (self) {
            [self defaultSetting];
    
            if (view) {
                [view addSubview:self];
            } else {
                [self performSelector:@selector(addButtonToKeyWindow) withObject:nil afterDelay:RC_DEFAULT_DELAY_TIME];
            }
        }
        return self;
    }
    
    #pragma mark Default Setting
    
    - (void)defaultSetting {
        self.userInteractionEnabled = YES;
        _draggable = YES;
        _autoDocking = NO;
        _singleTapCanceled = NO;
        _willBeRemoved = NO;
        _draggableAfterLongPress = NO;
        _dragOutOfBoundsEnabled = NO;
        _isRecordingDraggingPathEnabled = NO;
        
        [self setDockPoint:RC_POINT_NULL];
        
        [self setLimitedDistance: -1.f];
        
        self.isTraceEnabled = NO;
        _traceButtons = [[NSMutableArray alloc] initWithCapacity:RC_TRACES_NUMBER];
    }
    
    #pragma mark Add Button To KeyWindow
    
    - (void)addButtonToKeyWindow {
        [[UIApplication sharedApplication].keyWindow addSubview:self];
    }
    
    #pragma mark - Gesture Recognizer Handle
    
    - (void)gestureRecognizerHandle:(UILongPressGestureRecognizer *)gestureRecognizer {
        switch ([gestureRecognizer state]) {
            case UIGestureRecognizerStateBegan: {
                if (_longPressBlock) {
                    _longPressBlock(self);
                }
                
                _skipTapEventOnce = YES;
                
                if (_draggableAfterLongPress) {
                    _draggable = YES;
                }
            }
                break;
            case UIGestureRecognizerStateEnded:
            case UIGestureRecognizerStateCancelled: {
                if (_longPressEndedBlock) {
                    _longPressEndedBlock(self);
                }
            }
                break;
            default:
                break;
        }
    }
    
    #pragma mark - Blocks
    #pragma mark Single Tap Block
    
    - (void)setTapBlock:(void (^)(YZDraggeMoveView *))tapBlock {
        _tapBlock = tapBlock;
        
        if (_tapBlock) {
    //        [self addTarget:self action:@selector(buttonTouched) forControlEvents:UIControlEventTouchUpInside];
            UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(editzafNameAction)];
            tap.delegate = self;
            [self addGestureRecognizer:tap];
        }
    }
    
    #pragma mark Long Tap Block
    
    - (void)setLongPressBlock:(void (^)(YZDraggeMoveView *))longPressBlock {
        _longPressBlock = longPressBlock;
        if (_longPressBlock) {
            [self addLongPressToButton];
        }
    }
    
    - (void)addLongPressToButton {
        for (id gestureRecognizer in self.gestureRecognizers) {
            if ([gestureRecognizer isKindOfClass:[UILongPressGestureRecognizer class]]) {
                [self removeGestureRecognizer:gestureRecognizer];
            }
        }
        
        UILongPressGestureRecognizer *longPressGestureRecognizer = [[UILongPressGestureRecognizer alloc] init];
        longPressGestureRecognizer.cancelsTouchesInView = NO;
        [longPressGestureRecognizer addTarget:self action:@selector(gestureRecognizerHandle:)];
        [longPressGestureRecognizer setAllowableMovement:0];
        [self addGestureRecognizer:longPressGestureRecognizer];
    }
    
    #pragma mark - Touch Event Handle
    
    - (void)buttonTouched {
        [self performSelector:@selector(executeButtonTouchedBlock) withObject:nil afterDelay:(_doubleTapBlock ? RC_DOUBLE_TAP_TIME_INTERVAL : 0)];
    }
    
    - (void)executeButtonTouchedBlock {
        if ( !_singleTapCanceled && _tapBlock && !_isDragging && !_skipTapEventOnce) {
            _tapBlock(self);
        } else {
            _skipTapEventOnce = NO;
        }
    }
    
    #pragma mark - Touch Delegate
    
    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
        _isDragging = NO;
        
        [super touchesBegan:touches withEvent:event];
        
        UITouch *touch = [touches anyObject];
        
        if (touch.tapCount == 2) {
            if (_doubleTapBlock) {
                _singleTapCanceled = YES;
                _doubleTapBlock(self);
            }
        } else {
            _singleTapCanceled = NO;
        }
        
        _touchBeginPoint = [[touches anyObject] locationInView:self];
    }
    
    - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
        if (_draggable) {
            _isDragging = YES;
            
            UITouch *touch = [touches anyObject];
            CGPoint currentPoint = [touch locationInView:self];
            
            float offsetX = currentPoint.x - _touchBeginPoint.x;
            float offsetY = currentPoint.y - _touchBeginPoint.y;
            
            [self resetCenter:CGPointMake(self.center.x + offsetX, self.center.y + offsetY)];
            
            if (self.isTraceEnabled) {
                [self addTraceButton];
            }
            
            if (_isRecordingDraggingPathEnabled) {
                [_draggingPath addLineToPoint:self.center];
            }
            
            if (_draggingBlock) {
                _draggingBlock(self);
            }
            
            _skipTapEventOnce = YES;
        }
    }
    
    - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
        [super touchesEnded: touches withEvent: event];
        
        if (_isDragging && _dragEndedBlock) {
            _dragEndedBlock(self);
            _singleTapCanceled = YES;
        }
        
        if (_isDragging && _autoDocking) {
            if ( ![self isDockPointAvailable]) {
                [self dockingToBorder];
            } else {
                [self dockingToPoint];
            }
        }
        
        if (_draggableAfterLongPress) {
            _draggable = NO;
        }
    
        _isDragging = NO;
    }
    
    - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
    {
        [super touchesCancelled:touches withEvent:event];
    
        _isDragging = NO;
        _singleTapCanceled = YES;
        
        if (_draggableAfterLongPress) {
            _draggable = NO;
        }
        
        if (_dragCancelledBlock) {
            _dragCancelledBlock(self);
        }
    }
    
    - (BOOL)isDragging {
        return _isDragging;
    }
    
    #pragma mark - Docking
    
    - (BOOL)isDockPointAvailable {
        return !CGPointEqualToPoint(self.dockPoint, RC_POINT_NULL);
    }
    
    - (void)dockingToBorder {
        CGRect superviewFrame = self.superview.frame;
        CGRect frame = self.frame;
        CGFloat middleX = superviewFrame.size.width / 2;
        
        [UIView animateWithDuration:RC_DEFAULT_ANIMATE_DURATION animations:^{
            if (self.center.x >= middleX) {
                self.center = CGPointMake(superviewFrame.size.width - frame.size.width / 2, self.center.y);
            } else {
                self.center = CGPointMake(frame.size.width / 2, self.center.y);
            }
            
            if (_autoDockingBlock) {
                _autoDockingBlock(self);
            }
        } completion:^(BOOL finished) {
            if (_isRecordingDraggingPathEnabled) {
                [_draggingPath addLineToPoint:self.center];
            }
            
            if (_autoDockEndedBlock) {
                _autoDockEndedBlock(self);
            }
        }];
    }
    
    - (void)dockingToPoint {
        [UIView animateWithDuration:RC_DEFAULT_ANIMATE_DURATION animations:^{
            self.center = self.dockPoint;
            
            if (_autoDockingBlock) {
                _autoDockingBlock(self);
            }
        } completion:^(BOOL finished) {
            if (_isRecordingDraggingPathEnabled) {
                [_draggingPath addLineToPoint:self.center];
            }
            
            if (_autoDockEndedBlock) {
                _autoDockEndedBlock(self);
            }
        }];
    }
    
    #pragma mark - Dragging Distance And Checkings
    
    - (BOOL)isLimitedDistanceAvailable {
        return (self.limitedDistance > 0);
    }
    
    - (BOOL)checkIfExceedingLimitedDistanceThenFixIt:(BOOL)fixIt {
        CGPoint tmpDPoint = CGPointMake(self.center.x - self.dockPoint.x, self.center.y - self.dockPoint.y);
        
        CGFloat distance = [self distanceFromPoint:self.dockPoint];
        
        BOOL willExceedingLimitedDistance = (distance >= self.limitedDistance);
        
        if (willExceedingLimitedDistance && fixIt) {
            self.center = CGPointMake(tmpDPoint.x * self.limitedDistance / distance + self.dockPoint.x, tmpDPoint.y * self.limitedDistance / distance + self.dockPoint.y);
        }
        
        return willExceedingLimitedDistance;
    }
    
    - (BOOL)checkIfOutOfBoundsThenFixIt:(BOOL)fixIt {
        BOOL willOutOfBounds = YES;
        
        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;
        
        CGPoint fixedPoint = self.center;
        
        if (self.center.x > rightLimitX) {
            fixedPoint.x = rightLimitX;
        }else if (self.center.x <= leftLimitX) {
            fixedPoint.x = leftLimitX;
        }
        
        if (self.center.y > bottomLimitY) {
            fixedPoint.y = bottomLimitY;
        }else if (self.center.y <= topLimitY){
            fixedPoint.y = topLimitY;
        }
        
        if (CGPointEqualToPoint(self.center, fixedPoint)) {
            willOutOfBounds = NO;
        } else if (fixIt) {
            self.center = fixedPoint;
        }
        
        return willOutOfBounds;
    }
    
    #pragma mark - Version
    
    + (NSString *)version {
        return RCDRAGGABLEBUTTON_VERSION;
    }
    
    #pragma mark - Common Tools
    
    #pragma mark Items In View
    
    + (NSArray *)itemsInView:(id)view {
        if ( !view) {
            view = [UIApplication sharedApplication].keyWindow;
        }
        
        NSMutableArray *subviews = [[NSMutableArray alloc] init];
        
        for (id subview in [view subviews]) {
            if ([subview isKindOfClass:[YZDraggeMoveView class]]) {
                [subviews addObject:subview];
            }
        }
        
        return subviews;
    }
    
    - (BOOL)isInView:(id)view {
        return [self.superview isEqual:view];
    }
    
    #pragma mark Rect Detecter
    
    - (BOOL)isInsideRect:(CGRect)rect {
        return  CGRectContainsRect(rect, self.frame);
    }
    
    - (BOOL)isIntersectsRect:(CGRect)rect {
        return  CGRectIntersectsRect(rect, self.frame);
    }
    
    - (BOOL)isCrossedRect:(CGRect)rect {
        return  [self isIntersectsRect:rect] && ![self isInsideRect:rect];
    }
    
    #pragma mark Clean All Code Blocks
    
    - (void)cleanAllCodeBlocks {
        self.longPressBlock = nil;
        self.tapBlock = nil;
        self.doubleTapBlock = nil;
        
        self.draggingBlock = nil;
        self.dragEndedBlock = nil;
        
        self.autoDockingBlock = nil;
        self.autoDockEndedBlock = nil;
    }
    
    #pragma mark Reset Center
    
    - (void)resetCenter:(CGPoint)center {
        self.center = center;
        
        if ([self isDockPointAvailable] && [self isLimitedDistanceAvailable]) {
            [self checkIfExceedingLimitedDistanceThenFixIt: YES];
        } else if ( !self.dragOutOfBoundsEnabled) {
            [self checkIfOutOfBoundsThenFixIt: YES];
        }
    }
    
    #pragma mark - Remove All From View
    
    + (void)removeAllFromView:(id)view {
        for (id subview in [self itemsInView:view]) {
            [subview removeFromSuperview];
        }
    }
    
    #pragma mark - Remove From View With Tag(s)
    
    + (void)removeFromView:(id)view withTag:(NSInteger)tag {
        for (YZDraggeMoveView *subview in [self itemsInView:view]) {
            if (subview.tag == tag) {
                [subview removeFromSuperview];
            }
        }
    }
    
    + (void)removeFromView:(id)view withTags:(NSArray *)tags {
        for (NSNumber *tag in tags) {
            [YZDraggeMoveView removeFromView:view withTag:[tag intValue]];
        }
    }
    
    #pragma mark - Remove From View Inside Rect
    
    + (void)removeAllFromView:(id)view insideRect:(CGRect)rect {
        for (id subview in [self itemsInView:view]) {
            if ([subview isInsideRect:rect]) {
                [subview removeFromSuperview];
            }
        }
    }
    
    - (void)removeFromSuperviewInsideRect:(CGRect)rect {
        if (self.superview && [self isInsideRect:rect]) {
            [self removeFromSuperview];
        }
    }
    
    #pragma mark - Remove From View Overlapped Rect
    
    + (void)removeAllFromView:(id)view intersectsRect:(CGRect)rect {
        for (id subview in [self itemsInView:view]) {
            if ([subview isIntersectsRect:rect]) {
                [subview removeFromSuperview];
            }
        }
    }
    
    - (void)removeFromSuperviewIntersectsRect:(CGRect)rect {
        if (self.superview && [self isIntersectsRect:rect]) {
            [self removeFromSuperview];
        }
    }
    
    #pragma mark - Remove From View Crossed Rect
    
    + (void)removeAllFromView:(id)view crossedRect:(CGRect)rect {
        for (id subview in [self itemsInView:view]) {
            if ([subview isCrossedRect:rect]) {
                [subview removeFromSuperview];
            }
        }
    }
    
    - (void)removeFromSuperviewCrossedRect:(CGRect)rect {
        if (self.superview && [self isInsideRect:rect]) {
            [self removeFromSuperview];
        }
    }
    
    #pragma mark - removeFromSuperview
    
    - (void)removeFromSuperview {
        if (_willBeRemovedBlock) {
            _willBeRemovedBlock(self);
        }
        _willBeRemoved = YES;
        
        [self cleanAllCodeBlocks];
        
        [super removeFromSuperview];
    }
    
    #pragma mark - Auto Move To Point
    
    + (void)allInView:(id)view moveToPoint:(CGPoint)point animatedWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options completion:(void (^)())completion {
        for (YZDraggeMoveView *subview in [self itemsInView:view]) {
            [subview moveToPoint:point animatedWithDuration:duration delay:delay options:options completion:completion];
        }
    }
    
    + (void)inView:(id)view withTag:(NSInteger)tag moveToPoint:(CGPoint)point animatedWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options completion:(void (^)())completion {
        for (YZDraggeMoveView *subview in [self itemsInView:view]) {
            if (tag == subview.tag) {
                [subview moveToPoint:point animatedWithDuration:duration delay:delay options:options completion:completion];
            }
        }
    }
    
    + (void)inView:(id)view withTags:(NSArray *)tags moveToPoint:(CGPoint)point animatedWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options completion:(void (^)())completion {
        for (NSNumber *tag in tags) {
            [self inView:view withTag:[tag integerValue] moveToPoint:point animatedWithDuration:duration delay:delay options:options completion:completion];
        }
    }
    
    - (void)moveToPoint:(CGPoint)point animatedWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options completion:(void (^)())completion {
        if ( !_willBeRemoved) {
            _moveBeginPoint = self.center;
            
            if (self.isTraceEnabled) {
                [self addTraceButtonsDuringMoveToPoint:point animatedWithDuration:duration delay:delay options:options];
            }
            
            [UIView animateWithDuration:duration delay:delay options:options animations:^{
                [self resetCenter:point];
            } completion:^(BOOL finished) {
                if (_autoAddTraceButtonTimer) {
                    [_autoAddTraceButtonTimer invalidate];
                    _autoAddTraceButtonTimer = nil;
                }
                
                if (_isRecordingDraggingPathEnabled) {
                    [_draggingPath addLineToPoint:self.center];
                }
                
                if (completion) {
                    completion();
                }
            }];
        }
    }
    
    + (void)allInView:(id)view moveToPoint:(CGPoint)point {
        for (YZDraggeMoveView *subview in [self itemsInView:view]) {
            [subview moveToPoint:point];
        }
    }
    
    + (void)inView:(id)view withTag:(NSInteger)tag moveToPoint:(CGPoint)point {
        for (YZDraggeMoveView *subview in [self itemsInView:view]) {
            if (tag == subview.tag) {
                [subview moveToPoint:point];
            }
        }
    }
    
    + (void)inView:(id)view withTags:(NSArray *)tags moveToPoint:(CGPoint)point {
        for (NSNumber *tag in tags) {
            [self inView:view withTag:[tag integerValue] moveToPoint:point];
        }
    }
    
    - (void)moveToPoint:(CGPoint)point {
        [self moveToPoint:point animatedWithDuration:RC_DEFAULT_ANIMATE_DURATION delay:0 options:0 completion:nil];
    }
    
    #pragma mark - Trace
    #pragma mark Dismiss
    
    - (void)addTraceButtonsDuringMoveToPoint:(CGPoint)point animatedWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options {
        
        for (NSInteger count = 0; count < RC_TRACES_NUMBER; count ++) {
            YZDraggeMoveView *traceButton = [self loadTraceButton];
            traceButton.center = _moveBeginPoint;
    
            [self.superview addSubview: traceButton];
    
            [traceButton moveToPoint:point animatedWithDuration: duration + duration * (RC_TRACES_NUMBER - count) / RC_TRACES_NUMBER delay:delay options:options completion:nil];
            
            [traceButton performSelector:@selector(dismissSelf) withObject:nil afterDelay: count * duration / RC_TRACES_NUMBER];
        }
        
        [self.superview bringSubviewToFront:self];
    }
    
    - (YZDraggeMoveView *)loadTraceButton {
        YZDraggeMoveView *traceButton = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:self]];
        
        [traceButton setAlpha:0.8];
    //    [traceButton setSelected:NO];
    //    [traceButton setHighlighted:NO];
        [traceButton defaultSetting];
        
        if (self.layerConfigBlock) {
            self.layerConfigBlock(traceButton);
        }
        
        return traceButton;
    }
    
    - (void)addTraceButton {
    
        if ([_traceButtons count] < RC_TRACES_NUMBER) {
            YZDraggeMoveView *traceButton = [self loadTraceButton];
            [self.superview addSubview: traceButton];
            [_traceButtons addObject:traceButton];
        }
        
        [self.superview bringSubviewToFront:self];
        
        if ( !_traceDismissTimer) {
            _traceDismissTimer = [NSTimer scheduledTimerWithTimeInterval:RC_TRACE_DISMISS_TIME_INTERVAL target:self selector:@selector(dismissTraceButton) userInfo:nil repeats:YES];
        }
    }
    
    - (void)dismissTraceButton {
        if ([_traceButtons count]) {
            [[_traceButtons firstObject] removeFromSuperview];
            [_traceButtons removeObject:[_traceButtons firstObject]];
        } else {
            [_traceDismissTimer invalidate];
            _traceDismissTimer = nil;
        }
    }
    
    - (void)dismissSelf {
        [self setHidden:NO];
        [self performSelector:@selector(removeFromSuperview) withObject:nil afterDelay:RC_TRACE_DISMISS_TIME_INTERVAL];
    }
    
    #pragma mark - Calculate Distance
    #pragma mark From Point
    
    - (CGFloat)distanceFromPoint:(CGPoint)point {
        return hypotf(self.center.x - point.x, self.center.y - point.y);
    }
    
    #pragma mark From Rect
    
    - (CGFloat)distanceFromRect:(CGRect)rect {
        return [self distanceFromPoint:CGPointMake(rect.origin.x + rect.size.width / 2, rect.origin.y + rect.size.height / 2)];
    }
    
    #pragma mark - Draggable After Long Press
    
    - (void)setDraggableAfterLongPress:(BOOL)draggableAfterLongPress {
        _draggableAfterLongPress = draggableAfterLongPress;
        _draggable = NO;
    }
    
    #pragma mark - Record Dragging Path
    
    - (void)startRecordDraggingPath {
        _isRecordingDraggingPathEnabled = YES;
        
        if ( !_draggingPath) {
            _draggingPath = [UIBezierPath bezierPath];
        }
        
        [_draggingPath removeAllPoints];
        
        [_draggingPath moveToPoint:self.center];
    }
    
    - (UIBezierPath *)stopRecordDraggingPath {
        _isRecordingDraggingPathEnabled = NO;
        
        return _draggingPath;
    }
    
    - (BOOL)isRecordingDraggingPath {
        return _isRecordingDraggingPathEnabled;
    }
    
    - (UIBezierPath *)draggingPath {
        if ( !_draggingPath) {
            _draggingPath = [UIBezierPath bezierPath];
        }
        
        return _draggingPath;
    }
    
    @end
    
    

    透过view的事件实现

    YZClearUIView.h

    #import <UIKit/UIKit.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface YZClearUIView : UIView
    
    @end
    
    NS_ASSUME_NONNULL_END
    

    .m

    #import "YZClearUIView.h"
    
    @implementation YZClearUIView
    
    - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
        UIView * hitView = [super hitTest:point withEvent:event];
        if (hitView == self) {
            return nil;
        }
        return hitView;
    }
    - (instancetype)init
    {
        self = [super init];
        if (self) {
            self.userInteractionEnabled = YES;
            self.backgroundColor = [UIColor clearColor];
        }
        return self;
    }
    @end
    

    ViewController.m

    #import "ViewController.h"
    
    //#import "RCDraggableButton.h"
    
    #import "YZDraggeMoveView.h"
    
    #import "YZClearUIView.h"
    
    #import "Masonry.h"
    
    
    
    @interface ViewController ()<UIGestureRecognizerDelegate>
    
    @end
    
    @implementation ViewController
    z
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        UIButton * button = [UIButton buttonWithType:(UIButtonTypeCustom)];
        button.frame = CGRectMake(100, 100, 90, 90);
        button.backgroundColor = [UIColor greenColor];
        [button addTarget:self action:@selector(actionLog) forControlEvents:(UIControlEventTouchUpInside)];
        [self.view addSubview:button];
        
        YZClearUIView * blueView = [[YZClearUIView alloc] initWithFrame:CGRectMake(0, 0, 320, 400)];
    //    blueView.backgroundColor = [UIColor blueColor];
        [self.view addSubview:blueView];
        
        
        YZDraggeMoveView *draggableButton = [[YZDraggeMoveView alloc] initWithFrame:CGRectMake(0, 100, 100, 100)];
        draggableButton.backgroundColor = [UIColor redColor];
        UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(actionTapRed)];
        tap.delegate = self;
        [draggableButton addGestureRecognizer:tap];
            [blueView addSubview:draggableButton];
        
        UIButton * grayBtn = [UIButton buttonWithType:(UIButtonTypeCustom)];
        [blueView addSubview:grayBtn];
        [grayBtn mas_makeConstraints:^(MASConstraintMaker *make) {
            make.width.height.equalTo(@50);
            make.right.equalTo(draggableButton.mas_right);
            make.bottom.equalTo(draggableButton.mas_bottom);
        }];
        grayBtn.backgroundColor = [UIColor grayColor];
        [grayBtn addTarget:self action:@selector(actionGray) forControlEvents:(UIControlEventTouchUpInside)];
    }
    
    -(void)actionGray {
        NSLog(@"点击了红色上的灰色");
    }
    
    -(void)actionLog {
        NSLog(@"透过透明点击绿色");
    }
    
    -(void)actionTapRed {
        NSLog(@"点击了红色");
    }
    

    这里的手势拖拽监听和限制红色被拖拽的view在蓝色透明图层中的效果参看 RCDraggableButton

      pod 'RCDraggableButton', '~> 0.1'
    

    这里cocopods提供的是继承UIButton的子类

    我这里直接将cocopods中的代码复制出来,继承UIView实现了YZDraggeMoveView

    具体的用法和RCDraggableButton用法一致

    相关文章

      网友评论

          本文标题:小窗播放基础图层展示和处理笔记

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