Skip to content

Instantly share code, notes, and snippets.

@maxchuquimia
Created September 12, 2019 05:23
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save maxchuquimia/e1c31daebc9a6ee2e343b2231fb40f40 to your computer and use it in GitHub Desktop.
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.
#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
#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