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

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

作者: 蓝天白云_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