美文网首页
创建顶层显示可移动悬浮窗

创建顶层显示可移动悬浮窗

作者: 蓝天白云_Sam | 来源:发表于2020-09-14 11:30 被阅读0次
    • WSFloatingWndMgr.h
    #import <Foundation/Foundation.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface WSFloatingWndMgr : NSObject
    DECL_SINGLETON(WSFloatingWndMgr);
    
    @property(nonatomic, strong,readonly) UIView * floatingView;
    
    -(BOOL) showFloatingWnsWithView:(UIView *) floatingView;
    -(BOOL) showFloatingWnsWithView:(UIView *) floatingView frame:(CGRect) frame;
    -(void) removeFloatingView;
    @end
    
    NS_ASSUME_NONNULL_END
    
    
    • WSFloatingWndMgr.m
    #import "WSFloatingWndMgr.h"
    
    #define WSSafeContentPadding 16
    
    @interface WSFloatingWndMgr ()
    
    @property(nonatomic, strong) UIView * floatingView;
    @property(nonatomic, strong) UIPanGestureRecognizer *panGesture;
    
    @end
    
    
    @implementation WSFloatingWndMgr
    IMPL_SINGLETON(WSFloatingWndMgr);
    
    - (CGFloat)safeAreaTop
    {
        if (@available(iOS 11.0, *)) {
            UIWindow *window = [[[UIApplication sharedApplication] delegate] window];
            UIEdgeInsets safeArea = window.safeAreaInsets;
            return safeArea.top;
        }
        return 0;
    }
    
    - (CGFloat)safeAreaBottom
    {
        if (@available(iOS 11.0, *)) {
            UIWindow *window = [[[UIApplication sharedApplication] delegate] window];
            UIEdgeInsets safeArea = window.safeAreaInsets;
            return safeArea.bottom;
        }
        return 0;
    }
    
    -(BOOL) showFloatingWnsWithView:(UIView *) floatingView
    {
        return [self showFloatingWnsWithView:floatingView frame:floatingView.frame];
    }
    
    -(void) removeFloatingView
    {
        if (self.floatingView != nil) {
            [self.floatingView removeFromSuperview];
            [self.floatingView removeGestureRecognizer:self.panGesture];
            self.panGesture = nil;
            self.floatingView = nil;
        }
    }
    
    -(BOOL) showFloatingWnsWithView:(UIView *) floatingView frame:(CGRect) frame
    {
        [self removeFloatingView];
        if (CGRectEqualToRect(frame, CGRectZero)) {
            frame = floatingView.frame;
        }
        
        UIWindow *window = [UIApplication sharedApplication].delegate.window;
        [window addSubview:floatingView];
        
        UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(onPan:)];
        [floatingView addGestureRecognizer:pan];
        self.floatingView = floatingView;
        self.panGesture = pan;
        return YES;
    }
    
    - (void)onPan:(UIPanGestureRecognizer *)panGesture
    {
        UIWindow *mainWindow = [UIApplication sharedApplication].delegate.window;
        CGPoint point = [panGesture locationInView:mainWindow];
        UIView * floatingView = panGesture.view;
        
        if (panGesture.state == UIGestureRecognizerStateEnded || panGesture.state == UIGestureRecognizerStateCancelled) {
            CGRect currentFrame = floatingView.frame;
            CGRect targetFrame = currentFrame;
            CGRect availableDragArea = UIEdgeInsetsInsetRect(mainWindow.frame, UIEdgeInsetsMake([self safeAreaTop], WSSafeContentPadding, [self safeAreaBottom], WSSafeContentPadding));
            
            if (CGRectGetMinY(currentFrame) < CGRectGetMinY(availableDragArea)) {
                targetFrame.origin.y = CGRectGetMinY(availableDragArea);
            } else if (CGRectGetMaxY(currentFrame) > CGRectGetMaxY(availableDragArea)) {
                targetFrame.origin.y = CGRectGetMaxY(availableDragArea) - CGRectGetHeight(currentFrame);
            }
            
            if (CGRectGetMidX(currentFrame) < CGRectGetMidX(availableDragArea)) {
                targetFrame.origin.x = CGRectGetMinX(availableDragArea);
            } else {
                targetFrame.origin.x = CGRectGetMaxX(availableDragArea) - CGRectGetWidth(currentFrame);
            }
            
            [UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
                floatingView.frame = targetFrame;
            } completion:^(BOOL finished){
                
            }];
            return;
        }
        floatingView.center = point;
    }
    
    @end
    

    相关文章

      网友评论

          本文标题:创建顶层显示可移动悬浮窗

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