YMCaptchaCountdownButton.m 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. //
  2. // YMCaptchaCountdownButton.m
  3. // yuemoClient
  4. //
  5. // Created by YoMi on 2023/11/15.
  6. //
  7. #import "YMCaptchaCountdownButton.h"
  8. @interface NSTimer (YMCaptchaCountdownBlocksSupport)
  9. + (NSTimer *)ym_scheduledTimerWithTimeInterval:(NSTimeInterval)interval
  10. block:(void(^)(void))block
  11. repeats:(BOOL)repeats;
  12. @end
  13. @implementation NSTimer (YMCaptchaCountdownBlocksSupport)
  14. + (NSTimer *)ym_scheduledTimerWithTimeInterval:(NSTimeInterval)interval
  15. block:(void(^)(void))block
  16. repeats:(BOOL)repeats
  17. {
  18. return [self scheduledTimerWithTimeInterval:interval
  19. target:self
  20. selector:@selector(ym_blockInvoke:)
  21. userInfo:[block copy]
  22. repeats:repeats];
  23. }
  24. + (void)ym_blockInvoke:(NSTimer *)timer {
  25. void (^block)(void) = timer.userInfo;
  26. if(block) {
  27. block();
  28. }
  29. }
  30. @end
  31. @interface YMCaptchaCountdownButton(){
  32. NSInteger _second;
  33. NSUInteger _totalSecond;
  34. NSTimer *_timer;
  35. NSDate *_startDate;
  36. CountDownChanging _countDownChanging;
  37. CountDownFinished _countDownFinished;
  38. TouchedCountDownButtonHandler _touchedCountDownButtonHandler;
  39. }
  40. @end
  41. @implementation YMCaptchaCountdownButton
  42. #pragma -mark touche action
  43. - (void)countDownButtonHandler:(TouchedCountDownButtonHandler)touchedCountDownButtonHandler{
  44. _touchedCountDownButtonHandler = [touchedCountDownButtonHandler copy];
  45. [self addTarget:self action:@selector(touched:) forControlEvents:UIControlEventTouchUpInside];
  46. }
  47. - (void)touched:(YMCaptchaCountdownButton*)sender{
  48. if (_touchedCountDownButtonHandler) {
  49. dispatch_async(dispatch_get_main_queue(), ^{
  50. _touchedCountDownButtonHandler(sender,sender.tag);
  51. });
  52. }
  53. }
  54. #pragma -mark count down method
  55. - (void)startCountDownWithSecond:(NSUInteger)totalSecond
  56. {
  57. _totalSecond = totalSecond;
  58. _second = totalSecond;
  59. __weak typeof(self) weakSelf = self;
  60. _timer = [NSTimer ym_scheduledTimerWithTimeInterval:1.0 block:^{
  61. typeof(weakSelf) strongSelf = weakSelf;
  62. [strongSelf timerStart];
  63. } repeats:YES];
  64. _startDate = [NSDate date];
  65. _timer.fireDate = [NSDate distantPast];
  66. [[NSRunLoop currentRunLoop]addTimer:_timer forMode:NSRunLoopCommonModes];
  67. }
  68. - (void)timerStart {
  69. double deltaTime = [[NSDate date] timeIntervalSinceDate:_startDate];
  70. _second = _totalSecond - (NSInteger)(deltaTime+0.5) ;
  71. if (_second< 0.0)
  72. {
  73. [self stopCountDown];
  74. }
  75. else
  76. {
  77. if (_countDownChanging)
  78. {
  79. dispatch_async(dispatch_get_main_queue(), ^{
  80. NSString *title = _countDownChanging(self,_second);
  81. [self setTitle:title forState:UIControlStateNormal];
  82. [self setTitle:title forState:UIControlStateDisabled];
  83. });
  84. }
  85. else
  86. {
  87. NSString *title = [NSString stringWithFormat:@"%zd秒",_second];
  88. [self setTitle:title forState:UIControlStateNormal];
  89. [self setTitle:title forState:UIControlStateDisabled];
  90. }
  91. }
  92. }
  93. - (void)stopCountDown{
  94. if (_timer) {
  95. if ([_timer respondsToSelector:@selector(isValid)])
  96. {
  97. if ([_timer isValid])
  98. {
  99. [_timer invalidate];
  100. _second = _totalSecond;
  101. if (_countDownFinished)
  102. {
  103. dispatch_async(dispatch_get_main_queue(), ^{
  104. NSString *title = _countDownFinished(self,_totalSecond);
  105. [self setTitle:title forState:UIControlStateNormal];
  106. [self setTitle:title forState:UIControlStateDisabled];
  107. });
  108. }
  109. else
  110. {
  111. [self setTitle:@"重新获取" forState:UIControlStateNormal];
  112. [self setTitle:@"重新获取" forState:UIControlStateDisabled];
  113. }
  114. }
  115. }
  116. }
  117. }
  118. #pragma -mark block
  119. - (void)countDownChanging:(CountDownChanging)countDownChanging{
  120. _countDownChanging = [countDownChanging copy];
  121. }
  122. - (void)countDownFinished:(CountDownFinished)countDownFinished{
  123. _countDownFinished = [countDownFinished copy];
  124. }
  125. @end