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

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

作者: 数字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