忽略 iOS 中的动态类型:可访问性

Posted

技术标签:

【中文标题】忽略 iOS 中的动态类型:可访问性【英文标题】:Ignoring the dynamic type in iOS: Accessibility 【发布时间】:2015-01-07 07:56:29 【问题描述】:

有没有办法完全忽略 ios 应用中的动态类型/字体大小设置? 我的意思是有没有像 plist 条目这样的方法,这样我就可以完全禁用它。我知道有一个通知,我们可以在设置发生变化时观察并重新配置字体。我正在寻找一个更简单的解决方案。我正在使用iOS8。 谢谢。

【问题讨论】:

动态类型是你必须主动实现的(或者至少在 Interface Builder 中选择)。它不只是工作 如果我在手机的设置应用程序中更改字体大小并返回我的应用程序,字体就会更改。我没有为此做任何事情。 您在 Interface Builder 中使用什么字体? 没有使用界面生成器/故事板。已将代码中的字体设置为某个浮点值。 @FabioPoloni 是的,如果您使用默认的 UITableViewCell 标签,它会自动工作 【参考方案1】:

没有必要调配UIApplication。只需继承 UIApplication 并提供您自己的 preferredContentSizeCategory 实现:

斯威夫特:

class MyApplication: UIApplication 

    override var preferredContentSizeCategory: UIContentSizeCategory 
        get  return UIContentSizeCategory.large 
    


UIApplicationMain(
    CommandLine.argc,
    CommandLine.unsafeArgv,
    NSStringFromClass(MyApplication.self),
    NSStringFromClass(AppDelegate.self)
)

目标-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]));
    

【讨论】:

在 iOS 11 中工作。在实现这一点时,我了解到我一直在我的 iPhone 上完成我的所有开发工作,并将我的“大文本”滑块设置为 UIContentSizeCategoryExtraLarge(比默认)。无法知道“设置”中的默认值或重置为默认值(除非使用新的模拟器)。 “大文本”滑块始终处于活动状态(即使关闭)。当开关打开时,滑块有更大的范围。 又短又甜。在 iOS 13 中为我工作。【参考方案2】:

在你的AppDelegate 添加:

#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);

    ...

【讨论】:

@zeeple 应该是可能的。我只在 Obj-C 中有它。我试图快速转换到 Swift 2.2,但这需要整理出各种典型的 Swift 选择器和类型相关的问题;现在没有时间这样做。请使用您的 Swift 版本发布答案。 这个解决方案对我来说只有在启动新的应用程序时才有效。如果用户偶然修改了字体大小并在之后立即恢复应用程序,则此解决方案将不会涵盖该场景。 :(【参考方案3】:

只需为@gebirgsbärbel 答案提供 Swift 4 修复。 “preferredContentSizeCategory”在 Objective-C 中是一个方法,但在 Swift 中它是一个只读变量。所以在你的 AppDelegate 中是这样的:

@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
    

【讨论】:

【参考方案4】:

相当于@meaning-matters 的答案的swift 如下所示:

在您的 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)

【讨论】:

当我尝试使用它时,我得到编译器错误:Use of unresolved identifier 'preferredContentSizeCategory'。是否还需要其他东西才能使其正常工作? 我最好的猜测是将选择器更改为 getter: UIApplication.preferredContentSizeCategoryMyAppDelegate.swizzled_preferredContentSizeCategory 以及其他一些更改,这清除了编译器错误,但它在运行时似乎没有做任何事情。跨度>

以上是关于忽略 iOS 中的动态类型:可访问性的主要内容,如果未能解决你的问题,请参考以下文章

动态模拟 iOS 动态类型系统文本大小 (UIContentSizeCategory)

在 Swift 中禁用动态类型

iOS - 动态类型和界面生成器

自学python第一次整理

python第一周学习内容

CALayer 的动态可访问性标签