Created
September 12, 2019 05:23
-
-
Save maxchuquimia/e1c31daebc9a6ee2e343b2231fb40f40 to your computer and use it in GitHub Desktop.
Fixes large titles in iOS13 when you still need to compile with Xcode 10 and Swift.
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 <Foundation/Foundation.h> | |
@class UINavigationBar; | |
NS_ASSUME_NONNULL_BEGIN | |
@interface OSThirteenDynamicFixes: NSObject | |
/** | |
On iOS 13.0+, ensure the background color and title properties are set properly (they are not available in Xcode 10, these are from a future SDK) | |
You must set up your `UINavigationBar.appearance()` as per usual before calling this method. Assumes a non-transparent navigation bar. | |
*/ | |
+ (void)fix:(UINavigationBar *__nullable)bar; | |
@end | |
NS_ASSUME_NONNULL_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 "OSThirteenDynamicFixes.h" | |
#import <UIKit/UIKit.h> | |
void perform(id __nullable target, NSString *__nonnull selectorString, id __nullable object); | |
BOOL isOSThirteen(void); | |
@implementation OSThirteenDynamicFixes | |
+ (void)fix:(UINavigationBar *__nullable)bar { | |
if (!bar) { return; } | |
if (!isOSThirteen()) { return; } | |
// Try to get the `UINavigationBarAppearance` class | |
id UINavigationBarAppearance = NSClassFromString(@"UINavigationBarAppearance"); | |
if (!UINavigationBarAppearance) { return; } | |
// Instantiate it | |
id ios13Appearance = [[UINavigationBarAppearance alloc] init]; | |
// Set properties on the appearance | |
perform(ios13Appearance, @"setBackgroundColor:", [UINavigationBar appearance].barTintColor); // Imitate behaviour for non-transparent bar pre iOS13 | |
perform(ios13Appearance, @"setTitleTextAttributes:", [UINavigationBar appearance].titleTextAttributes); | |
perform(ios13Appearance, @"setLargeTitleTextAttributes:", [UINavigationBar appearance].largeTitleTextAttributes); | |
// Unfortunately in Objective C these don't seem to settable on `[UINavigationBar appearance]` | |
// It seems that it may listen to messages sent to it and replay them back later...? | |
// Hence, set the appearance on the navigation bar directly | |
perform(bar, @"setStandardAppearance:", ios13Appearance); | |
perform(bar, @"setCompactAppearance:", ios13Appearance); | |
perform(bar, @"setScrollEdgeAppearance:", ios13Appearance); | |
} | |
@end | |
/// Performs a selector on an object with an argument - only if possible | |
/// Assumes the selector takes a single nullable argument | |
void perform(id __nullable target, NSString *__nonnull selectorString, id __nullable object) { | |
if (!target) { return; } | |
SEL selector = NSSelectorFromString(selectorString); | |
if ([target respondsToSelector: selector]) { | |
#pragma clang diagnostic push | |
#pragma clang diagnostic ignored "-Warc-performSelector-leaks" | |
// Using IMP didn't work for me | |
[target performSelector:selector withObject:object]; | |
#pragma clang diagnostic pop | |
} | |
} | |
/// Checks if we are running under iOS13 or later | |
BOOL isOSThirteen(void) { | |
if (@available(iOS 13,*)) { | |
return TRUE; | |
} else { | |
return FALSE; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment