Is there a way to completely ignore dynamic type/font size settings in iOS apps? I mean is there a way like a plist entry so that I can disable it completely. I understand there is a notification we can observe and re-configure the font whenever there is change in the settings. I am looking for a simpler solution. I am using iOS8. Thanks.
可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
回答1:
There's no need to swizzle UIApplication
. Just subclass UIApplication
and provide your own implementation of preferredContentSizeCategory
:
Swift:
class MyApplication: UIApplication {
override var preferredContentSizeCategory: UIContentSizeCategory {
get { return UIContentSizeCategory.large }
}
}
UIApplicationMain(
CommandLine.argc,
CommandLine.unsafeArgv,
NSStringFromClass(MyApplication.self),
NSStringFromClass(AppDelegate.self)
)
Objective-C:
@interface MyApplication : UIApplication
@end
@implementation MyApplication
- (UIContentSizeCategory) preferredContentSizeCategory
{
return UIContentSizeCategoryLarge;
}
@end
int main(int argc, char * argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, NSStringFromClass([MyApplication class]), NSStringFromClass([AppDelegate class]));
}
}
回答2:
The swift equivalent to the answer of @meaning-matters looks as follows:
In your AppDelegate:
@objc func swizzled_preferredContentSizeCategory() -> UIContentSizeCategory {
return UIContentSizeCategory.small
}
open func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
let originalMethod = class_getInstanceMethod(UIApplication.self, #selector(preferredContentSizeCategory))
let swizzledMethod = class_getInstanceMethod(UIApplication.self, #selector(swizzled_preferredContentSizeCategory))
method_exchangeImplementations(originalMethod, swizzled_preferredContentSizeCategory)
}
回答3:
In your AppDelegate
add:
#import <objc/runtime.h>
@implementation AppDelegate
NSString* swizzled_preferredContentSizeCategory(id self, SEL _cmd)
{
return UIContentSizeCategoryLarge; // Set category you prefer, Large being iOS' default.
}
- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{
Method method = class_getInstanceMethod([UIApplication class], @selector(preferredContentSizeCategory));
method_setImplementation(method, (IMP)swizzled_preferredContentSizeCategory);
...
}
回答4:
Just provide Swift 4 fix to @gebirgsbärbel answer. "preferredContentSizeCategory" in Objective-C is a method, but in Swift it is a read-only variable. So in your AppDelegate is like this:
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
// MARK: - UIApplicationDelegate
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
UIApplication.classInit
self.window = UIWindow(frame: UIScreen.main.bounds)
...
self.window?.makeKeyAndVisible()
return true
}
}
// MARK: - Fix Dynamic Type
extension UIApplication {
static let classInit: Void = {
method_exchangeImplementations(
class_getInstanceMethod(UIApplication.self, #selector(getter: fixedPreferredContentSizeCategory))!,
class_getInstanceMethod(UIApplication.self, #selector(getter: preferredContentSizeCategory))!
)
}()
@objc
var fixedPreferredContentSizeCategory: UIContentSizeCategory {
return .large
}
}