YMAlert.m 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  1. //
  2. // YMAlert.m
  3. // yuemoClient
  4. //
  5. // Created by YoMi on 2023/11/6.
  6. //
  7. #import "YMAlert.h"
  8. @interface YMPopupConfig : NSObject
  9. #pragma mark - 基础属性
  10. /// 代理 支持多代理
  11. @property (nonatomic , strong) NSHashTable * delegate;
  12. /// 标识 默认为空
  13. @property (nonatomic , strong) NSString * identifier;
  14. /// 弹窗容器
  15. @property (nonatomic , weak ) UIView * parentView;
  16. /// 自定义view
  17. @property (nonatomic , weak ) UIView * currCustomView;
  18. /// 弹窗位置 默认YMPositionStyleCenter
  19. @property (nonatomic , assign) YMPositionStyle positionStyle;
  20. /// 显示时动画弹窗样式 默认YMPopupStyleFade
  21. @property (nonatomic , assign) YMPopupStyle popStyle;
  22. /// 移除时动画弹窗样式 默认YMDismissStyleFade
  23. @property (nonatomic , assign) YMDismissStyle dismissStyle;
  24. /// 显示时动画时长,> 0。不设置则使用默认的动画时长 设置成YMPopupStyleNO, 该属性无效
  25. @property (nonatomic , assign) NSTimeInterval popDuration;
  26. /// 隐藏时动画时长,>0。不设置则使用默认的动画时长 设置成YMDismissStyleNO, 该属性无效
  27. @property (nonatomic , assign) NSTimeInterval dismissDuration;
  28. /// 弹窗水平方向(X)偏移量校准 默认0
  29. @property (nonatomic , assign) CGFloat adjustX;
  30. /// 弹窗垂直方向(Y)偏移量校准 默认0
  31. @property (nonatomic , assign) CGFloat adjustY;
  32. /// 背景颜色 默认rgb(0,0,0) 透明度0.3
  33. @property (nonatomic , strong) UIColor * bgColor;
  34. /// 显示时背景的透明度,取值(0.0~1.0),默认为0.3
  35. @property (nonatomic , assign) CGFloat bgAlpha;
  36. /// 是否隐藏背景 默认NO
  37. @property (nonatomic , assign) BOOL isHideBg;
  38. /// 显示时点击背景是否移除弹窗,默认为NO。
  39. @property (nonatomic , assign) BOOL isClickBgDismiss;
  40. /// 是否监听屏幕旋转,默认为YES
  41. @property (nonatomic , assign) BOOL isObserverScreenRotation;
  42. /// 是否支持点击回馈 默认NO (暂时关闭)
  43. @property (nonatomic , assign) BOOL isClickFeedback;
  44. /// 是否规避键盘 默认YES
  45. @property (nonatomic , assign) BOOL isAvoidKeyboard;
  46. /// 弹窗和键盘的距离 默认10
  47. @property (nonatomic , assign) CGFloat avoidKeyboardSpace;
  48. /// 显示多长时间 默认0 不会消失
  49. @property (nonatomic , assign) NSTimeInterval showTime;
  50. /// 自定view圆角方向设置 默认UIRectCornerAllCorners 当cornerRadius>0时生效
  51. @property (nonatomic , assign) UIRectCorner rectCorners;
  52. /// 自定义view圆角大小, 默认 0
  53. @property (nonatomic , assign) CGFloat cornerRadius;
  54. /// 弹出震动反馈 默认NO iOS10+ 系统才有此效果
  55. @property (nonatomic , assign) BOOL isImpactFeedback;
  56. #pragma mark - 群组相关属性
  57. /// 群组标识 统一给弹窗编队 方便独立管理 默认为nil,统一全局处理
  58. @property (nonatomic , strong) NSString * groupId;
  59. /// 是否堆叠 默认NO 如果是YES priority优先级不生效
  60. @property (nonatomic , assign) BOOL isStack;
  61. /// 单显示 默认NO 只会显示优先级最高的popView
  62. @property (nonatomic , assign) BOOL isSingle;
  63. /// 优先级 范围0~1000 (默认0,遵循先进先出) isStack和isSingle为NO的时候生效
  64. @property (nonatomic , assign) CGFloat priority;
  65. #pragma mark - 拖拽手势相关属性
  66. /// 拖拽方向 默认 不可拖拽
  67. @property (nonatomic , assign) YMDragStyle dragStyle;
  68. /// X轴或者Y轴拖拽移除临界距离 范围(0 ~ +∞) 默认0 不拖拽移除 基使用于dragStyle
  69. @property (nonatomic , assign) CGFloat dragDistance;
  70. /// 拖拽移除动画类型 默认同dismissStyle
  71. @property (nonatomic , assign) YMDismissStyle dragDismissStyle;
  72. /// 拖拽消失动画时间 默认同 dismissDuration
  73. @property (nonatomic , assign) NSTimeInterval dragDismissDuration;
  74. /// 拖拽复原动画时间 默认0.25s
  75. @property (nonatomic , assign) NSTimeInterval dragReboundTime;
  76. /// 轻扫方向 默认 不可轻扫 前提开启dragStyle
  77. @property (nonatomic , assign) YMSweepStyle sweepStyle;
  78. /// 轻扫速率 控制轻扫移除 默认1000 基于使用sweepStyle
  79. @property (nonatomic , assign) CGFloat swipeVelocity;
  80. /// 轻扫移除的动画 默认YMSweepDismissStyleVelocity
  81. @property (nonatomic , assign) YMSweepDismissStyle sweepDismissStyle;
  82. #pragma mark - 交互回调
  83. /// 点击背景
  84. @property (nonatomic , copy ) YmVoidBlock bgClickBlock;
  85. /// 长按背景
  86. @property (nonatomic , copy ) YmVoidBlock bgLongPressBlock;
  87. /// 弹窗pan手势偏移量
  88. @property (nonatomic , copy ) YmPointBlock panOffsetBlock;
  89. #pragma mark - 以下键盘弹出/收起 第三方键盘会多次回调(百度,搜狗测试得出), 原生键盘回调一次
  90. /// 键盘将要弹出
  91. @property (nonatomic , copy ) YmVoidBlock keyboardWillShowBlock;
  92. /// 键盘弹出完毕
  93. @property (nonatomic , copy ) YmVoidBlock keyboardDidShowBlock;
  94. /// 键盘frame将要改变
  95. @property (nonatomic , copy ) YmKeyBoardChangeBlock keyboardFrameWillChangeBlock;
  96. /// 键盘frame改变完毕
  97. @property (nonatomic , copy ) YmKeyBoardChangeBlock keyboardFrameDidChangeBlock;
  98. /// 键盘将要收起
  99. @property (nonatomic , copy ) YmVoidBlock keyboardWillHideBlock;
  100. /// 键盘收起完毕
  101. @property (nonatomic , copy ) YmVoidBlock keyboardDidHideBlock;
  102. #pragma mark - 生命周期回调(Block)
  103. /// 将要显示 回调
  104. @property (nonatomic , copy ) YmVoidBlock popViewWillPopBlock;
  105. /// 已经显示完毕 回调
  106. @property (nonatomic , copy ) YmVoidBlock popViewDidPopBlock;
  107. /// 将要开始移除 回调
  108. @property (nonatomic , copy ) YmVoidBlock popViewWillDismissBlock;
  109. /// 已经移除完毕 回调
  110. @property (nonatomic , strong) NSHashTable * popViewDidDismissBlocks;
  111. /// 倒计时 回调
  112. @property (nonatomic , copy ) YmAlertCountDownBlock popViewCountDownBlock;
  113. @end
  114. @implementation YMPopupConfig
  115. - (instancetype)init
  116. {
  117. self = [super init];
  118. if (self) {
  119. [self initDefaultData];
  120. }
  121. return self;
  122. }
  123. - (void)initDefaultData
  124. {
  125. _positionStyle = YMPositionStyleCenter;
  126. _popStyle = YMPopupStyleFade;
  127. _dismissStyle = YMDismissStyleFade;
  128. _bgColor = UIColor.blackColor;
  129. _bgAlpha = 0.3;
  130. _isObserverScreenRotation = YES;
  131. _isAvoidKeyboard = YES;
  132. _avoidKeyboardSpace = 10;
  133. }
  134. - (NSHashTable *)delegate
  135. {
  136. if (_delegate) return _delegate;
  137. _delegate = [NSHashTable hashTableWithOptions:(NSPointerFunctionsWeakMemory)];
  138. return _delegate;
  139. }
  140. - (NSHashTable *)popViewDidDismissBlocks
  141. {
  142. if (_popViewDidDismissBlocks) return _popViewDidDismissBlocks;
  143. _popViewDidDismissBlocks = [NSHashTable hashTableWithOptions:(NSPointerFunctionsWeakMemory)];
  144. return _popViewDidDismissBlocks;
  145. }
  146. @end
  147. #pragma mark - YMAlert
  148. @interface YMAlert ()
  149. @property (nonatomic , weak ) YMPopupView * popView;
  150. @property (nonatomic , strong) YMPopupConfig * config;
  151. @end
  152. @implementation YMAlert
  153. + (instancetype)alert
  154. {
  155. YMAlert *alert = YMAlert.alloc.init;
  156. return alert;
  157. }
  158. - (YMPopupConfig *)config
  159. {
  160. if (_config) return _config;
  161. _config = YMPopupConfig.alloc.init;
  162. return _config;
  163. }
  164. #define ym_property_block(class, subclass, proprety) \
  165. - (class)proprety\
  166. {\
  167. return ^(subclass object) {\
  168. self.config.proprety = object;\
  169. return self;\
  170. };\
  171. }
  172. - (YMAlertDelegate)delegate
  173. {
  174. return ^(id<YMPopupViewProtocol> object) {
  175. if (object) {
  176. [self.config.delegate addObject:object];
  177. }
  178. return self;
  179. };
  180. }
  181. ym_property_block(YMAlertString, id, identifier);
  182. ym_property_block(YMAlertView, id, parentView);
  183. - (YMAlertCustomView)currCustomView{
  184. return ^(YmViewBlock object){
  185. self.config.currCustomView = object();
  186. return self;
  187. };
  188. }
  189. ym_property_block(YMAlertPositionStyle, YMPositionStyle, positionStyle);
  190. ym_property_block(YMAlertPopStyle, YMPopupStyle, popStyle);
  191. ym_property_block(YMAlertDismissStyle, YMDismissStyle, dismissStyle);
  192. ym_property_block(YMAlertInterval, NSTimeInterval, popDuration);
  193. ym_property_block(YMAlertInterval, NSTimeInterval, dismissDuration);
  194. ym_property_block(YMAlertFloat, CGFloat, adjustX);
  195. ym_property_block(YMAlertFloat, CGFloat, adjustY);
  196. ym_property_block(YMAlertColor, id, bgColor);
  197. ym_property_block(YMAlertFloat, CGFloat, bgAlpha);
  198. ym_property_block(YMAlertBOOL, BOOL, isHideBg);
  199. ym_property_block(YMAlertBOOL, BOOL,isClickBgDismiss);
  200. ym_property_block(YMAlertBOOL, BOOL, isObserverScreenRotation);
  201. ym_property_block(YMAlertBOOL, BOOL, isClickFeedback);
  202. ym_property_block(YMAlertBOOL, BOOL, isAvoidKeyboard);
  203. ym_property_block(YMAlertFloat, CGFloat, avoidKeyboardSpace);
  204. ym_property_block(YMAlertInterval, NSTimeInterval, showTime);
  205. ym_property_block(YMAlertCorner, UIRectCorner, rectCorners);
  206. ym_property_block(YMAlertFloat, CGFloat, cornerRadius);
  207. ym_property_block(YMAlertBOOL, BOOL, isImpactFeedback);
  208. ym_property_block(YMAlertString, id, groupId);
  209. ym_property_block(YMAlertBOOL, BOOL, isStack);
  210. ym_property_block(YMAlertBOOL, BOOL, isSingle);
  211. ym_property_block(YMAlertFloat, CGFloat, priority);
  212. ym_property_block(YMAlertDragStyle, YMDragStyle, dragStyle);
  213. ym_property_block(YMAlertFloat, CGFloat, dragDistance);
  214. ym_property_block(YMAlertDismissStyle, YMDismissStyle, dragDismissStyle);
  215. ym_property_block(YMAlertInterval, NSTimeInterval, dragDismissDuration);
  216. ym_property_block(YMAlertSweepStyle, YMSweepStyle, sweepStyle);
  217. ym_property_block(YMAlertFloat, CGFloat, swipeVelocity);
  218. ym_property_block(YMAlertSweepDismissStyle, YMSweepDismissStyle, sweepDismissStyle);
  219. ym_property_block(YMAlertBlock, YmVoidBlock, bgClickBlock);
  220. ym_property_block(YMAlertBlock, YmVoidBlock, bgLongPressBlock);
  221. ym_property_block(YMAlertPointBlock, YmPointBlock, panOffsetBlock);
  222. ym_property_block(YMAlertBlock, YmVoidBlock, keyboardWillShowBlock);
  223. ym_property_block(YMAlertBlock, YmVoidBlock, keyboardDidShowBlock);
  224. ym_property_block(YMAlertKeyBoardChangeBlock, YmKeyBoardChangeBlock, keyboardFrameWillChangeBlock);
  225. ym_property_block(YMAlertKeyBoardChangeBlock, YmKeyBoardChangeBlock, keyboardFrameDidChangeBlock);
  226. ym_property_block(YMAlertBlock, YmVoidBlock, keyboardWillHideBlock);
  227. ym_property_block(YMAlertBlock, YmVoidBlock, keyboardDidHideBlock);
  228. ym_property_block(YMAlertBlock, YmVoidBlock, popViewWillPopBlock);
  229. ym_property_block(YMAlertBlock, YmVoidBlock, popViewDidPopBlock);
  230. ym_property_block(YMAlertBlock, YmVoidBlock, popViewWillDismissBlock);
  231. - (YMAlertBlock)popViewDidDismissBlock
  232. {
  233. return ^(YmVoidBlock object) {
  234. if (object) {
  235. [self.config.popViewDidDismissBlocks addObject:object];
  236. }
  237. return self;
  238. };
  239. }
  240. ym_property_block(YMAlertAlertCountDownBlock, YmAlertCountDownBlock, popViewCountDownBlock);
  241. - (YMAlertVoid)pop
  242. {
  243. return ^ {
  244. [self show];
  245. return self;
  246. };
  247. }
  248. - (YMAlertVoid)dismiss
  249. {
  250. return ^ {
  251. [self hide];
  252. return self;
  253. };
  254. }
  255. - (void)hide
  256. {
  257. [_popView dismiss];
  258. }
  259. - (void)show
  260. {
  261. YMPopupView * popView = ({
  262. YMPopupConfig *config = self.config;
  263. YMPopupView * object = [YMPopupView initWithCustomView:config.currCustomView parentView:config.parentView popStyle:config.popStyle dismissStyle:config.dismissStyle];
  264. for (id<YMPopupViewProtocol> de in config.delegate) {
  265. object.delegate = de;
  266. }
  267. object.identifier = config.identifier;
  268. object.positionStyle = config.positionStyle;
  269. object.popStyle = config.popStyle;
  270. object.dismissStyle = config.dismissStyle;
  271. object.popDuration = config.popDuration;
  272. object.dismissDuration = config.dismissDuration;
  273. object.adjustX = config.adjustX;
  274. object.adjustY = config.adjustY;
  275. object.bgColor = config.bgColor;
  276. object.bgAlpha = config.bgAlpha;
  277. object.isHideBg = config.isHideBg;
  278. object.isClickBgDismiss = config.isClickBgDismiss;
  279. object.isObserverScreenRotation = config.isObserverScreenRotation;
  280. object.isClickFeedback = config.isClickFeedback;
  281. object.isAvoidKeyboard = config.isAvoidKeyboard;
  282. object.avoidKeyboardSpace = config.avoidKeyboardSpace;
  283. object.showTime = config.showTime;
  284. object.rectCorners = config.rectCorners;
  285. object.cornerRadius = config.cornerRadius;
  286. object.isImpactFeedback = config.isImpactFeedback;
  287. object.groupId = config.groupId;
  288. object.isStack = config.isStack;
  289. object.isSingle = config.isSingle;
  290. object.priority = config.priority;
  291. object.dragStyle = config.dragStyle;
  292. object.dragDistance = config.dragDistance;
  293. object.dragDismissStyle = config.dragDismissStyle;
  294. object.dragDismissDuration = config.dragDismissDuration;
  295. object.dragReboundTime = config.dragReboundTime;
  296. object.sweepStyle = config.sweepStyle;
  297. object.swipeVelocity = config.swipeVelocity;
  298. object.sweepDismissStyle = config.sweepDismissStyle;
  299. object.bgClickBlock = config.bgClickBlock;
  300. object.bgLongPressBlock = config.bgLongPressBlock;
  301. object.panOffsetBlock = config.panOffsetBlock;
  302. object.keyboardWillShowBlock = config.keyboardWillShowBlock;
  303. object.keyboardDidShowBlock = config.keyboardDidShowBlock;
  304. object.keyboardFrameWillChangeBlock = config.keyboardFrameWillChangeBlock;
  305. object.keyboardFrameDidChangeBlock = config.keyboardFrameDidChangeBlock;
  306. object.keyboardWillHideBlock = config.keyboardWillHideBlock;
  307. object.keyboardDidHideBlock = config.keyboardDidHideBlock;
  308. object.popViewWillPopBlock = config.popViewWillPopBlock;
  309. object.popViewDidPopBlock = config.popViewDidPopBlock;
  310. object.popViewWillDismissBlock = config.popViewWillDismissBlock;
  311. for (YmVoidBlock block in config.popViewDidDismissBlocks) {
  312. if (block) {
  313. object.popViewDidDismissBlock = block;
  314. }
  315. }
  316. object.popViewCountDownBlock = config.popViewCountDownBlock;
  317. object;
  318. });
  319. _popView = popView;
  320. [popView pop];
  321. }
  322. + (NSArray <YMPopupView *>*)getAllPopView
  323. {
  324. return YMPopupView.getAllPopView;
  325. }
  326. + (NSArray <YMPopupView *>*)getAllPopViewForParentView:(UIView *)parentView
  327. {
  328. return [YMPopupView getAllPopViewForParentView:parentView];
  329. }
  330. + (NSArray <YMPopupView *>*)getAllPopViewForPopView:(UIView *)popView
  331. {
  332. return [YMPopupView getAllPopViewForPopView:popView];
  333. }
  334. + (YMPopupView *)getPopViewForKey:(NSString *)key
  335. {
  336. return [YMPopupView getPopViewForKey:key];
  337. }
  338. + (void)dismissAllAlert:(YmVoidBlock)complete
  339. {
  340. [YMPopupView removeAllPopViewComplete:complete];
  341. }
  342. + (void)dismissAlertComplete:(YmVoidBlock)complete
  343. {
  344. [YMPopupView removeLastPopViewComplete:complete];
  345. }
  346. + (void)dismissAlertForAlert:(YMAlert *)alert complete:(YmVoidBlock)complete
  347. {
  348. [YMPopupView removePopView:alert.popView complete:complete];
  349. }
  350. + (void)dismissAlertForKey:(NSString *)key complete:(YmVoidBlock)complete
  351. {
  352. [YMPopupView removePopViewForKey:key complete:complete];
  353. }
  354. + (void)dismissAlertForPopView:(YMPopupView *)popView complete:(YmVoidBlock)complete
  355. {
  356. [YMPopupView removePopView:popView complete:complete];
  357. }
  358. @end