Created
November 28, 2016 08:52
-
-
Save evgenmikhaylov/e6287b99011f2437ac0beb5a72a897f0 to your computer and use it in GitHub Desktop.
UIApplication Obj-C category to add visibleViewControllers property
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <UIKit/UIKit.h> | |
@interface UIApplication (VisibleViewControllers) | |
@property (nonatomic, readonly) NSArray<__kindof UIViewController *> *visibleViewControllers; | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import "UIApplication+VisibleViewControllers.h" | |
#import <objc/runtime.h> | |
@interface UIApplication () | |
@property (nonatomic, readonly) NSPointerArray *visibleViewControllersPointers; | |
@end | |
@implementation UIApplication (VisibleViewControllers) | |
- (NSArray<__kindof UIViewController *> *)visibleViewControllers { | |
return self.visibleViewControllersPointers.allObjects; | |
} | |
- (NSPointerArray *)visibleViewControllersPointers { | |
NSPointerArray *pointers = objc_getAssociatedObject(self, @selector(visibleViewControllersPointers)); | |
if (!pointers) { | |
pointers = [NSPointerArray weakObjectsPointerArray]; | |
objc_setAssociatedObject(self, @selector(visibleViewControllersPointers), pointers, OBJC_ASSOCIATION_RETAIN_NONATOMIC); | |
} | |
return pointers; | |
} | |
@end | |
@implementation UIViewController (UIApplication_VisibleViewControllers) | |
+ (void)swizzleMethodWithOriginalSelector:(SEL)originalSelector swizzledSelector:(SEL)swizzledSelector { | |
Method originalMethod = class_getInstanceMethod(self, originalSelector); | |
Method swizzledMethod = class_getInstanceMethod(self, swizzledSelector); | |
BOOL didAddMethod = class_addMethod(self, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod)); | |
if (didAddMethod) { | |
class_replaceMethod(self, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod)); | |
} else { | |
method_exchangeImplementations(originalMethod, swizzledMethod); | |
} | |
} | |
+ (void)load { | |
static dispatch_once_t onceToken; | |
dispatch_once(&onceToken, ^{ | |
[self swizzleMethodWithOriginalSelector:@selector(viewDidAppear:) | |
swizzledSelector:@selector(uiapplication_visibleviewcontrollers_viewDidAppear:)]; | |
[self swizzleMethodWithOriginalSelector:@selector(viewDidDisappear:) | |
swizzledSelector:@selector(uiapplication_visibleviewcontrollers_viewDidDisappear:)]; | |
}); | |
} | |
- (void)uiapplication_visibleviewcontrollers_viewDidAppear:(BOOL)animated { | |
[[UIApplication sharedApplication].visibleViewControllersPointers addPointer:(__bridge void * _Nullable)self]; | |
[self uiapplication_visibleviewcontrollers_viewDidAppear:animated]; | |
} | |
- (void)uiapplication_visibleviewcontrollers_viewDidDisappear:(BOOL)animated { | |
NSPointerArray *pointers = [UIApplication sharedApplication].visibleViewControllersPointers; | |
for (int i = 0; i < pointers.count; i++) { | |
UIViewController *viewController = [pointers pointerAtIndex:i]; | |
if ([viewController isEqual:self]) { | |
[pointers removePointerAtIndex:i]; | |
break; | |
} | |
} | |
[self uiapplication_visibleviewcontrollers_viewDidDisappear:animated]; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment