NSObject+RQExtension.m 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  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] bounds].size.height){
  30. // up
  31. keyboardH = endFrame.size.height;
  32. }else if (endFrame.origin.y == [[UIScreen mainScreen] bounds].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. /// 左边按钮
  71. if(cancelTitle.length>0) {
  72. // UIAlertAction *cancel= [UIAlertAction actionWithTitle:cancelTitle?cancelTitle:@"取消" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { !cancelAction?:cancelAction(); }];
  73. QMUIAlertAction *cancel = [QMUIAlertAction actionWithTitle:RQStringIsNotEmpty(cancelTitle)? cancelTitle : @"取消" style:QMUIAlertActionStyleDefault handler:^(__kindof QMUIAlertController * _Nonnull aAlertController, QMUIAlertAction * _Nonnull action) {
  74. !cancelAction?:cancelAction();
  75. }];
  76. [alertController addAction:cancel];
  77. }
  78. if (confirmTitle.length>0) {
  79. // UIAlertAction *confirm = [UIAlertAction actionWithTitle:confirmTitle?confirmTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { !confirmAction?:confirmAction();}];
  80. QMUIAlertAction *confirm = [QMUIAlertAction actionWithTitle:RQStringIsNotEmpty(confirmTitle)? confirmTitle : @"确定" style:QMUIAlertActionStyleDefault handler:^(__kindof QMUIAlertController * _Nonnull aAlertController, QMUIAlertAction * _Nonnull action) {
  81. !confirmAction?:confirmAction();
  82. }];
  83. [alertController addAction:confirm];
  84. }
  85. dispatch_async(dispatch_get_main_queue(), ^{
  86. // [[RQControllerHelper currentViewController] presentViewController:alertController animated:YES completion:NULL];
  87. [alertController showWithAnimated:YES];
  88. });
  89. }
  90. #pragma mark - Safe
  91. + (void)methodSwizzlingWithOriginalSelector:(SEL)originalSelector bySwizzledSelector:(SEL)swizzledSelector{
  92. Class class = [self class];
  93. //原有方法
  94. Method originalMethod = class_getInstanceMethod(class, originalSelector);
  95. //替换原有方法的新方法
  96. Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
  97. //先尝试給源SEL添加IMP,这里是为了避免源SEL没有实现IMP的情况
  98. BOOL didAddMethod = class_addMethod(class,originalSelector,
  99. method_getImplementation(swizzledMethod),
  100. method_getTypeEncoding(swizzledMethod));
  101. if (didAddMethod) {//添加成功:说明源SEL没有实现IMP,将源SEL的IMP替换到交换SEL的IMP
  102. class_replaceMethod(class,swizzledSelector,
  103. method_getImplementation(originalMethod),
  104. method_getTypeEncoding(originalMethod));
  105. } else {//添加失败:说明源SEL已经有IMP,直接将两个SEL的IMP交换即可
  106. method_exchangeImplementations(originalMethod, swizzledMethod);
  107. }
  108. }
  109. @end