首次提交

This commit is contained in:
启星
2025-08-08 11:05:33 +08:00
parent 1b3bb91b4a
commit adc1a2a25d
8803 changed files with 708874 additions and 0 deletions

21
Pods/TFPopup/LICENSE generated Executable file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2019 抱紧我的小鲤鱼
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

159
Pods/TFPopup/README.md generated Executable file
View File

@@ -0,0 +1,159 @@
# TFPopup
[![License MIT](https://img.shields.io/badge/License-MIT-orange)]() 
[![Platform iOS](https://img.shields.io/badge/platform-iOS-grayblue)]() 
[![Pod 1.2.0](https://img.shields.io/badge/pod-1.2.0-blue)]() 
### 中文版 | [English](https://github.com/shmxybfq/TFPopup/blob/master/README_EN.md)
**🚀🚀🚀不耦合view代码,可以为已创建过 / 未创建过的view添加弹出方式;
<br>🚀🚀🚀TFPopup不是弹框,它只是一种弹出方式;**
<br>使用TFPopup做弹框会让你的弹框变的异常简单:
<br>1.已经有一个view。
<br>2.用喜欢的方式将它弹出来。<br>
## 注意
文档包含大量gif图片,可能加载较慢<br>
项目分别包含Swift 和 OC Demo
## 特点
- 和view代码不耦合<br>
&nbsp;&nbsp;&nbsp;&nbsp;你可以将一个新的/已存在的view调用弹出方法将他弹出来
- 默认支持多种弹出方式<br>
&nbsp;&nbsp;&nbsp;&nbsp;无动画覆盖 / 缩放弹出 / 滑动弹出 / 基于某点的泡泡方式弹出 / 基于frame变化的弹出 / 基于于遮罩的遮罩弹出 / 折叠弹出
- 在弹出方式基础上可以通过**调节参数**来调整**弹出效果**<br>
&nbsp;&nbsp;&nbsp;&nbsp;**拖动:** 开启/关闭拖动 / 是否开启拖动弹性效果 / 设置拖动松手后自动消失距离<br>
&nbsp;&nbsp;&nbsp;&nbsp;**拖动方式:** 自由模式下弹框可全方向拖动,松手后触发消失 / 组合模式下可自由组合上下左右四个方向进行方向识别<br>
&nbsp;&nbsp;&nbsp;&nbsp;**时间调整:** 动画时间 / 动画延迟开始时间/动画延迟消失时间 / 弹框自动消失时间<br>
&nbsp;&nbsp;&nbsp;&nbsp;**时间曲线:** 通过UIViewAnimationOptions设置动画时间曲线<br>
&nbsp;&nbsp;&nbsp;&nbsp;**弹出背景:** 是否使用背景 / 调整背景颜色 / 背景色透明 / 背景点击事件及默认自动点击消失 / 背景显示、消失透明度动画<br>
&nbsp;&nbsp;&nbsp;&nbsp;**渐隐和位置:** 弹出渐隐 / 消失渐隐 / 弹出位置变化 / 消失位置变化<br>
&nbsp;&nbsp;&nbsp;&nbsp;**尺寸和位置:** 弹出区域计算尺寸设置 / 弹框尺寸 / 位置偏移量 / 初始位置 / 目标位置 / 是否始终保持原位置<br>
&nbsp;&nbsp;&nbsp;&nbsp;**属性动画:** 可分别设置显示、消失时的属性动画,只需要设置属性:属性值、初始值、结束值即可使用丰富的属性动画效果<br>
&nbsp;&nbsp;&nbsp;&nbsp;**泡泡:** 泡泡基准点 / 泡泡八个弹出方向<br>
&nbsp;&nbsp;&nbsp;&nbsp;**mask** 可分别设置显示、消失时的mask,只需要设置属性:mask初始path、mask结束path即可<br>
- 保留弹出全过程接口,支持完全自定义弹出方式、动画、和背景<br>
&nbsp;&nbsp;&nbsp;&nbsp;**TFPopupDataSource**此代理包含弹出动画需要的各种参数配置,在动画开始后会依次被调用
&nbsp;&nbsp;&nbsp;&nbsp;**TFPopupBackgroundDelegate**同TFPopupDataSource一样可通过实现一个或多个方法来截断和修改弹出过程以实现完全自定义背景和背景动画
&nbsp;&nbsp;&nbsp;&nbsp;**TFPopupDelegate**代理包含整个弹出过程事件TFPopup使view本身实现此代理来封装以上动画效果的组合和弹出你可以在弹框类中
&nbsp;&nbsp;&nbsp;&nbsp;重写一个或多个方法来截断和修改弹出过程以实现完全自定义动画效果
## 弹出效果图示例
**拖动**
___
<div>
<img src="https://github.com/shmxybfq/TFProductResource/blob/master/TFPopup-Example/drag1.gif" width="30%" height="30%">
<img src="https://github.com/shmxybfq/TFProductResource/blob/master/TFPopup-Example/drag2.gif" width="30%" height="30%">
<img src="https://github.com/shmxybfq/TFProductResource/blob/master/TFPopup-Example/drag3.gif" width="30%" height="30%">
</div>
<div>
<img src="https://github.com/shmxybfq/TFProductResource/blob/master/TFPopup-Example/drag0.gif" width="30%" height="30%">
<img src="https://github.com/shmxybfq/TFProductResource/blob/master/TFPopup-Example/drag4.gif" width="30%" height="30%">
</div>
<br>
**自定义动画效果**
___
<div>
<img src="https://github.com/shmxybfq/TFProductResource/blob/master/TFPopup-Example/cus-6.gif" width="30%" height="30%">
<img src="https://github.com/shmxybfq/TFProductResource/blob/master/TFPopup-Example/cus-2.gif" width="30%" height="30%">
<img src="https://github.com/shmxybfq/TFProductResource/blob/master/TFPopup-Example/cus-3.gif" width="30%" height="30%">
</div>
<div>
<img src="https://github.com/shmxybfq/TFProductResource/blob/master/TFPopup-Example/cus-4.gif" width="30%" height="30%">
<img src="https://github.com/shmxybfq/TFProductResource/blob/master/TFPopup-Example/cus-5.gif" width="30%" height="30%">
<img src="https://github.com/shmxybfq/TFProductResource/blob/master/TFPopup-Example/cus-1.gif" width="30%" height="30%">
</div>
<br>
**默认动画效果**
___
<div>
<img src="https://github.com/shmxybfq/TFProductResource/blob/master/TFPopup-Example/exa1.gif" width="30%" height="30%">
<img src="https://github.com/shmxybfq/TFProductResource/blob/master/TFPopup-Example/exa2.gif" width="30%" height="30%">
<img src="https://github.com/shmxybfq/TFProductResource/blob/master/TFPopup-Example/exa3.gif" width="30%" height="30%">
</div>
<div>
<img src="https://github.com/shmxybfq/TFProductResource/blob/master/TFPopup-Example/exa4.gif" width="30%" height="30%">
<img src="https://github.com/shmxybfq/TFProductResource/blob/master/TFPopup-Example/exa5.gif" width="30%" height="30%">
<img src="https://github.com/shmxybfq/TFProductResource/blob/master/TFPopup-Example/exa6.gif" width="30%" height="30%">
</div>
<div>
<img src="https://github.com/shmxybfq/TFProductResource/blob/master/TFPopup-Example/exa7.gif" width="30%" height="30%">
<img src="https://github.com/shmxybfq/TFProductResource/blob/master/TFPopup-Example/exa8.gif" width="30%" height="30%">
<img src="https://github.com/shmxybfq/TFProductResource/blob/master/TFPopup-Example/exa9.gif" width="30%" height="30%">
</div>
<br>
**基于默认动画效果的参数自由组合**
___
<div>
<img src="https://github.com/shmxybfq/TFProductResource/blob/master/TFPopup-Example/nor-bubble.gif" width="30%" height="30%">
<img src="https://github.com/shmxybfq/TFProductResource/blob/master/TFPopup-Example/nor-mask.gif" width="30%" height="30%">
<img src="https://github.com/shmxybfq/TFProductResource/blob/master/TFPopup-Example/nor-slide.gif" width="30%" height="30%">
</div>
## 使用
图片加载较慢请耐心等待或在项目目录中查找使用截图资源
<br/>
### 普通用法
不设置TFPopupParam
<br/>
<div>
<img src="https://github.com/shmxybfq/TFPopup/blob/master/Example/TFPopupOperatingInstruction.png" width="100%" height="100%">
</div>
### 高级用法
通过设置TFPopupParam修改弹出方式和动画等
<br/>
<div>
<img src="https://github.com/shmxybfq/TFPopup/blob/master/Example/TFPopupParam.png" width="100%" height="100%">
</div>
### 自定义用法
通过在view上重写TFPopupDataSource 和 TFPopupBackgroundDelegate 的一个或多个方法来实现你想要的效果
<br/>
<div>
<img src="https://github.com/shmxybfq/TFPopup/blob/master/Example/delegateAndDatasource.png" width="100%" height="100%">
</div>
## 自定义用法请注意!!!
下图此属性TFPopupExtension是弹框view整个弹框过程中保存内部属性的一个model,所有和弹框过程相关的属性都在这里
<br/>
<div>
<img src="https://github.com/shmxybfq/TFPopup/blob/master/Example/UIView+TFPopup.png" width="100%" height="100%">
</div>
<br/>
TFPopupExtension model详情
<div>
<img src="https://github.com/shmxybfq/TFPopup/blob/master/Example/TFPopupExtension.png" width="100%" height="100%">
</div>
## 使用补充
##### 以上方式简单描述了使用方法,具体效果和使用请参照demo !
##### 此框架会一直更新维护【转行除外】请放心使用。
## 安装
```
pod 'TFPopup'
```
## 如果
使用过程中有bug或不足请随时issues我或者联系我<br>
现有功能满足不了你的需求请随时issues我或者联系我<br>
有更好的建议或者优化请随时issues我或者联系我<br>
QQ:927141965;<br>
邮箱shmxybfq@163.com;<br>

View File

@@ -0,0 +1,21 @@
//
// NSObject+TFPopupMethodExchange.h
// TFPopupDemo
//
// Created by zhutaofeng on 2019/8/15.
// Copyright © 2019 ztf. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
@interface NSObject (TFPopupMethodExchange)
/**
* 交换类方法和交换实例方法
*/
+(BOOL)popup_instanceMethodExchange:(SEL)originSel toClass:(Class)toClass toSel:(SEL)toSel;
+(BOOL)popup_classMethodExchange:(SEL)originSel toClass:(Class)toClass toSel:(SEL)toSel;
@end

View File

@@ -0,0 +1,45 @@
//
// NSObject+TFPopupMethodExchange.m
// TFPopupDemo
//
// Created by zhutaofeng on 2019/8/15.
// Copyright © 2019 ztf. All rights reserved.
//
#import "NSObject+TFPopupMethodExchange.h"
@implementation NSObject (TFPopupMethodExchange)
/**
*
*/
+(BOOL)popup_instanceMethodExchange:(SEL)originSel toClass:(Class)toClass toSel:(SEL)toSel{
Method originMethod = class_getInstanceMethod([self class], originSel);
Method toMethod = class_getInstanceMethod(toClass, toSel);
BOOL added = class_addMethod([self class], originSel, method_getImplementation(toMethod), method_getTypeEncoding(toMethod));
if (!added) {
method_exchangeImplementations(originMethod, toMethod);
}else{
class_replaceMethod(self, toSel, method_getImplementation(originMethod), method_getTypeEncoding(originMethod));
}
return YES;
}
+(BOOL)popup_classMethodExchange:(SEL)originSel toClass:(Class)toClass toSel:(SEL)toSel{
Method originMethod = class_getClassMethod([self class], originSel);
Method toMethod = class_getClassMethod(toClass, toSel);
Class metaClass = objc_getMetaClass(NSStringFromClass([self class]).UTF8String);
IMP toImp = method_getImplementation(toMethod);
const char *toTypeEncoding = method_getTypeEncoding(toMethod);
BOOL addMethod = class_addMethod(metaClass,originSel,toImp,toTypeEncoding);
if (!addMethod) {
method_exchangeImplementations(originMethod, toMethod);
}else{
IMP originImp = method_getImplementation(originMethod);
const char *originTypeEncoding = method_getTypeEncoding(originMethod);
class_replaceMethod([self class],toSel,originImp,originTypeEncoding);
}
return YES;
}
@end

15
Pods/TFPopup/TFPopup/TFPopup.h generated Executable file
View File

@@ -0,0 +1,15 @@
//
// TFPopup.h
// TFPopupDemo
//
// Created by ztf on 2019/1/14.
// Copyright © 2019年 ztf. All rights reserved.
//
#ifndef TFPopup_h
#define TFPopup_h
#import "TFPopupToast.h"
#import "UIView+TFPopup.h"
#endif /* TFPopup_h */

49
Pods/TFPopup/TFPopup/TFPopupConst.h generated Executable file
View File

@@ -0,0 +1,49 @@
//
// TFPopupConst.h
// TFPopupDemo
//
// Created by zhutaofeng on 2019/5/13.
// Copyright © 2019 ztf. All rights reserved.
//
#ifndef TFPopupConst_h
#define TFPopupConst_h
#import <objc/runtime.h>
#pragma mark -- 属性绑定
#ifndef tf_synthesize_category_property
#define tf_synthesize_category_property(getter,settter,objc_AssociationPolicy,TYPE)\
- (TYPE)getter{return objc_getAssociatedObject(self, @selector(getter));}\
- (void)settter:(TYPE)obj{objc_setAssociatedObject(self, @selector(getter), obj, objc_AssociationPolicy);}
#endif
#ifndef tf_synthesize_category_property_retain
#define tf_synthesize_category_property_retain(getter,settter) tf_synthesize_category_property(getter,settter,OBJC_ASSOCIATION_RETAIN_NONATOMIC,id)
#endif
#ifndef tf_synthesize_category_property_copy
#define tf_synthesize_category_property_copy(getter,settter) tf_synthesize_category_property(getter,settter,OBJC_ASSOCIATION_COPY,id)
#endif
#ifndef tf_synthesize_category_property_assign
#define tf_synthesize_category_property_assign(getter,settter) tf_synthesize_category_property(getter,settter,OBJC_ASSOCIATION_ASSIGN,id)
#endif
#ifndef x_weakSelf
#define x_weakSelf __weak typeof(self) weakself = self
#endif
#ifdef DEBUG
#define PopupLog(fmt, ...) NSLog((@"\nfunc:%s,line:%d\n" fmt @"\n"), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
#else
#define PopupLog(...)
#endif
typedef NS_ENUM(NSInteger,TFAnimationType) {
TFAnimationTypeFade,
TFAnimationTypeScale,
};
#endif /* TFPopupConst_h */

119
Pods/TFPopup/TFPopup/TFPopupExtension.h generated Executable file
View File

@@ -0,0 +1,119 @@
//
// TFPopupExtension.h
// TFPopupDemo
//
// Created by Time on 2019/3/4.
// Copyright © 2019 ztf. All rights reserved.
//
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import "TFPopupParam.h"
typedef NS_ENUM(NSInteger,DelegateProcess) {
DelegateProcessWillGetConfiguration = 0,//将要获取弹出配置
DelegateProcessDidGetConfiguration,//已经获取弹出配置
DelegateProcessWillShow,//将要弹出
DelegateProcessDidShow,//已经调用完弹出,正在执行动画
DelegateProcessShowAnimationDidFinish,//弹出动画执行完成
DelegateProcessWillHide,//将要消失
DelegateProcessDidHide,//已经调用完消失,正在执行动画
DelegateProcessHideAnimationDidFinish,//消失动画执行完成
DelegateProcessBackgroundDidTouch,//默认背景点击
};
typedef void(^TFDelegateProcessBlock)(UIView *pop,DelegateProcess pro);
@interface TFPopupExtension : NSObject
/* TFPopupDataSource */
@property(nonatomic, weak)UIView *inView;
@property(nonatomic,assign)CGSize popupArea;
@property(nonatomic,strong)UIButton *defaultBackgroundView;
@property(nonatomic,assign)NSInteger backgroundViewCount;
@property(nonatomic,strong)NSMutableArray *backgroundViewArray;
@property(nonatomic,strong)NSMutableArray *backgroundViewFrameArray;
@property(nonatomic,assign)BOOL disuseShowAlphaAnimation;
@property(nonatomic,assign)CGFloat showFromAlpha;
@property(nonatomic,assign)CGFloat showToAlpha;
@property(nonatomic,assign)BOOL disuseShowFrameAnimation;
@property(nonatomic,assign)CGRect showFromFrame;
@property(nonatomic,assign)CGRect showToFrame;
@property(nonatomic,assign)BOOL disuseHideAlphaAnimation;
@property(nonatomic,assign)CGFloat hideFromAlpha;
@property(nonatomic,assign)CGFloat hideToAlpha;
@property(nonatomic,assign)BOOL disuseHideFrameAnimation;
@property(nonatomic,assign)CGRect hideFromFrame;
@property(nonatomic,assign)CGRect hideToFrame;
/* TFPopupDelegate */
@property(nonatomic,assign)NSTimeInterval showAnimationDuration;
@property(nonatomic,assign)NSTimeInterval showAnimationDelay;
@property(nonatomic,assign)UIViewAnimationOptions showAnimationOptions;
@property(nonatomic,assign)NSTimeInterval hideAnimationDuration;
@property(nonatomic,assign)NSTimeInterval hideAnimationDelay;
@property(nonatomic,assign)UIViewAnimationOptions hideAnimationOptions;
@property(nonatomic,assign)PopupStyle style;//默认动画类型
@property(nonatomic,assign)PopupDirection direction;//默认动画方向,仅在滑动动画和泡泡动画下有效
//存储折叠和滑动时的方向
@property(nonatomic,assign)PopupDirection foldDirection;
@property(nonatomic,assign)PopupDirection slideDirection;
//监听弹框隐藏完毕回调,需要再显示弹框前调用此方法
@property(nonatomic, copy)TFDelegateProcessBlock delegateProcessBlock;
#pragma mark - 拖动相关
//拖住手势
@property(nonatomic,strong)UIPanGestureRecognizer *dragGes;
//当前拖动的滚动视图
@property(nonatomic,strong)UIScrollView *currentDragScrollView;
//当前拖动的滚动视图
@property(nonatomic,assign)BOOL currentDragScrollViewAllowScroll;
//拖动开始点
@property(nonatomic,assign)CGPoint dragBeginSelfPoint;
@property(nonatomic,assign)CGPoint dragBeginSuperPoint;
//是否需要推测多拽方式
@property(nonatomic,assign)BOOL needDiscernDragStyle;
//运行时的真正拖拽方式
@property(nonatomic,assign)DragStyle runtimeDragStyle;
//推测拖动方式时的开始点
@property(nonatomic,assign)CGPoint discernDragStyleBeginSelfPoint;
@property(nonatomic,assign)CGPoint discernDragStyleBeginSuperPoint;
//拖动结束后要消失的目标frame
@property(nonatomic,assign)CGRect dragDissmissFrame;
@end
@class TFPopupPoolBridge;
@interface TFPopupPool : NSObject
//已经弹出的弹窗,弱引用记录
@property(nonatomic,strong)NSMutableArray <TFPopupPoolBridge *>*pool;
+(void)refreshPool;
+(void)addToPool:(UIView *)popupView;
+(UIView *)findPopup:(NSString *)identifier;
+(NSArray <UIView *>*)allPopup;
@end
@interface TFPopupPoolBridge : NSObject
//已经弹出的弹窗,弱引用记录
@property(nonatomic, weak)UIView *popupView;
@end

99
Pods/TFPopup/TFPopup/TFPopupExtension.m generated Executable file
View File

@@ -0,0 +1,99 @@
//
// TFPopupExtension.m
// TFPopupDemo
//
// Created by Time on 2019/3/4.
// Copyright © 2019 ztf. All rights reserved.
//
#import "TFPopupExtension.h"
#import "UIView+TFPopup.h"
@implementation TFPopupExtension
-(NSMutableArray *)backgroundViewArray{
if (_backgroundViewArray == nil) {
_backgroundViewArray = [[NSMutableArray alloc]init];
}
return _backgroundViewArray;
}
-(NSMutableArray *)backgroundViewFrameArray{
if (_backgroundViewFrameArray == nil) {
_backgroundViewFrameArray = [[NSMutableArray alloc]init];
}
return _backgroundViewFrameArray;
}
@end
@implementation TFPopupPool
static TFPopupPool *_popupPool = nil;
+(instancetype)shareInstance{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_popupPool = [[TFPopupPool alloc]init];
});
return _popupPool;
}
+(void)refreshPool{
[[TFPopupPool shareInstance]refreshPool];
}
-(void)refreshPool{
NSMutableArray *newPool = [[NSMutableArray alloc]init];
for (TFPopupPoolBridge *bridge in self.pool) {
if (bridge.popupView != nil) {
[newPool addObject:bridge];
}
}
[self.pool removeAllObjects];
[self.pool addObjectsFromArray:newPool];
}
+(void)addToPool:(UIView *)popupView{
[[TFPopupPool shareInstance]addToPool:popupView];
}
-(void)addToPool:(UIView *)popupView{
TFPopupPoolBridge *bridge = [[TFPopupPoolBridge alloc]init];
bridge.popupView = popupView;
[self.pool addObject:bridge];
}
+(UIView *)findPopup:(NSString *)identifier{
return [[TFPopupPool shareInstance]findPopup:identifier];
}
-(UIView *)findPopup:(NSString *)identifier{
for (TFPopupPoolBridge *bridge in self.pool) {
if ([bridge.popupView.identifier isEqualToString:identifier]) {
return bridge.popupView;
}
}
return nil;
}
+(NSArray <UIView *>*)allPopup{
return [[TFPopupPool shareInstance]allPopup];
}
-(NSArray <UIView *>*)allPopup{
NSMutableArray *newPool = [[NSMutableArray alloc]init];
for (TFPopupPoolBridge *bridge in self.pool) {
if (bridge.popupView.superview != nil) {
[newPool addObject:bridge.popupView];
}
}
return newPool;
}
-(NSMutableArray *)pool{
if (!_pool) {
_pool = [[NSMutableArray alloc]init];
}
return _pool;
}
@end
@implementation TFPopupPoolBridge
@end

25
Pods/TFPopup/TFPopup/TFPopupLoading.h generated Executable file
View File

@@ -0,0 +1,25 @@
//
// TFPopupLoading.h
// TFPopupDemo
//
// Created by zhutaofeng on 2019/5/13.
// Copyright © 2019 ztf. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "TFPopupConst.h"
@class TFPopupLoading;
typedef void(^TFPopupLoadingBlock)(TFPopupLoading *toast);
@interface TFPopupLoading : UIView
@property(nonatomic,strong)UIActivityIndicatorView *indicatorView;
@property(nonatomic,strong)UILabel *msgLabel;
+(void)tf_show:(UIView *)inView animationType:(TFAnimationType)animationType;
+(void)tf_hide:(UIView *)inView;
@end

137
Pods/TFPopup/TFPopup/TFPopupLoading.m generated Executable file
View File

@@ -0,0 +1,137 @@
//
// TFPopupLoading.m
// TFPopupDemo
//
// Created by zhutaofeng on 2019/5/13.
// Copyright © 2019 ztf. All rights reserved.
//
#import "TFPopupLoading.h"
#import "UIView+TFPopup.h"
@interface TFPopupLoading ()<TFPopupDelegate>
@property(nonatomic,assign)CGRect inViewFrame;
@property(nonatomic, copy)NSString *msg;
@property(nonatomic, copy)TFPopupLoadingBlock cusBlock;
@end
@implementation TFPopupLoading
-(void)dealloc{
#if DEBUG
NSLog(@"****** TFPopupLoading(已释放) msg:%@ ******",self.msg);
#endif
}
+(void)tf_show:(UIView *)inView animationType:(TFAnimationType)animationType{
[TFPopupLoading tf_show:inView msg:@"正在加载..." animationType:animationType];
}
+(void)tf_show:(UIView *)inView msg:(NSString *)msg animationType:(TFAnimationType)animationType{
[TFPopupLoading tf_show:inView
msg:msg
offset:CGPointZero
animationType:animationType
customBlock:nil];
}
+(void)tf_show:(UIView *)inView
msg:(NSString *)msg
offset:(CGPoint)offset
animationType:(TFAnimationType)animationType
customBlock:(TFPopupLoadingBlock)customBlock{
if (inView == nil) {NSLog(@"****** %@ %@ ******",[self class],@"inView 不能为空!");return;}
if (msg == nil) {NSLog(@"****** %@ %@ ******",[self class],@"msg 不能为空!");return;}
TFPopupParam *param = [TFPopupParam new];
param.backgroundColorClear = YES;
param.offset = offset;
param.popupSize = CGSizeMake(90, 90);
param.disuseBackgroundTouchHide = YES;
TFPopupLoading *loading = [[TFPopupLoading alloc]initWithFrame:CGRectZero];
loading.inViewFrame = inView.bounds;
loading.msg = msg;
loading.cusBlock = customBlock;
switch (animationType) {
case TFAnimationTypeFade:
[loading tf_showNormal:inView popupParam:param];
break;
case TFAnimationTypeScale:
[loading tf_showScale:inView offset:CGPointZero popupParam:param];
break;
default:
break;
}
}
+(void)tf_hide:(UIView *)inView{
for (UIView *loading in inView.subviews) {
if ([loading isKindOfClass:[TFPopupLoading class]]) {
[loading tf_hide];
}
}
}
-(instancetype)initWithFrame:(CGRect)frame{
if (self = [super initWithFrame:frame]) {
self.layer.cornerRadius = 6;
self.layer.masksToBounds = YES;
self.backgroundColor = [[UIColor blackColor]colorWithAlphaComponent:0.7];
self.userInteractionEnabled = NO;
[self.indicatorView startAnimating];
[self addSubview:self.indicatorView];
[self addSubview:self.msgLabel];
}
return self;
}
-(void)setMsg:(NSString *)msg{
_msg = [msg copy];
self.msgLabel.text = msg;
}
-(void)layoutSubviews{
[super layoutSubviews];
CGRect sf = self.bounds;
if (self.msg == nil || self.msg.length == 0) {
self.indicatorView.center = CGPointMake(sf.size.width * 0.5, sf.size.height * 0.5);
self.msgLabel.frame = CGRectMake(10, sf.size.height * 0.5 + 10, sf.size.width - 20, 0);
}else{
self.indicatorView.center = CGPointMake(sf.size.width * 0.5, 35);
self.msgLabel.frame = CGRectMake(10, sf.size.height * 0.5 + 10, sf.size.width - 20, 20);
}
}
-(UIActivityIndicatorView *)indicatorView{
if (_indicatorView == nil) {
_indicatorView = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
}
return _indicatorView;
}
-(UILabel *)msgLabel{
if (_msgLabel == nil) {
_msgLabel = [[UILabel alloc]initWithFrame:CGRectZero];
_msgLabel.textColor = [UIColor whiteColor];
_msgLabel.font = [UIFont systemFontOfSize:13];
_msgLabel.textAlignment = NSTextAlignmentCenter;
_msgLabel.backgroundColor = [UIColor clearColor];
_msgLabel.numberOfLines = 0;
_msgLabel.lineBreakMode = NSLineBreakByClipping;
_msgLabel.clipsToBounds = YES;
}
return _msgLabel;
}
@end

168
Pods/TFPopup/TFPopup/TFPopupParam.h generated Executable file
View File

@@ -0,0 +1,168 @@
//
// TFPopupParam.h
// TFPopupDemo
//
// Created by ztf on 2019/1/18.
// Copyright © 2019年 ztf. All rights reserved.
//
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
typedef NS_ENUM(NSInteger,PopupDirection) {
PopupDirectionContainerCenter = 0,
PopupDirectionTop,
PopupDirectionTopRight,
PopupDirectionRight,
PopupDirectionRightBottom,
PopupDirectionBottom,
PopupDirectionBottomLeft,
PopupDirectionLeft,
PopupDirectionLeftTop,
PopupDirectionFrame,
};
typedef NS_ENUM(NSInteger,DragStyle) {
DragStyleNone = 0,//不可拖拽
DragStyleToTop = 1 << 0,//可以向上拖拽,可自由组合其他三个方向
DragStyleToLeft = 1 << 1,//可以向左拖拽,可自由组合其他三个方向
DragStyleToRight = 1 << 2,//可以向右拖拽,可自由组合其他三个方向
DragStyleToBottom = 1 << 3,//可以向下拖拽,可自由组合其他三个方向
DragStyleFree = 1000,//可以向任何方向拖拽,但松手后不消失
};
typedef NS_ENUM(NSInteger,PopupStyle) {
PopupStyleNone = 0,
PopupStyleDefaultAlpha = 1 << 0,
PopupStyleDefaultFrame = 1 << 1,
PopupStyleExtensionMask = 1 << 2,
PopupStyleExtensionAniamtion = 1 << 3,
};
typedef NS_ENUM(NSInteger,TFPopupState) {
TFPopupStateShow = 0,
TFPopupStateHide,
};
@interface TFPopupParam : NSObject
/* 【全局属性】参数载体
object0,object1,object1,用于弹框时需要传递的参数;
*/
@property(nonatomic,strong)id object0;
@property(nonatomic,strong)id object1;
@property(nonatomic,strong)id object2;
/* 【全局属性】时间
duration,动画时间default=0.3
showAnimationDelay,动画延迟执行时间:调用弹出后延迟此时间后执行弹出动画
hideAnimationDelay,动画延迟执行时间:调用消失后延迟此时间后执行弹出动画
autoDissmissDuration,自动消失时间,default=0
animationOptions,默认渐隐和frame动画的动画曲线default=UIViewAnimationOptionCurveEaseOut
*/
@property(nonatomic,assign)NSTimeInterval duration;
@property(nonatomic,assign)NSTimeInterval showAnimationDelay;
@property(nonatomic,assign)NSTimeInterval hideAnimationDelay;
@property(nonatomic,assign)NSTimeInterval autoDissmissDuration;
@property(nonatomic,assign)UIViewAnimationOptions animationOptions;
/* 【全局属性】背景
disuseBackground,不使用背景,default=NO,如果设为YES则自定义代理的方法也会被禁止
backgroundColor,默认背景的背景颜色,default=0.3alpha的黑色
backgroundColorClear,默认背景的背景色设为透明
disuseBackgroundTouchHide,禁止点击背景消失弹框
disuseShowBackgroundAlphaAnimation,不使用显示时的渐隐动画default=NO
disuseShowBackgroundAlphaAnimation,不使用消失时的渐隐动画default=NO
*/
@property(nonatomic,assign)BOOL disuseBackground;
@property(nonatomic,strong)UIColor *backgroundColor;
@property(nonatomic,assign)BOOL backgroundColorClear;
@property(nonatomic,assign)BOOL disuseBackgroundTouchHide;
@property(nonatomic,assign)BOOL disuseShowBackgroundAlphaAnimation;
@property(nonatomic,assign)BOOL disuseHideBackgroundAlphaAnimation;
/* 【全局属性】拖拽控制
dragEnable,是否可拖拽,默认为NO,设为YES时tf_showSlide的上下左右方向默认可以向消失的方向拖拽
dragStyle,拖拽类型/方向
dragBouncesEnable,拖拽到底的时候是否有弹性效果
discernScrollEnable,当拖拽的view中包含scrollview时,是否兼容识别拖拽
dragAutoDissmissMinDistance,拖拽松手时的距离大于此距离时拖拽消失,否则恢复原位
*/
@property(nonatomic,assign)BOOL dragEnable;
@property(nonatomic,assign)DragStyle dragStyle;
@property(nonatomic,assign)BOOL dragBouncesEnable;
@property(nonatomic,assign)BOOL discernScrollEnable;
@property(nonatomic,assign)NSUInteger dragAutoDissmissMinDistance;
/* 【全局属性】弹框渐隐动画
disuseShowPopupAlphaAnimation,不使用弹出时的渐隐动画default=NO
disuseHidePopupAlphaAnimation,不使用消失时的渐隐动画default=NO
disuseShowPopupFrameAnimation,不使用弹出时的frame动画default=NO
disuseHidePopupFrameAnimation,不使用消失时的frame动画default=NO
*/
@property(nonatomic,assign)BOOL disuseShowPopupAlphaAnimation;
@property(nonatomic,assign)BOOL disuseHidePopupAlphaAnimation;
@property(nonatomic,assign)BOOL disuseShowPopupFrameAnimation;
@property(nonatomic,assign)BOOL disuseHidePopupFrameAnimation;
/* 【全局属性】弹框尺寸和区域
popupAreaRect,弹框所在区域尺寸,default=父视图的bounds,此属性决定了弹框的位置和大小计算
popupSize,弹框尺寸,default=弹框的frame.size
offset,弹框偏移,offset.x正为右移,offset.y正为下移
popOriginFrame,弹框初始frame
popTargetFrame,弹框动画后的frame
keepPopupOriginFrame,是否保持原有frame不变,值为YES时,不对frame进行计算和操作
zIndex,多个弹窗同时出现时的层次默认为0
*/
@property(nonatomic,assign)CGRect popupAreaRect;
@property(nonatomic,assign)CGSize popupSize;
@property(nonatomic,assign)CGPoint offset;
@property(nonatomic,assign)CGRect popOriginFrame;
@property(nonatomic,assign)CGRect popTargetFrame;
@property(nonatomic,assign)BOOL keepPopupOriginFrame;
@property(nonatomic,assign)NSInteger zIndex;
/* 【全局属性】属性动画 和 默认缩放动画冲突
showKeyPath,显示时的属性动画keyPath
showFromValue,显示动画初始值
showToValue,,显示动画结束值
hideKeyPath,隐藏时的属性动画keyPath
hideFromValue,隐藏动画初始值
hideToValue,隐藏动画结束值
*/
@property(nonatomic, copy)NSString *showKeyPath;
@property(nonatomic,strong)id showFromValue;
@property(nonatomic,strong)id showToValue;
@property(nonatomic, copy)NSString *hideKeyPath;
@property(nonatomic,strong)id hideFromValue;
@property(nonatomic,strong)id hideToValue;
/* 【泡泡弹出方式属性】
basePoint,弹出泡泡基于哪个点
bubbleDirection,弹出泡泡的方向,八个方向
*/
@property(nonatomic,assign)CGPoint basePoint;
@property(nonatomic,assign)PopupDirection bubbleDirection;
/* 【全局属性】遮罩
maskShowFromPath,必须参数
maskShowToPath,必须参数
maskHideFromPath,非必填为空时值为maskShowToPath
maskHideToPath,非必填为空时值为maskShowFromPath
*/
@property(nonatomic,strong)UIBezierPath *maskShowFromPath;
@property(nonatomic,strong)UIBezierPath *maskShowToPath;
@property(nonatomic,strong)UIBezierPath *maskHideFromPath;
@property(nonatomic,strong)UIBezierPath *maskHideToPath;
@end

13
Pods/TFPopup/TFPopup/TFPopupParam.m generated Executable file
View File

@@ -0,0 +1,13 @@
//
// TFPopupParam.m
// TFPopupDemo
//
// Created by ztf on 2019/1/18.
// Copyright © 2019 ztf. All rights reserved.
//
#import "TFPopupParam.h"
@implementation TFPopupParam
@end

39
Pods/TFPopup/TFPopup/TFPopupToast.h generated Executable file
View File

@@ -0,0 +1,39 @@
//
// TFPopupToast.h
// TFPopupDemo
//
// Created by ztf on 2019/1/14.
// Copyright © 2019年 ztf. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "TFPopupConst.h"
@class TFPopupToast;
typedef void(^TFPopupToastBlock)(TFPopupToast *toast);
@interface TFPopupToast : UIView
@property(nonatomic,assign)UIEdgeInsets edge;
@property(nonatomic,strong)UILabel *msgLabel;
//注释同下
+(void)tf_show:(UIView *)inView msg:(NSString *)msg animationType:(TFAnimationType)animationType;
/* toast展示,默认黑底白字,底80%黑色不透明度
* inView 容器视图
* msg弹出string
* offset,弹框偏移,offset.x正为右移,offset.y正为下移
* duration,自动消失时间值为0时默认被设置为最低为1.5s,根据字数计算消失时间最大5s
* animationType,动画方式,渐隐和缩放,默认渐隐
* customBlock,可在此回调内设置样式 */
+(void)tf_show:(UIView *)inView
msg:(NSString *)msg
offset:(CGPoint)offset
dissmissDuration:(NSTimeInterval)duration
animationType:(TFAnimationType)animationType
customBlock:(TFPopupToastBlock)customBlock;
@end

147
Pods/TFPopup/TFPopup/TFPopupToast.m generated Executable file
View File

@@ -0,0 +1,147 @@
//
// TFPopupToast.m
// TFPopupDemo
//
// Created by ztf on 2019/1/14.
// Copyright © 2019 ztf. All rights reserved.
//
#import "TFPopupToast.h"
#import "UIView+TFPopup.h"
@interface TFPopupToast ()<TFPopupDelegate>
@property(nonatomic,assign)CGRect inViewFrame;
@property(nonatomic, copy)NSString *msg;
@property(nonatomic, copy)TFPopupToastBlock cusBlock;
@end
@implementation TFPopupToast
-(void)dealloc{
#if DEBUG
NSLog(@"****** TFPopupToast(已释放) msg:%@ ******",self.msg);
#endif
}
+(void)tf_show:(UIView *)inView msg:(NSString *)msg animationType:(TFAnimationType)animationType{
[TFPopupToast tf_show:inView
msg:msg
offset:CGPointZero
dissmissDuration:0
animationType:animationType
customBlock:nil];
}
+(void)tf_show:(UIView *)inView
msg:(NSString *)msg
offset:(CGPoint)offset
dissmissDuration:(NSTimeInterval)duration
animationType:(TFAnimationType)animationType
customBlock:(TFPopupToastBlock)customBlock{
if (inView == nil) {NSLog(@"****** %@ %@ ******",[self class],@"inView 不能为空!");return;}
if (msg == nil) {NSLog(@"****** %@ %@ ******",[self class],@"msg 不能为空!");return;}
TFPopupParam *param = [TFPopupParam new];
param.disuseBackground = YES;
param.offset = offset;
if (duration == 0) {
param.autoDissmissDuration = [TFPopupToast toastDuration:msg];
}else{
param.autoDissmissDuration = duration;
}
TFPopupToast *toast = [[TFPopupToast alloc]initWithFrame:CGRectZero];
toast.inViewFrame = inView.bounds;
toast.msg = msg;
toast.cusBlock = customBlock;
switch (animationType) {
case TFAnimationTypeFade:
[toast tf_showNormal:inView popupParam:param];
break;
case TFAnimationTypeScale:
[toast tf_showScale:inView offset:CGPointZero popupParam:param];
break;
default:
break;
}
}
-(instancetype)initWithFrame:(CGRect)frame{
if (self = [super initWithFrame:frame]) {
self.layer.cornerRadius = 6;
self.layer.masksToBounds = YES;
self.backgroundColor = [[UIColor blackColor]colorWithAlphaComponent:0.7];
self.userInteractionEnabled = NO;
[self addSubview:self.msgLabel];
}
return self;
}
-(void)setMsg:(NSString *)msg{
_msg = [msg copy];
self.frame = [self toastFrame];
self.msgLabel.frame = [self toastLabelFrame];
self.msgLabel.text = msg;
}
+(NSTimeInterval)toastDuration:(NSString *)msg{
NSTimeInterval dur = 0;
if ([msg isKindOfClass:[NSString class]] && msg.length > 10) {
dur = (msg.length - 10) / 10 + 1.5;
if (dur > 5) {
dur = 5;
}
}else{
dur = 1.5;
}
return dur;
}
-(CGRect)toastFrame{
CGRect frame = self.inViewFrame;
CGSize constrantSize = CGSizeMake(frame.size.width - 60, frame.size.height - 60);
NSDictionary *attr = @{NSFontAttributeName:self.msgLabel.font};
NSString *msg = [NSString stringWithFormat:@" %@ ",self.msg];
CGSize size = [msg boundingRectWithSize:constrantSize
options:NSStringDrawingUsesLineFragmentOrigin
attributes:attr
context:nil].size;
size = CGSizeMake(size.width + 30, size.height + 30);
size = CGSizeMake(size.width < 60.0?60.0:size.width, size.height < 40.0?40.0:size.height);
CGFloat x = 15 + (frame.size.width - 30 - size.width) * 0.5;
CGFloat y = 15 + (frame.size.height - 30 - size.height) * 0.5;
CGRect fr = CGRectMake(x ,y ,size.width ,size.height);
return fr;
}
-(CGRect)toastLabelFrame{
CGRect fr = CGRectMake(15, 15,self.frame.size.width - 15 * 2,self.frame.size.height - 15 * 2);
return fr;
}
-(UILabel *)msgLabel{
if (_msgLabel == nil) {
_msgLabel = [[UILabel alloc]initWithFrame:CGRectZero];
_msgLabel.textColor = [UIColor whiteColor];
_msgLabel.font = [UIFont systemFontOfSize:13];
_msgLabel.textAlignment = NSTextAlignmentCenter;
_msgLabel.backgroundColor = [UIColor clearColor];
_msgLabel.numberOfLines = 0;
_msgLabel.lineBreakMode = NSLineBreakByClipping;
_msgLabel.clipsToBounds = NO;
}
return _msgLabel;
}
@end

20
Pods/TFPopup/TFPopup/UIScrollView+TFPopup.h generated Executable file
View File

@@ -0,0 +1,20 @@
//
// UIScrollView+TFPopup.h
// TFPopupDemo
//
// Created by zhutaofeng on 2019/8/15.
// Copyright © 2019 ztf. All rights reserved.
//
#import <UIKit/UIKit.h>
#import <objc/runtime.h>
#import "TFPopupConst.h"
#import "NSObject+TFPopupMethodExchange.h"
@interface UIScrollView (TFPopup)<UIGestureRecognizerDelegate,UIScrollViewDelegate>
@property(nonatomic, weak) UIView *faterPopupView;
@end

87
Pods/TFPopup/TFPopup/UIScrollView+TFPopup.m generated Executable file
View File

@@ -0,0 +1,87 @@
//
// UIScrollView+TFPopup.m
// TFPopupDemo
//
// Created by zhutaofeng on 2019/8/15.
// Copyright © 2019 ztf. All rights reserved.
//
#import "UIScrollView+TFPopup.h"
#import "UIView+TFPopup.h"
@implementation UIScrollView (TFPopup)
@dynamic faterPopupView;
+(void)load{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// [self popExchangeShouldReceiveTouch];
// [self popExchangeGestureRecognizerShouldBegin];
// [self popExchangeShouldRecognizeSimultaneouslyWithGestureRecognizer];
});
}
//+(void)popExchangeShouldReceiveTouch{
// //scrollview
// SEL selOrigin = @selector(gestureRecognizer:shouldReceiveTouch:);
// SEL selTarget = @selector(popup_gestureRecognizer:shouldReceiveTouch:);
// [[self class] popup_instanceMethodExchange:selOrigin
// toClass:[self class] toSel:selTarget];
//
//}
////10,,NO
//-(BOOL)popup_gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{
// NSLog(@"=====1:%@:%@",self.scrollEnabled?@"是":@"否",[self class]);
// BOOL should = [self popup_gestureRecognizer:gestureRecognizer shouldReceiveTouch:touch];
// if (should) {
// self.executeShouldReceiveTouch = @(YES);
// }
// return should;
//}
+(void)popExchangeGestureRecognizerShouldBegin{
//scrollview
SEL selOrigin = @selector(gestureRecognizerShouldBegin:);
SEL selTarget = @selector(popup_gestureRecognizerShouldBegin:);
[[self class] popup_instanceMethodExchange:selOrigin
toClass:[self class] toSel:selTarget];
}
//20,1,,NO,
- (BOOL)popup_gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{
NSLog(@"=====2:%@:%@",self.scrollEnabled?@"是":@"否",[self class]);
BOOL should = [self popup_gestureRecognizerShouldBegin:gestureRecognizer];
if (self.faterPopupView) {
self.faterPopupView.extension.currentDragScrollViewAllowScroll = should;
}
return should;
}
+(void)popExchangeShouldRecognizeSimultaneouslyWithGestureRecognizer{
//scrollview
SEL selOrigin = @selector(gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:);
SEL selTarget = @selector(popup_gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:);
[[self class] popup_instanceMethodExchange:selOrigin
toClass:[self class] toSel:selTarget];
}
//30,,NO
- (BOOL)popup_gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
NSLog(@"=====3:%@:%@",self.scrollEnabled?@"是":@"否",[self class]);
if (self.faterPopupView && [self.faterPopupView isKindOfClass:[UIView class]]) {
if (self.faterPopupView.extension.currentDragScrollViewAllowScroll) {
self.faterPopupView.extension.currentDragScrollView = self;
}else{
self.faterPopupView.extension.currentDragScrollView = nil;
}
return YES;
}
return NO;
}
tf_synthesize_category_property_assign(faterPopupView, setFaterPopupView);
@end

276
Pods/TFPopup/TFPopup/UIView+TFPopup.h generated Executable file
View File

@@ -0,0 +1,276 @@
//
// UIView+TFPopup.h
// TFPopupDemo
//
// Created by ztf on 2019/1/14.
// Copyright © 2019年 ztf. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "TFPopupParam.h"
#import "TFPopupExtension.h"
//如果弹框view不设tag值,那么弹框的tag值将设为此值
#define kTFPopupDefaultTag (201912)
/* 动画数据源代理,询问动画的各种配置
* 弹框本身自动实现,若将代理设为其他类则其他类需要实现以下方法
*/
@protocol TFPopupDataSource<NSObject>
@required;
- (UIView *)tf_popupInView:(UIView *)popup;//将弹框弹到哪个view上,无默认值
- (CGSize )tf_popupInArea:(UIView *)popup;//参与计算的弹框区域的大小,默认为弹框容器的size
/* 弹框的渐隐动画设置
* popup:弹框本类
* state:有两个参数TFPopupStateShow,TFPopupStateHide分别设置弹框展示时的参数和参考消失时的参数
* animationWithAlphaForState:弹出和消失时分别是否需要渐隐动画
* fromAlphaForState:弹出和消失时起始alpha值
* toAlphaForState:弹出和消失时结束alpha值
*/
- (BOOL )tf_popupView:(UIView *)popup animationWithAlphaForState:(TFPopupState)state;//默认返回YES
- (CGFloat )tf_popupView:(UIView *)popup fromAlphaForState:(TFPopupState)state;//默认show=0,hide=1
- (CGFloat )tf_popupView:(UIView *)popup toAlphaForState:(TFPopupState)state;//默认show=1,hide=0
/* 弹框的尺寸【位移】动画设置
* popup:弹框本类
* state:有两个参数TFPopupStateShow,TFPopupStateHide分别设置弹框展示时的参数和参考消失时的参数
* animationWithAlphaForState:弹出和消失时分别是否需要尺寸【位移】动画
* fromAlphaForState:弹出和消失时起始frame值
* toAlphaForState:弹出和消失时结束frame值
*/
- (BOOL )tf_popupView:(UIView *)popup animationWithFrameForState:(TFPopupState)state;//默认返回YES
//默认show&hide大小为弹框原来尺寸,位置为弹框区域的终点位置
- (CGRect )tf_popupView:(UIView *)popup fromFrameForState:(TFPopupState)state;
- (CGRect )tf_popupView:(UIView *)popup toFrameForState:(TFPopupState)state;//同上
/* 弹出动画参数设置
* popup:弹框本类
* state:有两个参数TFPopupStateShow,TFPopupStateHide分别设置弹框展示时的参数和参考消失时的参数
* animationDurationForState:弹出和消失时分别的动画时间
* animationDelayForState:弹出和消失时分别的动画开始前延迟时间
* animationOptionsForState:弹出和消失时分别的动画曲线类型
*/
@optional;
- (NSTimeInterval)tf_popupView:(UIView *)popup animationDurationForState:(TFPopupState)state;//默认0.3
- (NSTimeInterval)tf_popupView:(UIView *)popup animationDelayForState:(TFPopupState)state;//默认0.0
//默认UIViewAnimationOptionCurveEaseOut
- (UIViewAnimationOptions)tf_popupView:(UIView *)popup animationOptionsForState:(TFPopupState)state;
//拖动子scrollView时是否同步识别并改变弹框
- (BOOL)tf_popupView:(UIView *)popup enableScrollViewGestureRecognizerWhenDrag:(UIScrollView *)scrollView;
@end
/* 弹出背景视图代理,询问背景视图的数量,view,和frame
* 弹框本身自动实现,默认为一个背景black-0.3透明度,尺寸为弹出区域尺寸,若将代理设为其他类则其他类需要实现以下方法
*/
@protocol TFPopupBackgroundDelegate<NSObject>
/* 弹出背景视图设置
* popup:弹框本类
* tf_popupBackgroundViewCount:背景视图的数量
* backgroundViewAtIndex:返回每一个背景视图
* backgroundViewFrameAtIndex:返回每一个背景视图的frame
*/
@optional
- (NSInteger)tf_popupBackgroundViewCount:(UIView *)popup;//默认1
//默认UIButton背景色为black-0.3透明度
- (UIView *)tf_popupView:(UIView *)popup backgroundViewAtIndex:(NSInteger)index;
- (CGRect)tf_popupView:(UIView *)popup backgroundViewFrameAtIndex:(NSInteger)index;//默认弹框区域大小
@end
/* 动画过程代理
* 代理包含了动画执行过程中的各个阶段,在这个阶段中你可以获取和修改参数以达到修改动画的目的
*/
@protocol TFPopupDelegate<NSObject>
@optional;
/* 监听获取参数前后
* popup:弹框本类
* tf_popupViewWillGetConfiguration:开始获取所有配置前调用
* tf_popupViewDidGetConfiguration:获取完所有配置后调用
*/
- (void)tf_popupViewWillGetConfiguration:(UIView *)popup;
- (void)tf_popupViewDidGetConfiguration:(UIView *)popup;
/* 弹框show过程
* popup:弹框本类
* tf_popupViewWillShow:开始执行动画代码前调用
* tf_popupViewDidShow:执行完动画代码后调用,此函数早于tf_popupViewShowAnimationDidFinish调用
* tf_popupViewShowAnimationDidFinish:动画执行完成时调用
*/
- (BOOL)tf_popupViewWillShow:(UIView *)popup;//默认YES
- (void)tf_popupViewDidShow:(UIView *)popup;
- (void)tf_popupViewShowAnimationDidFinish:(UIView *)popup;
/* 弹框即将执行hide代码
* popup:弹框本类
* return:返回是否继续动画,如返回NO则需要自己定义消失方式和自己调用tf_remove
*/
- (BOOL)tf_popupViewWillHide:(UIView *)popup;//默认YES
/* 弹框已经执行完hide代码
* popup:弹框本类
* return:返回如果没有任何动画的情况下,是否移除背景和弹框
*/
- (BOOL)tf_popupViewDidHide:(UIView *)popup;//默认YES
/* hide动画执行完成时调用
* popup:弹框本类
* return:返回是否移除背景和弹框,如果返回NO则需要自己调用tf_remove
*/
- (BOOL)tf_popupViewHideAnimationDidFinish:(UIView *)popup;//默认YES
/* 点击默认背景时调用
* popup:弹框本类
* return:返回点击背景后是否调用tf_hide
*/
- (BOOL)tf_popupViewBackgroundDidTouch:(UIView *)popup;//默认YES
/* 拖动非scrollview的view时调用,处理了view的拖动
* popup:弹框本类
* dragGes:拖拽手势
*/
- (void)tf_popupViewDidDrag:(UIView *)popup dragGes:(UIPanGestureRecognizer *)dragGes;
/* 拖动过程中调用,对外释放拖动距离百分比
* popup:弹框本类
* percent:拖动距离原始位置的直线百分比
* state:拖拽手势状态
*/
- (BOOL)tf_popupViewDidDragSlide:(UIView *)popup distancePercent:(CGFloat)percent distance:(CGFloat)distance state:(UIGestureRecognizerState)state;
@end
@interface UIView (TFPopup)<TFPopupDataSource,TFPopupDelegate,TFPopupBackgroundDelegate>
@property(nonatomic, weak)UIView *inView;//弹框的容器视图
@property(nonatomic, copy)NSString *identifier;//标示符用于在弹出池里查找弹出的view
@property(nonatomic,strong)TFPopupExtension *extension;
@property(nonatomic,assign)id<TFPopupDelegate>popupDelegate;//动画调用过程代理
@property(nonatomic,assign)id<TFPopupDataSource>popupDataSource;//动画所有配置代理
@property(nonatomic,assign)id<TFPopupBackgroundDelegate>backgroundDelegate;//动画背景视图设置代理
@property(nonatomic,strong)TFPopupParam *popupParam;//默认动画参数
//通过id查找弹窗如果多个弹窗id一样则返回最先弹出的弹窗
+(UIView *)tf_findPopup:(NSString *)identifier;
//获取所有已弹出的弹窗
+(NSArray <UIView *>*)tf_getAllPopup;
//手动控制弹框消失,此函数是将弹框正常动画移除,动画完成后内部调用tf_remove
-(void)tf_hide;
//手动控制弹框移除
-(void)tf_remove;
//手动控制显示默认弹框 popupParam.disuseBackground = YES 时无效
-(void)showDefaultBackground;
//手动控制移除默认弹框
-(void)hideDefaultBackground;
//监听弹框隐藏完毕回调,需要再显示弹框前调用此方法
-(void)tf_observerDelegateProcess:(TFDelegateProcessBlock)delegateProcessBlock;
/* 基本动画,位置固定,可设置无任何动画弹出和渐隐方式
* inView 容器视图
* animated YES为渐隐动画NO为无任何动画
* offset 弹框基于默认的偏移y正数为向下偏移y负数为向上偏移x值同理
* popupParam 弹出的更多参数设置具体参照TFPopupParam类 */
-(void)tf_showNormal:(UIView *)inView animated:(BOOL)animated;
-(void)tf_showNormal:(UIView *)inView offset:(CGPoint)offset animated:(BOOL)animated;
-(void)tf_showNormal:(UIView *)inView popupParam:(TFPopupParam *)popupParam;
/* 缩放动画,位置固定
* inView 容器视图
* offset 弹框基于默认的便宜y正数为向下便宜y负数为向上便宜x值同理
* popupParam 弹出的更多参数设置具体参照TFPopupParam类 */
-(void)tf_showScale:(UIView *)inView;
-(void)tf_showScale:(UIView *)inView offset:(CGPoint)offset;
-(void)tf_showScale:(UIView *)inView offset:(CGPoint)offset popupParam:(TFPopupParam *)popupParam;
/* 滑动动画,初始位置->目标位置
* inView 容器视图
* direction 弹出方向如设置此参数则弹出动画会根据popupParam.popupSize参数计算出弹出方向和位置。示例设direction=PopupDirectionToppopupParam.popupSize=CGSizeMake(300, 200)弹框会从容器视图顶部向下弹出水平居中垂直方向弹框盖于顶部并显示完全。也可以通过设置popupParam.offset设置弹框基于默认计算位置的偏移也可以设置popupParam.popupAreaRect改变默认计算区域。direction只支持上下左右四个方向弹出。
* 如不设置direction值可以设置popupParam.popOriginFrame&popupParam.popTargetFrame自由控制弹框的初始frame和最终frame
* popupParam 弹出的更多参数设置具体参照TFPopupParam类 */
-(void)tf_showSlide:(UIView *)inView direction:(PopupDirection)direction;
-(void)tf_showSlide:(UIView *)inView direction:(PopupDirection)direction popupParam:(TFPopupParam *)popupParam;
/* 基于mask,所以此弹出方式不可以同时使用mask动画
* 折叠动画,弹框最终显示位置->可选四个方向折叠展开
* inView 容器视图
* targetFrame 弹框的显示frame
* direction 折叠方向,可设置四个默认折叠方向:向下展开,向右展开,向左展开,向上展开
* popupParam 弹出的更多参数设置具体参照TFPopupParam类
*/
-(void)tf_showFold:(UIView *)inView
targetFrame:(CGRect)targetFrame
direction:(PopupDirection)direction
popupParam:(TFPopupParam *)popupParam;
/* 基于mask,所以此弹出方式不可以同时使用mask动画
* 泡泡动画基于point&bubbleDirection -> 展开弹框
* inView 容器视图
* basePoint 基础点,泡泡基于哪个位置做弹出,
* direction 弹出方向支持上右上右下下左左上八个方向可结合popupParam.offset设置弹框的偏移
* popupParam 弹出的更多参数设置具体参照TFPopupParam类 */
-(void)tf_showBubble:(UIView *)inView
basePoint:(CGPoint)basePoint
bubbleDirection:(PopupDirection)bubbleDirection
popupParam:(TFPopupParam *)popupParam;
/* 形变动画初始frame -> 目标frame
* inView 容器视图
* from 初始frame
* to 目标frame
* popupParam 弹出的更多参数设置具体参照TFPopupParam类 */
-(void)tf_showFrame:(UIView *)inView
from:(CGRect)from
to:(CGRect)to
popupParam:(TFPopupParam *)popupParam;
/* 遮罩动画位置固定由mask执行动画
* inView 容器视图
* 必须参数popupParam.maskShowFromPath,popupParam.maskShowToPath,popupParam.maskHideFromPath,popupParam.maskHideToPath四个参数控制遮罩的动画path可以最少设置popupParam.maskShowFromPath,popupParam.maskShowToPath两个参数其余两个参数可选
* popupParam 弹出的更多参数设置具体参照TFPopupParam类 */
-(void)tf_showMask:(UIView *)inView
popupParam:(TFPopupParam *)popupParam;
/* 自定义动画
* inView 容器视图
* popupParam 弹出的更多参数设置具体参照TFPopupParam类
* delegate 动画代理默认为弹框本类具体请参照TFPopupDelegate类 */
-(void)tf_showcustom:(UIView *)inView
popupParam:(TFPopupParam *)popupParam;
@end
typedef void(^AnimationStartBlock)(CAAnimation *anima);
typedef void(^AnimationStopBlock)(CAAnimation *anima,BOOL finished);
@interface CAAnimation (TFPopup)<CAAnimationDelegate>
@property(nonatomic,assign)BOOL openOberserBlock;
@property(nonatomic, copy)AnimationStartBlock startBlock;
@property(nonatomic, copy)AnimationStopBlock stopBlock;
-(void)observerAnimationDidStart:(AnimationStartBlock)start;
-(void)observerAnimationDidStop:(AnimationStopBlock)stop;
@end

1908
Pods/TFPopup/TFPopup/UIView+TFPopup.m generated Executable file

File diff suppressed because it is too large Load Diff