Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 27 additions & 3 deletions CTAppearance/CTAppearance+UIKit.m
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ static void _CTAppearanceReplaceClassSelector(Class klass, SEL srcSelector, SEL
method_exchangeImplementations(dstMethod, srcMethod);
}

static void _CTAppearanceReplaceInstanceSelector(Class klass, SEL srcSelector, SEL dstSelector) {
__unused static void _CTAppearanceReplaceInstanceSelector(Class klass, SEL srcSelector, SEL dstSelector) {
Method srcMethod = class_getInstanceMethod(klass, srcSelector);
Method dstMethod = class_getInstanceMethod(klass, dstSelector);
method_exchangeImplementations(dstMethod, srcMethod);
Expand Down Expand Up @@ -65,6 +65,7 @@ - (void)applyAppearanceForSuperview:(UIView*)superview {

// Always apply the hierarchy appearances when moving superviews
[CTAppearance applyContainedInTo: self forSuperview: superview];
[self setAppliedAppearanceWindow:superview.window];
}

- (void)willMoveToSuperview:(UIView *)newSuperview {
Expand All @@ -82,8 +83,19 @@ - (void)didMoveToSuperview {
}
}

- (void)didMoveToWindow {
if (![CTAppearance isEnabled]) { return; }

// If we moved to a new window, we need to re-check the hierarchy. Common need for UITableView subviews.
UIWindow *window = self.window;
if (window && window != [self appliedAppearanceWindow]) {
[CTAppearance applyContainedInTo: self forSuperview: self.superview];
}
[self setAppliedAppearanceWindow:window];
}

#pragma mark -
#pragma mark Associatd Objects
#pragma mark Associated Objects
#pragma mark -
- (void)setHasAppliedAppearance:(BOOL)hasApplied {
objc_setAssociatedObject(self, &_property_hasAppliedKey, [NSNumber numberWithBool:hasApplied], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
Expand All @@ -92,4 +104,16 @@ - (void)setHasAppliedAppearance:(BOOL)hasApplied {
- (BOOL)hasAppliedAppearance {
return [objc_getAssociatedObject(self, &_property_hasAppliedKey) boolValue];
}
@end

static char * APPLIED_WINDOW = "_property_appliedAppearWindow";

- (void)setAppliedAppearanceWindow:(UIWindow *)window {
objc_setAssociatedObject(self, APPLIED_WINDOW, window, OBJC_ASSOCIATION_ASSIGN);
}

- (id)appliedAppearanceWindow {
return objc_getAssociatedObject(self, APPLIED_WINDOW);
}

@end

24 changes: 24 additions & 0 deletions CTAppearance/CTAppearance.m
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,16 @@ + (void)applyContainedInTo:(id)arg1 forSuperview:(id)superview {

if (superviews == nil) {
superviews = [NSMutableArray array];

[self collateViewControllersOfView:arg1 intoArray:superviews];
[self collateSuperviews: superview intoArray:superviews];

// NOTE: If the view is inside of a UIPopoverController, that should be added here at the
// end of the array, as it is also a UIAppearanceContainer. There does not seem to be any
// public API to determine that. If you are in a position to use private API, you could
// iterate through the superviews array here, and if any UIViewController instance has a
// popover set in its _popoverController instance variable, add it. If there is a local
// way to determine a current popover, use that.
}

for (CTAppearance *a in parents) {
Expand All @@ -121,6 +130,7 @@ + (void)applyContainedInTo:(id)arg1 forSuperview:(id)superview {
for (UIView *sv in superviews) {
if ([sv isKindOfClass: c] || [sv isMemberOfClass:c]) {
found = YES;
break;
}
}

Expand All @@ -137,9 +147,23 @@ + (void)applyContainedInTo:(id)arg1 forSuperview:(id)superview {
}
}

+ (void)collateViewControllersOfView:(UIView*)view intoArray:(NSMutableArray *)svs
{
id responder = [view nextResponder];
if ([responder isKindOfClass:[UIViewController class]]) {
UIViewController *controller = responder;
while (controller) {
[svs addObject:controller];
controller = controller.parentViewController;
}

}
}

+ (void)collateSuperviews:(UIView*)superview intoArray:(NSMutableArray*)svs {
if (superview) {
[svs addObject: superview];
[self collateViewControllersOfView:superview intoArray:svs];
[self collateSuperviews:superview.superview intoArray:svs];
}
}
Expand Down