Files
keyboard/Pods/LSTPopView/LSTPopView/Classes/Code/LSTPopView.m

1776 lines
65 KiB
Mathematica
Raw Normal View History

2025-11-06 13:18:27 +08:00
//
// LSTPopView.m
// LoSenTrad
//
// Created by LoSenTrad on 2020/2/22.
//
#import "LSTPopView.h"
#import <objc/runtime.h>
#import "LSTTimer.h"
static NSString *const LSTPopViewLogTitle = @"LSTPopView日志 ---> :";
static LSTPopViewLogStyle _logStyle;
@interface LSTPopViewManager : NSObject
/** */
LSTPopViewManager *LSTPopViewM(void);
@end
@interface LSTPopViewManager ()
/** popView */
@property (nonatomic,strong) NSMutableArray *popViewMarr;
/** popview */
@property (nonatomic,strong) NSPointerArray *showList;
/** popView */
@property (nonatomic,strong) NSHashTable <LSTPopView *> *removeList;
/** View */
@property (nonatomic,strong) UILabel *infoView;
@end
@implementation LSTPopViewManager
static LSTPopViewManager *_instance;
LSTPopViewManager *LSTPopViewM() {
return [LSTPopViewManager sharedInstance];
}
+ (instancetype)sharedInstance {
if (!_instance) {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [[self alloc] init];
});
}
return _instance;
}
+ (id)allocWithZone:(struct _NSZone *)zone {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [super allocWithZone:zone];
});
return _instance;
}
+ (NSArray *)getAllPopView {
return LSTPopViewM().popViewMarr;
}
/** popView */
+ (NSArray *)getAllPopViewForParentView:(UIView *)parentView {
NSMutableArray *mArr = LSTPopViewM().popViewMarr;
NSMutableArray *resMarr = [NSMutableArray array];
for (id obj in mArr) {
LSTPopView *popView = (LSTPopView *)obj;
if ([popView.parentView isEqual:parentView]) {
[resMarr addObject:obj];
}
}
return [NSArray arrayWithArray:resMarr];
}
/** popView */
+ (NSArray *)getAllPopViewForPopView:(LSTPopView *)popView {
NSArray *mArr = [self getAllPopViewForParentView:popView.parentView];
NSMutableArray *resMarr = [NSMutableArray array];
for (id obj in mArr) {
LSTPopView *tPopView = (LSTPopView *)obj;
if (popView.groupId == nil && tPopView.groupId == nil) {
[resMarr addObject:obj];
continue;
}
if ([tPopView.groupId isEqual:popView.groupId]) {
[resMarr addObject:obj];
continue;
}
}
return [NSArray arrayWithArray:resMarr];
}
/** popView */
+ (LSTPopView *)getPopViewForKey:(NSString *)key {
if (key.length<=0) { return nil; }
NSMutableArray *mArr = LSTPopViewM().popViewMarr;
for (id obj in mArr) {
LSTPopView *popView = (LSTPopView *)obj;
if ([popView.identifier isEqualToString:key]) {
return popView;
}
}
return nil;
}
+ (void)savePopView:(LSTPopView *)popView {
[LSTPopViewM().popViewMarr addObject:popView];
//
[self sortingArr];
if (_logStyle & LSTPopViewLogStyleWindow) {
[self setInfoData];
}
if (_logStyle & LSTPopViewLogStyleConsole) {
[self setConsoleLog];
}
}
/** popView */
+ (void)removePopView:(LSTPopView *)popView {
if (!popView) { return; }
NSArray *arr = LSTPopViewM().popViewMarr;
for (id obj in arr) {
LSTPopView *tPopView = (LSTPopView *)obj;
if ([tPopView isEqual:popView]) {
// [LSTPopViewM().popViewMarr removeObject:obj];
[tPopView dismissWithStyle:LSTDismissStyleNO];
break;
}
}
if (_logStyle & LSTPopViewLogStyleWindow) {
[self setInfoData];
}
if (_logStyle & LSTPopViewLogStyleConsole) {
[self setConsoleLog];
}
}
/** popView */
+ (void)removePopViewForKey:(NSString *)key {
if (key.length<=0) { return; }
NSArray *arr = LSTPopViewM().popViewMarr;
for (id obj in arr) {
LSTPopView *tPopView = (LSTPopView *)obj;
if ([tPopView.identifier isEqualToString:key]) {
// [LSTPopViewM().popViewMarr removeObject:obj];
[tPopView dismissWithStyle:LSTDismissStyleNO];
break;
}
}
if (_logStyle & LSTPopViewLogStyleWindow) {
[self setInfoData];
}
if (_logStyle & LSTPopViewLogStyleConsole) {
[self setConsoleLog];
}
}
/** popView */
+ (void)removeAllPopView {
NSMutableArray *arr = LSTPopViewM().popViewMarr;
if (arr.count<=0) { return; }
NSArray *popViewMarr = [NSArray arrayWithArray:LSTPopViewM().popViewMarr];
[popViewMarr enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
LSTPopView *tPopView = (LSTPopView *)obj;
[tPopView dismissWithStyle:LSTDismissStyleNO];
}];
if (_logStyle & LSTPopViewLogStyleWindow) {
[self setInfoData];
}
if (_logStyle & LSTPopViewLogStyleConsole) {
[self setConsoleLog];
}
}
+ (void)removeLastPopView {
NSPointerArray *showList = LSTPopViewM().showList;
for (NSInteger i = showList.count - 1; i >= 0; i --) {
LSTPopView *popView = [showList pointerAtIndex:i];
if (popView) {
[self removePopView:popView];
[showList addPointer:NULL];
[showList compact];
break;
}
}
}
#pragma mark - ***** Other *****
+ (void)setInfoData {
LSTPopViewM().infoView.text = [NSString stringWithFormat:@"S:%zd R:%zd",LSTPopViewM().popViewMarr.count,LSTPopViewM().removeList.allObjects.count];
}
+ (void)setConsoleLog {
LSTPVLog(@"%@ S:%zd个 R:%zd个",LSTPopViewLogTitle,LSTPopViewM().popViewMarr.count,LSTPopViewM().removeList.allObjects.count);
}
//
+ (void)sortingArr {
NSMutableArray *arr = LSTPopViewM().popViewMarr;
for (int i = 0; i < arr.count; i++) {
for (int j = i+1; j < arr.count; j++) {
LSTPopView *iPopView = (LSTPopView *)arr[i];
LSTPopView *jPopView = (LSTPopView *)arr[j];
if (iPopView.priority > jPopView.priority) {
[arr exchangeObjectAtIndex:i withObjectAtIndex:j];
}
}
}
}
/** popView */
+ (void)transferredToRemoveQueueWithPopView:(LSTPopView *)popView {
NSArray *popViewMarr = LSTPopViewM().popViewMarr;
[popViewMarr enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
LSTPopView *tPopView = (LSTPopView *)obj;
if ([popView isEqual:tPopView]) {
[LSTPopViewM().removeList addObject:obj];
[LSTPopViewM().popViewMarr removeObject:obj];
}
}];
}
+ (void)destroyInRemoveQueue:(LSTPopView *)popView {
if (LSTPopViewM().removeList.allObjects.count <= 0) {
[self transferredToRemoveQueueWithPopView:popView];
}
if (_logStyle&LSTPopViewLogStyleWindow) {
[self setInfoData];
}
if (_logStyle&LSTPopViewLogStyleConsole) {
[self setConsoleLog];
}
}
#pragma mark - ***** *****
- (UILabel *)infoView {
if(_infoView) return _infoView;
_infoView = [[UILabel alloc] init];
_infoView.backgroundColor = UIColor.orangeColor;
_infoView.textAlignment = NSTextAlignmentCenter;
_infoView.font = [UIFont systemFontOfSize:11];
_infoView.frame = CGRectMake(pv_ScreenWidth()-70, pv_IsIphoneX_ALL()? 40:20, 60, 10);
_infoView.layer.cornerRadius = 1;
_infoView.layer.masksToBounds = YES;
UIView *superView = [UIApplication sharedApplication].keyWindow;
[superView addSubview:_infoView];
return _infoView;
}
- (NSMutableArray *)popViewMarr {
if(_popViewMarr) return _popViewMarr;
_popViewMarr = [NSMutableArray array];
return _popViewMarr;
}
- (NSHashTable<LSTPopView *> *)removeList {
if (_removeList) return _removeList;
_removeList = [NSHashTable hashTableWithOptions:NSPointerFunctionsWeakMemory];
return _removeList;
}
- (NSPointerArray *)showList {
if (_showList) return _showList;
_showList = [NSPointerArray pointerArrayWithOptions:(NSPointerFunctionsWeakMemory)];
return _showList;
}
@end
static const NSTimeInterval LSTPopViewDefaultDuration = -1.0f;
//
#define LST_DEGREES_TO_RADIANS(angle) ((angle) / 180.0 * M_PI)
@interface LSTPopViewBgView : UIView
/** NO */
@property (nonatomic, assign) BOOL isHideBg;
@end
@implementation LSTPopViewBgView
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{
UIView *hitView = [super hitTest:point withEvent:event];
if(hitView == self && self.isHideBg){
return nil;
}
return hitView;
}
@end
@interface LSTPopView () <UIGestureRecognizerDelegate>
/** app UIWindow view */
@property (nonatomic, weak) UIView *container;
/** */
@property (nonatomic, strong) LSTPopViewBgView *backgroundView;
/** */
@property (nonatomic,strong) UIView *customView;
/** */
@property (nonatomic, assign) CGFloat avoidKeyboardOffset;
/** */
@property (nonatomic, strong) NSHashTable <id<LSTPopViewProtocol>> *delegates;
/** */
@property (nonatomic, strong) UITapGestureRecognizer *tapGesture;
/** View */
@property (nonatomic, strong) UIPanGestureRecognizer *panGesture;
//tableView
@property (nonatomic, assign) BOOL isDragScrollView;
/** popViewUIScrollView, UITableView, UICollectionView */
@property (nonatomic, weak) UIScrollView *scrollerView;
/** viewFrame */
@property (nonatomic, assign) CGRect originFrame;
/** dragDismissStyle */
@property (nonatomic, assign) BOOL isDragDismissStyle;
/** */
@property (nonatomic,assign,readonly) BOOL isShowKeyboard;
/** */
@property (nonatomic, assign) CGFloat keyboardY;
@end
@implementation LSTPopView
#pragma mark - ***** *****
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
[self initSubViews];
}
return self;
}
- (void)initSubViews {
//
_isClickBgDismiss = NO;
_isObserverScreenRotation = YES;
_bgAlpha = 0.25;
_popStyle = LSTPopStyleFade;
_dismissStyle = LSTDismissStyleFade;
_popDuration = LSTPopViewDefaultDuration;
_dismissDuration = LSTPopViewDefaultDuration;
_hemStyle = LSTHemStyleCenter;
_adjustX = 0;
_adjustY = 0;
_isClickFeedback = NO;
_isAvoidKeyboard = YES;
_avoidKeyboardSpace = 10;
_bgColor = [UIColor blackColor];
_identifier = @"";
_isShowKeyboard = NO;
_showTime = 0.0;
_priority = 0;
_isHideBg = NO;
_isShowKeyboard = NO;
_isImpactFeedback = NO;
_rectCorners = UIRectCornerAllCorners;
_isSingle = NO;
//
_dragStyle = LSTDragStyleNO;
_dragDismissStyle = LSTDismissStyleNO;
_dragDistance = 0.0f;
_dragReboundTime = 0.25;
_dragDismissDuration = LSTPopViewDefaultDuration;
_swipeVelocity = 1000.0f;
_isDragDismissStyle = NO;
}
+ (nullable instancetype)initWithCustomView:(UIView *_Nonnull)customView {
return [self initWithCustomView:customView popStyle:LSTPopStyleNO dismissStyle:LSTDismissStyleNO];
}
+ (nullable instancetype)initWithCustomView:(UIView *_Nonnull)customView
popStyle:(LSTPopStyle)popStyle
dismissStyle:(LSTDismissStyle)dismissStyle {
return [self initWithCustomView:customView
parentView:nil
popStyle:popStyle
dismissStyle:dismissStyle];
}
+ (nullable instancetype)initWithCustomView:(UIView *_Nonnull)customView
parentView:(UIView *)parentView
popStyle:(LSTPopStyle)popStyle
dismissStyle:(LSTDismissStyle)dismissStyle {
// (check customView is exist)
if (!customView) { return nil; }
if (![parentView isKindOfClass:[UIView class]] && parentView != nil) {
LSTPVLog(@"parentView is error !!!");
return nil;
}
CGRect popViewFrame = CGRectZero;
if (parentView) {
popViewFrame = parentView.bounds;
} else {
popViewFrame = CGRectMake(0, 0, pv_ScreenWidth(), pv_ScreenHeight());
}
LSTPopView *popView = [[LSTPopView alloc] initWithFrame:popViewFrame];
popView.backgroundColor = [UIColor clearColor];
popView.container = parentView? parentView : [UIApplication sharedApplication].keyWindow;
popView.customView = customView;
popView.backgroundView = [[LSTPopViewBgView alloc] initWithFrame:popView.bounds];
popView.backgroundView.backgroundColor = [UIColor clearColor];
popView.popStyle = popStyle;
popView.dismissStyle = dismissStyle;
[popView addSubview:popView.backgroundView];
[popView.backgroundView addSubview:customView];
//
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:popView action:@selector(popViewBgViewTap:)];
tap.delegate = popView;
popView.tapGesture = tap;
[popView.backgroundView addGestureRecognizer:tap];
//
popView.panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:popView action:@selector(pan:)];
popView.panGesture.delegate = popView;
[popView.customView addGestureRecognizer:popView.panGesture];
// [popView.backgroundView addTarget:popView action:@selector(popViewBgViewTap:) forControlEvents:UIControlEventTouchUpInside];;
// UILongPressGestureRecognizer *customViewLP = [[UILongPressGestureRecognizer alloc] initWithTarget:popView action:@selector(bgLongPressEvent:)];
// [popView.backgroundView addGestureRecognizer:customViewLP];
// UITapGestureRecognizer *customViewTap = [[UITapGestureRecognizer alloc] initWithTarget:popView action:@selector(customViewClickEvent:)];
// [popView.customView addGestureRecognizer:customViewTap];
//
[[NSNotificationCenter defaultCenter] addObserver:popView
selector:@selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
//
[[NSNotificationCenter defaultCenter] addObserver:popView
selector:@selector(keyboardDidShow:)
name:UIKeyboardDidShowNotification
object:nil];
//frame
[[NSNotificationCenter defaultCenter] addObserver:popView
selector:@selector(keyboardWillChangeFrame:)
name:UIKeyboardWillChangeFrameNotification
object:nil];
//frame
[[NSNotificationCenter defaultCenter] addObserver:popView
selector:@selector(keyboardDidChangeFrame:)
name:UIKeyboardDidChangeFrameNotification
object:nil];
//
[[NSNotificationCenter defaultCenter] addObserver:popView
selector:@selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification
object:nil];
//
[[NSNotificationCenter defaultCenter] addObserver:popView
selector:@selector(keyboardDidHide:)
name:UIKeyboardDidHideNotification
object:nil];
//
[[NSNotificationCenter defaultCenter] addObserver:popView
selector:@selector(statusBarOrientationChange:)
name:UIApplicationDidChangeStatusBarOrientationNotification
object:nil];
//customView frame
[popView.customView addObserver:popView
forKeyPath:@"frame"
options:NSKeyValueObservingOptionOld
context:NULL];
return popView;
}
- (void)dealloc {
[self.customView removeObserver:self forKeyPath:@"frame"];
[[NSNotificationCenter defaultCenter] removeObserver:self];
//
[LSTPopViewManager destroyInRemoveQueue:self];
[self lst_PopViewDidDismissForPopView:self];
self.popViewDidDismissBlock? self.popViewDidDismissBlock():nil;
}
- (void)removeFromSuperview {
[super removeFromSuperview];
[LSTPopViewManager transferredToRemoveQueueWithPopView:self];
}
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
UIView *hitView = [super hitTest:point withEvent:event];
if (hitView != self.customView) {
if(hitView == self && self.isHideBg){ return nil; }
}
return hitView;
}
#pragma mark - ***** *****
- (void)lst_PopViewBgClickForPopView:(LSTPopView *)popView {
for (id<LSTPopViewProtocol> delegate in _delegates.copy) {
if ([delegate respondsToSelector:_cmd]) {
[delegate lst_PopViewBgClickForPopView:popView];
}
}
}
- (void)lst_PopViewBgLongPressForPopView:(LSTPopView *)popView {
for (id<LSTPopViewProtocol> delegate in _delegates.copy) {
if ([delegate respondsToSelector:_cmd]) {
[delegate lst_PopViewBgLongPressForPopView:popView];
}
}
}
- (void)lst_PopViewWillPopForPopView:(LSTPopView *)popView {
for (id<LSTPopViewProtocol> delegate in _delegates.copy) {
if ([delegate respondsToSelector:_cmd]) {
[delegate lst_PopViewWillPopForPopView:popView];
}
}
}
- (void)lst_PopViewDidPopForPopView:(LSTPopView *)popView {
for (id<LSTPopViewProtocol> delegate in _delegates.copy) {
if ([delegate respondsToSelector:_cmd]) {
[delegate lst_PopViewDidPopForPopView:popView];
}
}
}
- (void)lst_PopViewCountDownForPopView:(LSTPopView *)popView forCountDown:(NSTimeInterval)timeInterval {
for (id<LSTPopViewProtocol> delegate in _delegates.copy) {
if ([delegate respondsToSelector:_cmd]) {
[delegate lst_PopViewCountDownForPopView:popView forCountDown:timeInterval];
}
}
}
- (void)lst_PopViewCountDownFinishForPopView:(LSTPopView *)popView {
for (id<LSTPopViewProtocol> delegate in _delegates.copy) {
if ([delegate respondsToSelector:_cmd]) {
[delegate lst_PopViewCountDownFinishForPopView:popView];
}
}
}
- (void)lst_PopViewWillDismissForPopView:(LSTPopView *)popView {
for (id<LSTPopViewProtocol> delegate in _delegates.copy) {
if ([delegate respondsToSelector:_cmd]) {
[delegate lst_PopViewWillDismissForPopView:popView];
}
}
}
- (void)lst_PopViewDidDismissForPopView:(LSTPopView *)popView {
for (id<LSTPopViewProtocol> delegate in _delegates.copy) {
if ([delegate respondsToSelector:_cmd]) {
[delegate lst_PopViewDidDismissForPopView:popView];
}
}
}
#pragma mark - ***** *****
- (void)setCustomViewFrameWithHeight:(CGFloat)height {
CGFloat changeY = 0;
switch (self.hemStyle) {
case LSTHemStyleTop ://
{
self.customView.pv_X = _backgroundView.pv_CenterX - _customView.pv_Size.width*0.5 + _adjustX;
self.customView.pv_Y = _adjustY;
changeY = _adjustY;
}
break;
case LSTHemStyleLeft ://
{
self.customView.pv_X = _adjustX;
self.customView.pv_Y = _backgroundView.pv_CenterY - _customView.pv_Size.height*0.5 + _adjustY;
changeY = height*0.5;
}
break;
case LSTHemStyleBottom ://
{
self.customView.pv_X = _backgroundView.pv_CenterX - _customView.pv_Size.width*0.5 + _adjustX;
[self.customView layoutIfNeeded];
self.customView.pv_Y = _backgroundView.pv_Height - _customView.pv_Height + _adjustY;
changeY = height;
}
break;
case LSTHemStyleRight ://
{
self.customView.pv_X = _backgroundView.pv_Width - _customView.pv_Width + _adjustX;
self.customView.pv_Y = _backgroundView.pv_CenterY - _customView.pv_Size.height*0.5 + _adjustY;
changeY = height*0.5;
}
break;
case LSTHemStyleTopLeft :///
{
self.customView.pv_X = _adjustX;
self.customView.pv_Y = _adjustY;
changeY = _adjustY;
}
break;
case LSTHemStyleBottomLeft ://
{
self.customView.pv_X = _adjustX;
[self.customView layoutIfNeeded];
self.customView.pv_Y = _backgroundView.pv_Height - _customView.pv_Height + _adjustY;
changeY = height;
}
break;
case LSTHemStyleBottomRight ://
{
self.customView.pv_X = _backgroundView.pv_Width - _customView.pv_Width + _adjustX;
[self.customView layoutIfNeeded];
self.customView.pv_Y = _backgroundView.pv_Height - _customView.pv_Height + _adjustY;
changeY = height;
}
break;
case LSTHemStyleTopRight ://
{
self.customView.pv_X = _backgroundView.pv_Width - _customView.pv_Width + _adjustX;
self.customView.pv_Y = _adjustY;
changeY = _adjustY;
}
break;
default://
{
self.customView.pv_X = _backgroundView.pv_CenterX - _customView.pv_Size.width*0.5 + _adjustX;
self.customView.pv_Y = _backgroundView.pv_CenterY - _customView.pv_Size.height*0.5 + _adjustY;
changeY = height*0.5;
}
break;
}
CGFloat originBottom = _originFrame.origin.y + _originFrame.size.height + _avoidKeyboardSpace;
if (_isShowKeyboard && (originBottom > _keyboardY)) {//
CGFloat Y = _keyboardY - _customView.pv_Height - _avoidKeyboardSpace;
_customView.pv_Y = Y;
CGRect newFrame = _originFrame;
newFrame.origin.y = newFrame.origin.y - changeY;
newFrame.size = CGSizeMake(_originFrame.size.width, _customView.pv_Height);
self.originFrame = newFrame;
}else {//
self.originFrame = _customView.frame;
}
[self setCustomViewCorners];
}
- (void)setCustomViewCorners {
BOOL isSetCorner = NO;
if (self.rectCorners & UIRectCornerTopLeft) {
isSetCorner = YES;
}
if (self.rectCorners & UIRectCornerTopRight) {
isSetCorner = YES;
}
if (self.rectCorners & UIRectCornerBottomLeft) {
isSetCorner = YES;
}
if (self.rectCorners & UIRectCornerBottomRight) {
isSetCorner = YES;
}
if (self.rectCorners & UIRectCornerAllCorners) {
isSetCorner = YES;
}
if (isSetCorner && self.cornerRadius>0) {
UIBezierPath * path = [UIBezierPath bezierPathWithRoundedRect:self.customView.bounds byRoundingCorners:self.rectCorners cornerRadii:CGSizeMake(self.cornerRadius, self.cornerRadius)];
CAShapeLayer * layer = [[CAShapeLayer alloc]init];
layer.frame = self.customView.bounds;
layer.path = path.CGPath;
self.customView.layer.mask = layer;
}
}
#pragma mark - ***** setter / *****
- (void)setPopDuration:(NSTimeInterval)popDuration {
if (popDuration <= 0.0) { return; }
_popDuration = popDuration;
}
- (void)setDismissDuration:(NSTimeInterval)dismissDuration {
if (dismissDuration <= 0.0) { return; }
_dismissDuration = dismissDuration;
}
- (void)setDragDismissDuration:(NSTimeInterval)dragDismissDuration {
if (dragDismissDuration <= 0.0) { return; }
_dragDismissDuration = dragDismissDuration;
}
- (void)setHemStyle:(LSTHemStyle)hemStyle {
_hemStyle = hemStyle;
}
- (void)setAdjustX:(CGFloat)adjustX {
_adjustX = adjustX;
// self.customView.x = _customView.x + adjustX;
// self.originFrame = _customView.frame;
[self setCustomViewFrameWithHeight:0];
}
- (void)setAdjustY:(CGFloat)adjustY {
_adjustY = adjustY;
// self.customView.y = _customView.y + adjustY;
// self.originFrame = _customView.frame;
[self setCustomViewFrameWithHeight:0];
}
- (void)setIsObserverScreenRotation:(BOOL)isObserverScreenRotation {
_isObserverScreenRotation = isObserverScreenRotation;
}
- (void)setBgAlpha:(CGFloat)bgAlpha {
_bgAlpha = (bgAlpha <= 0.0f) ? 0.0f : ((bgAlpha > 1.0) ? 1.0 : bgAlpha);
}
- (void)setIsClickFeedback:(BOOL)isClickFeedback {
_isClickFeedback = isClickFeedback;
}
- (void)setIsHideBg:(BOOL)isHideBg {
_isHideBg = isHideBg;
self.backgroundView.isHideBg = isHideBg;
self.backgroundView.backgroundColor = [self getNewColorWith:self.bgColor alpha:0.0];
}
- (void)setShowTime:(NSTimeInterval)showTime {
_showTime = showTime;
}
- (void)setDelegate:(id<LSTPopViewProtocol>)delegate {
if ([self.delegates containsObject:delegate]) return;
[self.delegates addObject:delegate];
}
- (void)setDragDismissStyle:(LSTDismissStyle)dragDismissStyle {
_dragDismissStyle = dragDismissStyle;
self.isDragDismissStyle = YES;
}
#pragma mark - ***** pop *****
- (void)pop {
[self popWithStyle:self.popStyle duration:self.popDuration];
}
- (void)popWithStyle:(LSTPopStyle)popStyle {
[self popWithStyle:popStyle duration:self.popDuration];
}
- (void)popWithDuration:(NSTimeInterval)duration {
[self popWithStyle:self.popStyle duration:duration];
}
- (void)popWithStyle:(LSTPopStyle)popStyle duration:(NSTimeInterval)duration {
[self popWithPopStyle:popStyle duration:duration isOutStack:NO];
}
- (void)popWithPopStyle:(LSTPopStyle)popStyle duration:(NSTimeInterval)duration isOutStack:(BOOL)isOutStack {
NSTimeInterval resDuration = [self getPopDuration:duration];
[self setCustomViewFrameWithHeight:0];
self.originFrame = self.customView.frame;
BOOL startTimer = NO;
if (self.isSingle) {//
NSArray *popViewArr = [LSTPopViewManager getAllPopViewForPopView:self];
for (id obj in popViewArr) {//popViewa
LSTPopView *lastPopView = (LSTPopView *)obj;
[lastPopView dismissWithDismissStyle:LSTDismissStyleNO duration:0.2 isRemove:YES];
}
startTimer = YES;
}else {//
if (!isOutStack) {//popView
NSArray *popViewArr = [LSTPopViewManager getAllPopViewForPopView:self];
if (popViewArr.count >= 1) {
id obj = popViewArr[popViewArr.count - 1];
LSTPopView *lastPopView = (LSTPopView *)obj;
if (self.isStack) {//
startTimer = YES;
}else {
if (self.priority >= lastPopView.priority) {//
if (lastPopView.isShowKeyboard) {
[lastPopView endEditing:YES];
}
[lastPopView dismissWithDismissStyle:LSTDismissStyleFade duration:0.2 isRemove:NO];
startTimer = YES;
} else {//
if (!self.parentView) {
self.container = [UIApplication sharedApplication].keyWindow;
}
[LSTPopViewManager savePopView:self];
return;
}
}
} else {
startTimer = YES;
}
}
}
// if (!isOutStack){
// [self.parentView addSubview:self];
// }
if (!self.superview) {
[self.container addSubview:self];
[LSTPopViewM().showList addPointer:(__bridge void * _Nullable)self];
}
if (!isOutStack){
[self lst_PopViewWillPopForPopView:self];
self.popViewWillPopBlock? self.popViewWillPopBlock():nil;
}
//
[self popAnimationWithPopStyle:popStyle duration:resDuration];
//
[self beginImpactFeedback];
LSTPopViewWK(self);;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(resDuration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
if (!isOutStack){
[self lst_PopViewDidPopForPopView:self];
wk_self.popViewDidPopBlock? wk_self.popViewDidPopBlock():nil;
}
if (startTimer){ [self startTimer]; }
});
//popView
if (!isOutStack) { [LSTPopViewManager savePopView:self]; }
}
- (void)popAnimationWithPopStyle:(LSTPopStyle)popStyle duration:(NSTimeInterval)duration {
LSTPopViewWK(self);
if (popStyle == LSTPopStyleFade) {//
self.backgroundView.backgroundColor = [self getNewColorWith:self.bgColor alpha:0.0];
self.customView.alpha = 0.0f;
[UIView animateWithDuration:0.2 animations:^{
self.backgroundView.backgroundColor =[self getNewColorWith:self.bgColor alpha:self.bgAlpha];
self.customView.alpha = 1.0f;
}];
} else if (popStyle == LSTPopStyleNO){//
self.backgroundView.backgroundColor = [self getNewColorWith:self.bgColor alpha:0.0];
[UIView animateWithDuration:0.1 animations:^{
self.backgroundView.backgroundColor =[self getNewColorWith:self.bgColor alpha:self.bgAlpha];
}];
self.customView.alpha = 1.0f;
} else {//
self.backgroundView.backgroundColor = [self getNewColorWith:self.bgColor alpha:0.0];
[UIView animateWithDuration:duration animations:^{
wk_self.backgroundView.backgroundColor = [self getNewColorWith:self.bgColor alpha:self.bgAlpha];
}];
//view
[self hanlePopAnimationWithDuration:duration popStyle:popStyle];
}
}
- (void)hanlePopAnimationWithDuration:(NSTimeInterval)duration
popStyle:(LSTPopStyle)popStyle {
self.alpha = 0;
[UIView animateWithDuration:duration*0.2 animations:^{
self.alpha = 1;
}];
LSTPopViewWK(self);
switch (popStyle) {
case LSTPopStyleScale:// <
{
[self animationWithLayer:_customView.layer duration:((0.3*duration)/0.7) values:@[@0.0, @1.2, @1.0]]; // (the other animation values) @[@0.0, @1.2, @0.9, @1.0]
}
break;
case LSTPopStyleSmoothFromTop:
case LSTPopStyleSmoothFromBottom:
case LSTPopStyleSmoothFromLeft:
case LSTPopStyleSmoothFromRight:
case LSTPopStyleSpringFromTop:
case LSTPopStyleSpringFromLeft:
case LSTPopStyleSpringFromBottom:
case LSTPopStyleSpringFromRight:
{
CGPoint startPosition = self.customView.layer.position;
if (popStyle == LSTPopStyleSmoothFromTop || popStyle == LSTPopStyleSpringFromTop) {
self.customView.layer.position = CGPointMake(startPosition.x, -_customView.pv_Height*0.5);
} else if (popStyle == LSTPopStyleSmoothFromLeft || popStyle == LSTPopStyleSpringFromLeft) {
self.customView.layer.position = CGPointMake(-_customView.pv_Width*0.5, startPosition.y);
} else if (popStyle == LSTPopStyleSmoothFromBottom || popStyle == LSTPopStyleSpringFromBottom) {
self.customView.layer.position = CGPointMake(startPosition.x, CGRectGetMaxY(self.frame) + _customView.pv_Height*0.5);
} else {
self.customView.layer.position = CGPointMake(CGRectGetMaxX(self.frame) + _customView.pv_Width*0.5 , startPosition.y);
}
CGFloat damping = 1.0;
if (popStyle == LSTPopStyleSpringFromTop||
popStyle == LSTPopStyleSpringFromLeft||
popStyle == LSTPopStyleSpringFromBottom||
popStyle == LSTPopStyleSpringFromRight) {
damping = 0.65;
}
[UIView animateWithDuration:duration
delay:0
usingSpringWithDamping:damping
initialSpringVelocity:1.0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
wk_self.customView.layer.position = startPosition;
} completion:nil];
}
break;
case LSTPopStyleCardDropFromLeft:
case LSTPopStyleCardDropFromRight:
{
CGPoint startPosition = self.customView.layer.position;
if (popStyle == LSTPopStyleCardDropFromLeft) {
self.customView.layer.position = CGPointMake(startPosition.x * 1.0, -_customView.pv_Height*0.5);
self.customView.transform = CGAffineTransformMakeRotation(LST_DEGREES_TO_RADIANS(15.0));
} else {
self.customView.layer.position = CGPointMake(startPosition.x * 1.0, -_customView.pv_Height*0.5);
self.customView.transform = CGAffineTransformMakeRotation(LST_DEGREES_TO_RADIANS(-15.0));
}
[UIView animateWithDuration:duration delay:0 usingSpringWithDamping:0.75 initialSpringVelocity:1.0 options:UIViewAnimationOptionCurveEaseIn animations:^{
wk_self.customView.layer.position = startPosition;
} completion:nil];
[UIView animateWithDuration:duration*0.6 animations:^{
wk_self.customView.layer.transform = CATransform3DMakeRotation(LST_DEGREES_TO_RADIANS((popStyle == LSTPopStyleCardDropFromRight) ? 5.5 : -5.5), 0, 0, 0);
} completion:^(BOOL finished) {
[UIView animateWithDuration:duration*0.2 animations:^{
wk_self.customView.transform = CGAffineTransformMakeRotation(LST_DEGREES_TO_RADIANS((popStyle == LSTPopStyleCardDropFromRight) ? -1.0 : 1.0));
} completion:^(BOOL finished) {
[UIView animateWithDuration:duration*0.2 animations:^{
wk_self.customView.transform = CGAffineTransformMakeRotation(0.0);
} completion:nil];
}];
}];
}
break;
default:
break;
}
}
#pragma mark - ***** dismiss *****
- (void)dismiss {
[self dismissWithStyle:self.dismissStyle duration:self.dismissDuration];
}
- (void)dismissWithStyle:(LSTDismissStyle)dismissStyle {
[self dismissWithStyle:dismissStyle duration:self.dismissDuration];
}
- (void)dismissWithDuration:(NSTimeInterval)duration {
[self dismissWithStyle:self.dismissStyle duration:duration];
}
- (void)dismissWithStyle:(LSTDismissStyle)dismissStyle duration:(NSTimeInterval)duration {
[self dismissWithDismissStyle:dismissStyle duration:duration isRemove:YES];
}
- (void)dismissWithDismissStyle:(LSTDismissStyle)dismissStyle
duration:(NSTimeInterval)duration
isRemove:(BOOL)isRemove {
NSTimeInterval resDuration = [self getDismissDuration:duration];
if (isRemove) {
//popView 线
[LSTPopViewManager transferredToRemoveQueueWithPopView:self];
}
[self lst_PopViewWillDismissForPopView:self];
self.popViewWillDismissBlock? self.popViewWillDismissBlock():nil;
LSTPopViewWK(self)
[self dismissAnimationWithDismissStyle:dismissStyle duration:resDuration];
if (!self.isSingle && (isRemove && [LSTPopViewManager getAllPopViewForPopView:self].count >= 1)){//
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(resDuration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//popView
if (!self.isStack && [LSTPopViewManager getAllPopViewForPopView:self].count >= 1) {
NSArray *popViewArr = [LSTPopViewManager getAllPopViewForPopView:self];
id obj = popViewArr[popViewArr.count-1];
LSTPopView *tPopView = (LSTPopView *)obj;
if (!tPopView.superview) {
[tPopView.container addSubview:tPopView];
[LSTPopViewM().showList addPointer:(__bridge void * _Nullable)tPopView];
}
[tPopView popWithPopStyle:LSTPopStyleFade duration:0.25 isOutStack:YES];
}
});
}
if (isRemove) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(resDuration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[wk_self removeFromSuperview];
});
}
}
- (void)dismissAnimationWithDismissStyle:(LSTDismissStyle)dismissStyle duration:(NSTimeInterval)duration {
LSTPopViewWK(self);
if (dismissStyle == LSTPopStyleFade) {
[UIView animateWithDuration:0.2 animations:^{
wk_self.backgroundView.backgroundColor = [self getNewColorWith:self.bgColor alpha:0.0];
wk_self.customView.alpha = 0.0f;
}];
}else if (dismissStyle == LSTPopStyleNO){
wk_self.backgroundView.backgroundColor = [self getNewColorWith:self.bgColor alpha:0.0];
wk_self.customView.alpha = 0.0f;
}else {//
[UIView animateWithDuration:duration*0.8 animations:^{
wk_self.backgroundView.backgroundColor = [self getNewColorWith:self.bgColor alpha:0.0];
}];
[self hanleDismissAnimationWithDuration:duration withDismissStyle:dismissStyle];
}
}
- (void)hanleDismissAnimationWithDuration:(NSTimeInterval)duration
withDismissStyle:(LSTDismissStyle)dismissStyle {
[UIView animateWithDuration:duration*0.8 animations:^{
self.alpha = 0;
}];
LSTPopViewWK(self);;
switch (dismissStyle) {
case LSTDismissStyleScale:
{
[self animationWithLayer:self.customView.layer duration:((0.2*duration)/0.8) values:@[@1.0, @0.66, @0.33, @0.01]];
}
break;
case LSTDismissStyleSmoothToTop:
case LSTDismissStyleSmoothToBottom:
case LSTDismissStyleSmoothToLeft:
case LSTDismissStyleSmoothToRight:
{
CGPoint startPosition = self.customView.layer.position;
CGPoint endPosition = self.customView.layer.position;
if (dismissStyle == LSTDismissStyleSmoothToTop) {
endPosition = CGPointMake(startPosition.x, -(_customView.pv_Height*0.5));
} else if (dismissStyle == LSTDismissStyleSmoothToBottom) {
endPosition = CGPointMake(startPosition.x, CGRectGetMaxY(self.frame) + _customView.pv_Height*0.5);
} else if (dismissStyle == LSTDismissStyleSmoothToLeft) {
endPosition = CGPointMake(-_customView.pv_Width*0.5, startPosition.y);
} else {
endPosition = CGPointMake(CGRectGetMaxX(self.frame) + _customView.pv_Width*0.5, startPosition.y);
}
[UIView animateWithDuration:duration delay:0 usingSpringWithDamping:1.0 initialSpringVelocity:1.0 options:UIViewAnimationOptionCurveEaseOut animations:^{
wk_self.customView.layer.position = endPosition;
} completion:nil];
}
break;
case LSTDismissStyleCardDropToLeft:
case LSTDismissStyleCardDropToRight:
{
CGPoint startPosition = self.customView.layer.position;
BOOL isLandscape = UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation);
__block CGFloat rotateEndY = 0.0f;
[UIView animateWithDuration:duration delay:0 usingSpringWithDamping:0.5 initialSpringVelocity:1.0 options:UIViewAnimationOptionCurveEaseIn animations:^{
if (dismissStyle == LSTDismissStyleCardDropToLeft) {
wk_self.customView.transform = CGAffineTransformMakeRotation(M_1_PI * 0.75);
if (isLandscape) rotateEndY = fabs(wk_self.customView.frame.origin.y);
wk_self.customView.layer.position = CGPointMake(startPosition.x, CGRectGetMaxY(wk_self.frame) + startPosition.y + rotateEndY);
} else {
wk_self.customView.transform = CGAffineTransformMakeRotation(-M_1_PI * 0.75);
if (isLandscape) rotateEndY = fabs(wk_self.customView.frame.origin.y);
wk_self.customView.layer.position = CGPointMake(startPosition.x * 1.25, CGRectGetMaxY(wk_self.frame) + startPosition.y + rotateEndY);
}
} completion:nil];
}
break;
case LSTDismissStyleCardDropToTop:
{
CGPoint startPosition = self.customView.layer.position;
CGPoint endPosition = CGPointMake(startPosition.x, -startPosition.y);
[UIView animateWithDuration:duration*0.2 animations:^{
wk_self.customView.layer.position = CGPointMake(startPosition.x, startPosition.y + 50.0f);
} completion:^(BOOL finished) {
[UIView animateWithDuration:duration*0.8 animations:^{
wk_self.customView.layer.position = endPosition;
} completion:nil];
}];
}
break;
default:
break;
}
}
#pragma mark - ***** other *****
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if([keyPath isEqualToString:@"frame"]) {
CGRect newFrame = CGRectNull;
CGRect oldFrame = CGRectNull;
if([object valueForKeyPath:keyPath] != [NSNull null]) {
//frame
newFrame = [[object valueForKeyPath:keyPath] CGRectValue];
oldFrame = [[change valueForKeyPath:@"old"] CGRectValue];
if (!CGSizeEqualToSize(newFrame.size, oldFrame.size)) {
[self setCustomViewFrameWithHeight:newFrame.size.height-oldFrame.size.height];
}
}
}else {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}
//
- (void)bgLongPressEvent:(UIGestureRecognizer *)ges {
// [self.delegateMarr enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
//
// if ([obj respondsToSelector:@selector(lst_PopViewBgLongPressForPopView:)]) {
// [obj lst_PopViewBgLongPressForPopView:self];
// }
//
// }];
self.bgLongPressBlock? self.bgLongPressBlock():nil;
// switch (ges.state) {
// case UIGestureRecognizerStateBegan:
// {
// CGFloat scale = 0.95;
// [UIView animateWithDuration:0.35 animations:^{
// ges.view.transform = CGAffineTransformMakeScale(scale, scale);
// }];
// }
// break;
// case UIGestureRecognizerStateEnded:
// case UIGestureRecognizerStateCancelled:
// {
// [UIView animateWithDuration:0.35 animations:^{
// ges.view.transform = CGAffineTransformMakeScale(1.0, 1.0);
// } completion:^(BOOL finished) {
// }];
// }
// break;
//
// default:
// break;
// }
}
- (void)customViewClickEvent:(UIGestureRecognizer *)ges {
if (self.isClickFeedback) {
CGFloat scale = 0.95;
[UIView animateWithDuration:0.25 animations:^{
ges.view.transform = CGAffineTransformMakeScale(scale, scale);
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.25 animations:^{
ges.view.transform = CGAffineTransformMakeScale(1.0, 1.0);
} completion:^(BOOL finished) {
}];
}];
}
}
- (void)popViewBgViewTap:(UIButton *)tap {
// [self.delegateMarr enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
//
// if ([obj respondsToSelector:@selector(lst_PopViewBgClickForPopView:)]) {
// [obj lst_PopViewBgClickForPopView:self];
// }
//
// }];
if (self.bgClickBlock) {
if (self.isShowKeyboard) {
[self endEditing:YES];
}
self.bgClickBlock();
}
if (_isClickBgDismiss) {
[self dismiss];
}
}
- (NSTimeInterval)getPopDuration:(NSTimeInterval)currDuration {
if (_popStyle == LSTPopStyleNO) { return 0.0f; }
if (_popStyle == LSTPopStyleFade) { return 0.2f; }
if (currDuration<=0) { self.popDuration = LSTPopViewDefaultDuration; }
if (self.popDuration == LSTPopViewDefaultDuration) {
NSTimeInterval defaultDuration = 0.0f;
if (_popStyle == LSTPopStyleScale) {
defaultDuration = 0.3f;
}
if (_popStyle == LSTPopStyleSmoothFromTop ||
_popStyle == LSTPopStyleSmoothFromLeft ||
_popStyle == LSTPopStyleSmoothFromBottom ||
_popStyle == LSTPopStyleSmoothFromRight ||
_popStyle == LSTPopStyleSpringFromTop ||
_popStyle == LSTPopStyleSpringFromLeft ||
_popStyle == LSTPopStyleSpringFromBottom ||
_popStyle == LSTPopStyleSpringFromRight ||
_popStyle == LSTPopStyleCardDropFromLeft ||
_popStyle == LSTPopStyleCardDropFromRight) {
defaultDuration = 0.6f;
}
return defaultDuration;
} else {
return currDuration;
}
}
- (NSTimeInterval)getDismissDuration:(NSTimeInterval)currDuration {
if (_dismissStyle == LSTDismissStyleNO) { return 0.0f; }
if (_dismissStyle == LSTDismissStyleFade) { return 0.2f; }
if (self.dismissDuration == LSTPopViewDefaultDuration) {
NSTimeInterval defaultDuration = 0.0f;
if (_dismissStyle == LSTDismissStyleNO) {
defaultDuration = 0.0f;
}
if (_dismissStyle == LSTDismissStyleScale) {
defaultDuration = 0.3f;
}
if (_dismissStyle == LSTDismissStyleSmoothToTop ||
_dismissStyle == LSTDismissStyleSmoothToBottom ||
_dismissStyle == LSTDismissStyleSmoothToLeft ||
_dismissStyle == LSTDismissStyleSmoothToRight ||
_dismissStyle == LSTDismissStyleCardDropToLeft ||
_dismissStyle == LSTDismissStyleCardDropToRight ||
_dismissStyle == LSTDismissStyleCardDropToTop) {
defaultDuration = 0.5f;
}
return defaultDuration;
} else {
return currDuration;
}
}
- (NSTimeInterval)getDragDismissDuration {
if (self.dragDismissDuration == LSTPopViewDefaultDuration) {
return [self getDismissDuration:self.dismissDuration];
} else {
return self.dragDismissDuration;
}
}
- (void)animationWithLayer:(CALayer *)layer duration:(CGFloat)duration values:(NSArray *)values {
CAKeyframeAnimation *KFAnimation = [CAKeyframeAnimation animationWithKeyPath:@"transform"];
KFAnimation.duration = duration;
KFAnimation.removedOnCompletion = NO;
KFAnimation.fillMode = kCAFillModeForwards;
// KFAnimation.delegate = self;// popView
NSMutableArray *valueArr = [NSMutableArray arrayWithCapacity:values.count];
for (NSUInteger i = 0; i<values.count; i++) {
CGFloat scaleValue = [values[i] floatValue];
[valueArr addObject:[NSValue valueWithCATransform3D:CATransform3DMakeScale(scaleValue, scaleValue, scaleValue)]];
}
KFAnimation.values = valueArr;
KFAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
[layer addAnimation:KFAnimation forKey:nil];
}
- (UIColor *)lst_BlackWithAlpha:(CGFloat)alpha {
return [UIColor colorWithRed:0 green:0 blue:0 alpha:alpha];
}
// UIColorAlpha
- (UIColor *)getNewColorWith:(UIColor *)color alpha:(CGFloat)alpha {
if (self.isHideBg) {
return UIColor.clearColor;
}
if (self.bgColor == UIColor.clearColor) {
return UIColor.clearColor;
}
CGFloat red = 0.0;
CGFloat green = 0.0;
CGFloat blue = 0.0;
CGFloat resAlpha = 0.0;
[color getRed:&red green:&green blue:&blue alpha:&resAlpha];
UIColor *newColor = [UIColor colorWithRed:red green:green blue:blue alpha:alpha];
return newColor;
}
- (void)startTimer {
if (self.showTime > 0) {
LSTPopViewWK(self);;
NSString *idStr = [NSString stringWithFormat:@"LSTPopView_%p",self];
[LSTTimer addMinuteTimerForTime:self.showTime identifier:idStr handle:^(NSString * _Nonnull day, NSString * _Nonnull hour, NSString * _Nonnull minute, NSString * _Nonnull second, NSString * _Nonnull ms) {
if (wk_self.popViewCountDownBlock) {
wk_self.popViewCountDownBlock(wk_self, [second doubleValue]);
}
[wk_self lst_PopViewCountDownForPopView:wk_self forCountDown:[second doubleValue]];
} finish:^(NSString * _Nonnull identifier) {
[wk_self lst_PopViewCountDownFinishForPopView:wk_self];
[self dismiss];
} pause:^(NSString * _Nonnull identifier) {}];
}
}
/** */
- (void)removeForDelegate:(id<LSTPopViewProtocol>)delegate {
if (delegate) {
if ([self.delegates containsObject:delegate]) {
[self.delegates removeObject:delegate];
}
}
}
/** */
- (void)removeAllDelegate {
if (self.delegates.count > 0) {
[self.delegates removeAllObjects];
}
}
- (void)beginImpactFeedback {
if (self.isImpactFeedback) {
if (@available(iOS 10.0, *)) {
UIImpactFeedbackGenerator *feedBackGenertor = [[UIImpactFeedbackGenerator alloc] initWithStyle:UIImpactFeedbackStyleMedium];
[feedBackGenertor impactOccurred];
}
}
}
#pragma mark - ***** *****
- (void)statusBarOrientationChange:(NSNotification *)notification {
if (self.isObserverScreenRotation) {
CGRect originRect = self.customView.frame;
self.frame = CGRectMake(0, 0, pv_ScreenWidth(), pv_ScreenHeight());
self.backgroundView.frame = self.bounds;
self.customView.frame = originRect;
[self setCustomViewFrameWithHeight:0];
}
}
#pragma mark - ***** / *****
- (void)keyboardWillShow:(NSNotification *)notification{
// LSTPVLog(@"keyboardWillShow");
_isShowKeyboard = YES;
self.keyboardWillShowBlock? self.keyboardWillShowBlock():nil;
if (!self.isAvoidKeyboard) { return; }
CGFloat customViewMaxY = self.customView.pv_Bottom + self.avoidKeyboardSpace;
CGFloat duration = [notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue];
CGRect keyboardEedFrame = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGFloat keyboardMaxY = keyboardEedFrame.origin.y;
self.isAvoidKeyboard = YES;
self.avoidKeyboardOffset = customViewMaxY - keyboardMaxY;
self.keyboardY = keyboardEedFrame.origin.y;
//
if ((keyboardMaxY<customViewMaxY) || ((_originFrame.origin.y + _customView.pv_Height) > keyboardMaxY)) {
//
[UIView animateWithDuration:duration animations:^{
self.customView.pv_Y = self.customView.pv_Y - self.avoidKeyboardOffset;
}];
}
}
- (void)keyboardDidShow:(NSNotification *)notification{
_isShowKeyboard = YES;
self.keyboardDidShowBlock? self.keyboardDidShowBlock():nil;
}
- (void)keyboardWillHide:(NSNotification *)notification{
_isShowKeyboard = NO;
self.keyboardWillHideBlock? self.keyboardWillHideBlock():nil;
if (!self.isAvoidKeyboard) {
return;
}
CGFloat duration = [notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue];
[UIView animateWithDuration:duration animations:^{
self.customView.pv_Y = self.originFrame.origin.y;
}];
}
- (void)keyboardDidHide:(NSNotification *)notification{
_isShowKeyboard = NO;
self.keyboardDidHideBlock? self.keyboardDidHideBlock():nil;
}
- (void)keyboardWillChangeFrame:(NSNotification *)notification{
// LSTPVLog(@"键盘frame将要改变");
if (self.keyboardFrameWillChangeBlock) {
CGRect keyboardBeginFrame = [notification.userInfo[UIKeyboardFrameBeginUserInfoKey] CGRectValue];
CGRect keyboardEedFrame = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGFloat duration = [notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue];
self.keyboardFrameWillChangeBlock(keyboardBeginFrame,keyboardEedFrame,duration);
}
}
- (void)keyboardDidChangeFrame:(NSNotification *)notification{
// LSTPVLog(@"键盘frame已经改变");
if (self.keyboardFrameDidChangeBlock) {
CGRect keyboardBeginFrame = [notification.userInfo[UIKeyboardFrameBeginUserInfoKey] CGRectValue];
CGRect keyboardEedFrame = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGFloat duration = [notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue];
self.keyboardFrameDidChangeBlock(keyboardBeginFrame,keyboardEedFrame,duration);
}
}
#pragma mark - ***** UIGestureRecognizerDelegate *****
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
if(gestureRecognizer == self.panGesture) {
UIView *touchView = touch.view;
while (touchView != nil) {
if([touchView isKindOfClass:[UIScrollView class]]) {
self.isDragScrollView = YES;
self.scrollerView = (UIScrollView *)touchView;
break;
} else if(touchView == self.customView) {
self.isDragScrollView = NO;
break;
}
touchView = (id)[touchView nextResponder];
}
}
return YES;
}
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
if(gestureRecognizer == self.tapGesture) {
//
CGPoint point = [gestureRecognizer locationInView:self.customView];
BOOL iscontain = [self.customView.layer containsPoint:point];
if(iscontain) {
return NO;
}
} else if(gestureRecognizer == self.panGesture){
//
// LSTPVLog(@"gestureRecognizerShouldBegin");
}
return YES;
}
//3. 使(NO)
- (BOOL)gestureRecognizer:(UIPanGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
if(gestureRecognizer == self.panGesture) {
if ([otherGestureRecognizer isKindOfClass:NSClassFromString(@"UIScrollViewPanGestureRecognizer")] || [otherGestureRecognizer isKindOfClass:NSClassFromString(@"UIPanGestureRecognizer")] ) {
if([otherGestureRecognizer.view isKindOfClass:[UIScrollView class]] ) {
return YES;
}
}
}
return NO;
}
//
- (void)pan:(UIPanGestureRecognizer *)panGestureRecognizer {
self.panOffsetBlock?self.panOffsetBlock(CGPointMake(_customView.pv_X-_originFrame.origin.x, _customView.pv_Y-_originFrame.origin.y)):nil;
if (self.dragStyle == LSTDragStyleNO) {return;}
//
CGPoint transP = [panGestureRecognizer translationInView:self.customView];
CGPoint velocity = [panGestureRecognizer velocityInView:[UIApplication sharedApplication].keyWindow];
if(self.isDragScrollView) {//tableView,collectionView,scrollView
//tableView
if(self.scrollerView.contentOffset.y <= 0) {
//tableView
if(transP.y > 0) {
//
self.scrollerView.contentOffset = CGPointMake(0, 0);
self.scrollerView.panGestureRecognizer.enabled = NO;
self.isDragScrollView = NO;
//
self.customView.frame = CGRectMake(_customView.pv_X, _customView.pv_Y + transP.y, _customView.pv_Width, _customView.pv_Height);
} else {
//
}
}
} else {//tableView,collectionView,scrollView
CGFloat customViewX = self.customView.pv_X;
CGFloat customViewY = self.customView.pv_Y;
//X
if ((self.dragStyle & LSTDragStyleX_Positive) && (customViewX >= _originFrame.origin.x)) {
if (transP.x > 0) {
customViewX = customViewX + transP.x;
} else if(transP.x < 0 && customViewX > _originFrame.origin.x ){
customViewX = (customViewX + transP.x) > _originFrame.origin.x? (customViewX + transP.x):(_originFrame.origin.x);
}
}
//X
if ((self.dragStyle & LSTDragStyleX_Negative) && (customViewX <= self.originFrame.origin.x)) {
if (transP.x < 0) {
customViewX = customViewX + transP.x;
} else if(transP.x > 0 && customViewX < _originFrame.origin.x ){
customViewX = (customViewX + transP.x) < _originFrame.origin.x? (customViewX + transP.x):(_originFrame.origin.x);
}
}
//Y
if (self.dragStyle & LSTDragStyleY_Positive && (customViewY >= _originFrame.origin.y)) {
if (transP.y > 0) {
customViewY = customViewY + transP.y;
} else if(transP.y < 0 && customViewY > _originFrame.origin.y ){
customViewY = (customViewY + transP.y) > _originFrame.origin.y ?(customViewY + transP.y):(_originFrame.origin.y);
}
}
//Y
if (self.dragStyle & LSTDragStyleY_Negative&&(customViewY <= _originFrame.origin.y)) {
if (transP.y < 0) {
customViewY = customViewY + transP.y;
} else if(transP.y > 0 && customViewY < _originFrame.origin.y){
customViewY = (customViewY + transP.y) < _originFrame.origin.y?(customViewY + transP.y):(_originFrame.origin.y);
}
}
self.customView.frame = CGRectMake(customViewX, customViewY, _customView.pv_Width, _customView.pv_Height);
}
[panGestureRecognizer setTranslation:CGPointZero inView:self.customView];
if(panGestureRecognizer.state == UIGestureRecognizerStateEnded) {
if (self.scrollerView) {
self.scrollerView.panGestureRecognizer.enabled = YES;
}
LSTPopViewWK(self)
//Block
void (^dragReboundBlock)(void) = ^ {
[UIView animateWithDuration:wk_self.dragReboundTime
delay:0.1f
options:UIViewAnimationOptionCurveEaseOut
animations:^{
CGRect frame = wk_self.customView.frame;
frame.origin.y = wk_self.frame.size.height - wk_self.customView.frame.size.height;
wk_self.customView.frame = wk_self.originFrame;
} completion:^(BOOL finished) {}];
};
//Block
void (^sweepBlock)(BOOL,BOOL,BOOL,BOOL) = ^(BOOL isX_P, BOOL isX_N, BOOL isY_P, BOOL isY_N) {
if (isX_P==NO && isX_N==NO && isY_P==NO && isY_N==NO) {
dragReboundBlock();
return;
}
if (isY_P==NO && isY_N==NO && self.sweepDismissStyle == LSTSweepDismissStyleSmooth) {//X
if (velocity.x>0) {//
[self dismissWithStyle:LSTDismissStyleSmoothToRight duration:self.dismissDuration];
} else {//
[self dismissWithStyle:LSTDismissStyleSmoothToLeft duration:self.dismissDuration];
}
return;
}
if (isX_P==NO && isX_N==NO && self.sweepDismissStyle == LSTSweepDismissStyleSmooth) {//Y
if (velocity.y>0) {//
[self dismissWithStyle:LSTDismissStyleSmoothToBottom duration:self.dismissDuration];
} else {//
[self dismissWithStyle:LSTDismissStyleSmoothToTop duration:self.dismissDuration];
}
return;
}
//
[UIView animateWithDuration:0.5 animations:^{
wk_self.backgroundView.backgroundColor = [self getNewColorWith:self.bgColor alpha:0.0];
self.customView.center = CGPointMake(isX_P || isX_N?velocity.x:self.customView.pv_CenterX, isY_P||isY_N?velocity.y:self.customView.pv_CenterY);
} completion:^(BOOL finished) {
[wk_self dismissWithStyle:LSTDismissStyleFade duration:0.1];
}];
};
double velocityX = sqrt(pow(velocity.x, 2));
double velocityY = sqrt(pow(velocity.y, 2));
if((velocityX >= self.swipeVelocity)||(velocityY >= self.swipeVelocity)) {//
if (self.scrollerView.contentOffset.y>0) {
return;
}
//
BOOL isX_P = NO;
BOOL isX_N = NO;
BOOL isY_P = NO;
BOOL isY_N = NO;
if ((self.dragStyle & LSTDragStyleX_Positive) && velocity.x>0 && velocityX >= self.swipeVelocity) {
isX_P = self.sweepStyle & LSTSweepStyleX_Positive? YES:NO;
}
if ((self.dragStyle & LSTDragStyleX_Negative) && velocity.x<0 && velocityX >= self.swipeVelocity) {
isX_N = self.sweepStyle & LSTSweepStyleX_Negative? YES:NO;
}
if ((self.dragStyle & LSTDragStyleY_Positive) && velocity.y>0 && velocityY >= self.swipeVelocity) {
isY_P = self.sweepStyle & LSTSweepStyleY_Positive? YES:NO;
}
if ((self.dragStyle & LSTDragStyleY_Negative) && velocity.y <0 && velocityY >= self.swipeVelocity) {
isY_N = self.sweepStyle & LSTSweepStyleY_Negative? YES:NO;
}
sweepBlock(isX_P,isX_N,isY_P,isY_N);
// LSTPVLog(@"isX=%@,isY=%@,velocityX=%lf,velocityY=%lf",isX?@"YES":@"NO",isY?@"YES":@"NO",velocityX,velocityY);
}else {//
BOOL isCanDismiss = NO;
if (self.dragStyle & LSTDragStyleAll) {
if (fabs(self.customView.frame.origin.x - self.originFrame.origin.x)>=self.dragDistance && self.dragDistance!=0) {
isCanDismiss = YES;
}
if (fabs(self.customView.frame.origin.y - self.originFrame.origin.y)>=self.dragDistance && self.dragDistance!=0) {
isCanDismiss = YES;
}
if (isCanDismiss) {
[self dismissWithStyle:_isDragDismissStyle? self.dragDismissStyle:self.dismissStyle
duration:self.getDragDismissDuration];
}else {
dragReboundBlock();
}
} else {
dragReboundBlock();
}
}
}
}
#pragma mark - ***** *****
- (NSHashTable<id<LSTPopViewProtocol>> *)delegates {
if (_delegates) return _delegates;
_delegates = [NSHashTable hashTableWithOptions:NSPointerFunctionsWeakMemory];
return _delegates;
}
- (UIView *)parentView {
return self.container;
}
- (UIView *)currCustomView {
return self.customView;
}
#pragma mark - ***** api *****
/** popView */
+ (void)savePopView:(LSTPopView *)popView {
[LSTPopViewManager savePopView:popView];
}
/** (app)popView */
+ (NSArray *)getAllPopView {
return [LSTPopViewManager getAllPopView];
}
/** popView */
+ (NSArray *)getAllPopViewForParentView:(UIView *)parentView {
return [LSTPopViewManager getAllPopViewForParentView:parentView];
}
/** popView */
+ (NSArray *)getAllPopViewForPopView:(LSTPopView *)popView {
return [LSTPopViewManager getAllPopViewForPopView:popView];
}
/**
popView ()
使getPopViewForGroupId:forkey:
*/
+ (LSTPopView *)getPopViewForKey:(NSString *)key {
return [LSTPopViewManager getPopViewForKey:key];
}
/** popView */
+ (void)removePopView:(LSTPopView *)popView {
[LSTPopViewManager removePopView:popView];
}
/**
popView key ()
使removePopViewForGroupId:forkey:
*/
+ (void)removePopViewForKey:(NSString *)key {
[LSTPopViewManager removePopViewForKey:key];
}
/** popView */
+ (void)removeAllPopView {
[LSTPopViewManager removeAllPopView];
}
/** popView */
+ (void)removeLastPopView {
return [LSTPopViewManager removeLastPopView];
}
/** view 线 */
+ (void)setLogStyle:(LSTPopViewLogStyle)logStyle {
_logStyle = logStyle;
if (logStyle == LSTPopViewLogStyleNO) {
[LSTPopViewM().infoView removeFromSuperview];
LSTPopViewM().infoView = nil;
}
}
@end