iOS-关于UIViewController常用的分类功能

  • 1、获取最顶层的控制器(可以通过该功能获取导航控制器)
  • 2、页面旋转

一、获取到最上层的控制器

构建UIViewController的分类来实现该方法

1、在.h文件中声明方法

#import 

NS_ASSUME_NONNULL_BEGIN

@interface UIViewController (SLExtension)

/// 当前控制器
+ (__kindof UIViewController *)currentViewController;

@end

2、在.m文件中实现该方法

#import "UIViewController+SLExtension.h"

@implementation UIViewController (SLExtension)

+ (__kindof UIViewController *)currentViewController {
    __block UIViewController *viewController;
    [self performSelectorOnMainThreadWithSync:^{
        viewController = [self findViewController:self.frontWindow.rootViewController];
    }];
    return viewController;
}

+ (UIViewController *)findViewController:(UIViewController *)viewController {
    if (viewController.presentedViewController) {
        return [self findViewController:viewController.presentedViewController];
    } else if ([viewController isKindOfClass:[UISplitViewController class]]) {
        UISplitViewController *vc = (UISplitViewController *)viewController;
        if (vc.viewControllers.count > 0) {
            return [self findViewController:vc.viewControllers.lastObject];
        } else {
            return viewController;
        }
    } else if ([viewController isKindOfClass:[UINavigationController class]]) {
        UINavigationController *vc = (UINavigationController *)viewController;
        if (vc.viewControllers.count > 0) {
            return [self findViewController:vc.topViewController];
        } else {
            return viewController;
        }
    } else if ([viewController isKindOfClass:[UITabBarController class]]) {
        UITabBarController *vc = (UITabBarController *)viewController;
        if (vc.viewControllers.count > 0) {
            return [self findViewController:vc.selectedViewController];
        } else {
            return viewController;
        }
    } else {
        return viewController;
    }
}

+ (UIWindow *)frontWindow {
#if !defined(SV_APP_EXTENSIONS)
    __block UIWindow *fwindow;
    [self performSelectorOnMainThreadWithSync:^{
        NSEnumerator *frontToBackWindows = [UIApplication.sharedApplication.windows reverseObjectEnumerator];
        for (UIWindow *window in frontToBackWindows) {
            BOOL windowOnMainScreen = window.screen == UIScreen.mainScreen;
            BOOL windowIsVisible = !window.hidden && window.alpha > 0;
            BOOL windowLevelSupported = (window.windowLevel >= UIWindowLevelNormal && window.windowLevel <= UIWindowLevelNormal);
            if(windowOnMainScreen && windowIsVisible && windowLevelSupported) {
                fwindow = window;
            }
        }
    }];
#endif
    return fwindow;
}

+ (void)performSelectorOnMainThreadWithSync:(void (^)(void))customEvent {
    if (!customEvent) return;
    
    if ([NSThread isMainThread]) {
        customEvent();
    } else {
        dispatch_sync(dispatch_get_main_queue(), ^{
            customEvent();
        });
    }
}
@end

二、设置控制器强制旋转

同样在UIViewController的分类当中实现,在.h文件中增加两个方法

/// 设置控制器方向
/// @param orientation 方向
- (void)setupOrientation:(UIInterfaceOrientation)orientation;

/// 还原控制器方向
- (void)resetRotation;

在.m文件中进行实现

- (void)setupOrientation:(UIInterfaceOrientation)orientation {
    id  delegate = [UIApplication sharedApplication].delegate;
    if ([delegate respondsToSelector:NSSelectorFromString(@"setOrientation:")]) {
        [(id)delegate setValue:@(orientation) forKey:@"orientation"];
        [self setupDeviceOrientation:orientation];
    }
}

- (void)resetRotation {
    [self setupOrientation:UIInterfaceOrientationPortrait];
}

- (void)setupDeviceOrientation:(UIInterfaceOrientation)orientation {
    NSNumber *orientationNumber = [NSNumber numberWithInteger:orientation];
    [UIDevice.currentDevice setValue:orientationNumber forKey:@"orientation"];
    // 强制旋转
    [UIViewController attemptRotationToDeviceOrientation];
}

你可能感兴趣的:(iOS-关于UIViewController常用的分类功能)