如何隐藏主页指示器 iPhone X 在 app delegate 中编写通用代码

How to hide the home indicator for iPhone X writing a common code in app delegate

在我的项目中,我想隐藏主页指示器,而不是在每个视图控制器中编写相同的代码,而是在 appDelegate 中实现它。我试过了

   - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    self.window.backgroundColor = [UIColor yellowColor];
    return YES;
}

-(BOOL)prefersHomeIndicatorAutoHidden{
    return YES;
}

我这样试过,但效果不佳。那么,如何在不写入每个视图控制器的情况下隐藏主页指示器,而不是从应用程序委托本身实现呢?

有一种方法可以做到这一点。在我看来,它不是最优雅的,我同意 Gereon 的观点,你最好创建一个 UIViewController 的子 class,在那里实现它,然后让你的所有视图控制器继承它基地 class.

不过,您可以使用 Method Swizzling 来完成此操作。在这里查看:https://nshipster.com/method-swizzling/。在您的情况下,您可以在 application: didFinishLaunchingWithOptions: 中的 AppDelegate 中调配它,并将 prefersHomeIndicatorAutoHidden 调配到您的自定义函数 returns YES.

因此,对于调配,我建议您创建一个新的 UIViewController 类别。实际调配:

#import <objc/runtime.h>

@implementation UIViewController (Swizzling)

+ (void)load
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        Class class = [self class];
        SEL originalSelector = @selector(prefersHomeIndicatorAutoHidden);
        SEL swizzledSelector = @selector(swizzledPrefersHomeIndicatorAutoHidden);
        Method originalMethod = class_getInstanceMethod(class, originalSelector);
        Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);

        const BOOL didAdd = class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));
        if (didAdd)
            class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
        else
            method_exchangeImplementations(originalMethod, swizzledMethod);
    });
}

- (BOOL)prefersHomeIndicatorAutoHidden
{
    return YES; //Doesn't matter what you return here. In this you could return the actual property value.
}

- (BOOL)swizzledPrefersHomeIndicatorAutoHidden //This is the actual `prefersHomeIndicatorAutoHidden ` call
{
    return YES;
}

@end