NSObject+RQExtension.m 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. //
  2. // NSObject+RQExtension.m
  3. // RQCommon
  4. //
  5. // Created by 张嵘 on 2018/11/21.
  6. // Copyright © 2018 张嵘. All rights reserved.
  7. //
  8. #import "NSObject+RQExtension.h"
  9. #import "RQControllerHelper.h"
  10. @implementation NSObject (RQExtension)
  11. #pragma mark - Other
  12. + (NSInteger) rq_randomNumberWithFrom:(NSInteger)from to:(NSInteger)to{
  13. return (NSInteger)(from + (arc4random() % (to - from + 1)));
  14. }
  15. - (void)rq_convertNotification:(NSNotification *)notification completion:(void (^ _Nullable)(CGFloat, UIViewAnimationOptions, CGFloat))completion
  16. {
  17. // 按钮
  18. NSDictionary *userInfo = notification.userInfo;
  19. // 最终尺寸
  20. CGRect endFrame = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
  21. // 开始尺寸
  22. CGRect beginFrame = [userInfo[UIKeyboardFrameBeginUserInfoKey] CGRectValue];
  23. // 动画时间
  24. CGFloat duration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
  25. /// options
  26. UIViewAnimationOptions options = ([userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue] << 16 ) | UIViewAnimationOptionBeginFromCurrentState;
  27. /// keyboard height
  28. CGFloat keyboardH = 0;
  29. if (beginFrame.origin.y == [[UIScreen mainScreen] currentBounds].size.height){
  30. // up
  31. keyboardH = endFrame.size.height;
  32. }else if (endFrame.origin.y == [[UIScreen mainScreen] currentBounds].size.height) {
  33. // down
  34. keyboardH = 0;
  35. }else{
  36. // up
  37. keyboardH = endFrame.size.height;
  38. }
  39. /// 回调
  40. !completion?:completion(duration,options,keyboardH);
  41. }
  42. #pragma mark - Get..
  43. /// Get class
  44. - (BOOL)rq_isStringClass { return [self isKindOfClass:[NSString class]]; }
  45. - (BOOL)rq_isNumberClass { return [self isKindOfClass:[NSNumber class]]; }
  46. - (BOOL)rq_isArrayClass { return [self isKindOfClass:[NSArray class]]; }
  47. - (BOOL)rq_isDictionaryClass { return [self isKindOfClass:[NSDictionary class]]; }
  48. - (BOOL)rq_isStringOrNumberClass { return [self rq_isStringClass] || [self rq_isNumberClass]; }
  49. - (BOOL)rq_isNullOrNil { return !self || [self isKindOfClass:[NSNull class]]; }
  50. - (BOOL)rq_isExist {
  51. if (self.rq_isNullOrNil) return NO;
  52. if (self.rq_isStringClass) return (self.rq_stringValueExtension.length>0);
  53. return YES;
  54. }
  55. /// Get value
  56. - (NSString *)rq_stringValueExtension{
  57. if ([self rq_isStringClass]) return [(NSString *)self length]? (NSString *)self: @"";
  58. if ([self rq_isNumberClass]) return [NSString stringWithFormat:@"%@", self];
  59. return @"";
  60. }
  61. #pragma mark - Alert
  62. + (void)rq_showAlertViewWithTitle:(NSString *)title message:(NSString *)message confirmTitle:(NSString *)confirmTitle {
  63. [self rq_showAlertViewWithTitle:title message:message confirmTitle:confirmTitle confirmAction:NULL];
  64. }
  65. + (void)rq_showAlertViewWithTitle:(NSString *)title message:(NSString *)message confirmTitle:(NSString *)confirmTitle confirmAction:(void(^)(void))confirmAction {
  66. [self rq_showAlertViewWithTitle:title message:message confirmTitle:confirmTitle cancelTitle:nil confirmAction:confirmAction cancelAction:NULL];
  67. }
  68. + (void)rq_showAlertViewWithTitle:(NSString *)title message:(NSString *)message confirmTitle:(NSString *)confirmTitle cancelTitle:(NSString *)cancelTitle confirmAction:(void(^)(void))confirmAction cancelAction:(void(^)(void))cancelAction {
  69. QMUIAlertController *alertController = [QMUIAlertController alertControllerWithTitle:title message:message preferredStyle:QMUIAlertControllerStyleAlert];
  70. alertController.alertTitleMessageSpacing = 16.f;
  71. alertController.alertTitleAttributes = @{NSForegroundColorAttributeName:RQ_MAIN_TEXT_COLOR_1,NSFontAttributeName:UIFontBoldMake(17),NSParagraphStyleAttributeName:[NSMutableParagraphStyle qmui_paragraphStyleWithLineHeight:0 lineBreakMode:NSLineBreakByTruncatingTail textAlignment:NSTextAlignmentCenter]};
  72. alertController.alertMessageAttributes = @{NSForegroundColorAttributeName:RQ_MAIN_TEXT_COLOR_3,NSFontAttributeName:UIFontMake(13),NSParagraphStyleAttributeName:[NSMutableParagraphStyle qmui_paragraphStyleWithLineHeight:0 lineBreakMode:NSLineBreakByTruncatingTail textAlignment:NSTextAlignmentCenter]};
  73. alertController.alertButtonAttributes = @{NSForegroundColorAttributeName:RQ_MAIN_COLOR,NSFontAttributeName:UIFontMake(17),NSKernAttributeName:@(0)};
  74. alertController.alertCancelButtonAttributes = @{NSForegroundColorAttributeName:RQ_MAIN_TEXT_COLOR_RED,NSFontAttributeName:UIFontMake(17),NSKernAttributeName:@(0)};
  75. if (confirmTitle.length>0) {
  76. QMUIAlertAction *confirm = [QMUIAlertAction actionWithTitle:confirmTitle?confirmTitle:@"确定" style:QMUIAlertActionStyleDefault handler:^(__kindof QMUIAlertController * _Nonnull aAlertController, QMUIAlertAction * _Nonnull action) {
  77. !confirmAction?:confirmAction();
  78. }];
  79. [alertController addAction:confirm];
  80. }
  81. /// 左边按钮
  82. if(cancelTitle.length>0){
  83. QMUIAlertAction *cancel = [QMUIAlertAction actionWithTitle:cancelTitle?cancelTitle:@"取消" style:QMUIAlertActionStyleCancel handler:^(__kindof QMUIAlertController * _Nonnull aAlertController, QMUIAlertAction * _Nonnull action) {
  84. !cancelAction?:cancelAction();
  85. }];
  86. [alertController addAction:cancel];
  87. }
  88. dispatch_async(dispatch_get_main_queue(), ^{
  89. [alertController showWithAnimated:YES];
  90. });
  91. }
  92. #pragma mark - Safe
  93. + (void)methodSwizzlingWithOriginalSelector:(SEL)originalSelector bySwizzledSelector:(SEL)swizzledSelector{
  94. Class class = [self class];
  95. //原有方法
  96. Method originalMethod = class_getInstanceMethod(class, originalSelector);
  97. //替换原有方法的新方法
  98. Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
  99. //先尝试給源SEL添加IMP,这里是为了避免源SEL没有实现IMP的情况
  100. BOOL didAddMethod = class_addMethod(class,originalSelector,
  101. method_getImplementation(swizzledMethod),
  102. method_getTypeEncoding(swizzledMethod));
  103. if (didAddMethod) {//添加成功:说明源SEL没有实现IMP,将源SEL的IMP替换到交换SEL的IMP
  104. class_replaceMethod(class,swizzledSelector,
  105. method_getImplementation(originalMethod),
  106. method_getTypeEncoding(originalMethod));
  107. } else {//添加失败:说明源SEL已经有IMP,直接将两个SEL的IMP交换即可
  108. method_exchangeImplementations(originalMethod, swizzledMethod);
  109. }
  110. }
  111. @end