iOS开发 16以后横竖屏切换-OC

380 阅读2分钟

哎,网上各种代码,各说各的,代码都不全,废话不多说,上代码

在AppDelegate.m中

- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
   if ([manager sharedManager].isCanLan) {
        return [manager sharedManager].orientation;
    }
    return UIInterfaceOrientationMaskPortrait;
}

在UINavigationController的子类中

- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
    return self.topViewController.supportedInterfaceOrientations;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return self.topViewController.preferredInterfaceOrientationForPresentation;
}
- (BOOL)shouldAutorotate {
    return self.topViewController.shouldAutorotate;
}

在UITabBarController中

- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
     return self.selectedViewController.supportedInterfaceOrientations;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
     return self.selectedViewController.preferredInterfaceOrientationForPresentation;
}
- (BOOL)shouldAutorotate {
     return self.selectedViewController.shouldAutorotate;
}
// 监听方向改变
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
    // 根据业务需要更新UI,这里不做填充了,每个类都有这个方法,可以把他放在要实现的类中
    

}

在要实现横竖屏切换的类中

.h中
@property (nonatomic, assign) UIInterfaceOrientationMask orientation;
- (UIInterfaceOrientation)getDeviceOrientation;
.m中
- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    
    UIInterfaceOrientation currentOrientation = [self getDeviceOrientation];
    if (self.orientation == UIInterfaceOrientationMaskPortrait && currentOrientation != UIInterfaceOrientationPortrait) {// 竖屏状态
           // 切竖屏
           [manager sharedManager].isCanLan = NO;
           [self setScreenOrientation:UIInterfaceOrientationMaskPortrait controller:self];
        } else if (self.orientation == UIInterfaceOrientationMaskLandscapeLeft && currentOrientation != UIInterfaceOrientationLandscapeLeft) {// 横屏状态
// 切横屏
    [manager sharedManager].isCanLan = YES;
    [self setScreenOrientation:UIInterfaceOrientationMaskLandscapeLeft controller:self];
        } else if (self.orientation == UIInterfaceOrientationMaskLandscapeRight && currentOrientation != UIInterfaceOrientationLandscapeRight) {// 横屏状态
// 切换屏
 [manager sharedManager].isCanLan = YES;
    [self setScreenOrientation:UIInterfaceOrientationMaskLandscapeLeft controller:self];
        }
    }

}
- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    UIInterfaceOrientation currentOrientation = [self getDeviceOrientation];
    if (currentOrientation != UIInterfaceOrientationPortrait) {// 恢复成竖屏
         [manager sharedManager].isCanLan = NO;
        [self setScreenOrientation:UIInterfaceOrientationMaskPortrait controller:self];
    }
}
- (UIInterfaceOrientation)getDeviceOrientation {
    __block UIInterfaceOrientation orientation = UIInterfaceOrientationUnknown;
    if (@available(iOS 13.0, *)) {
        NSSet *connectedScenes = UIApplication.sharedApplication.connectedScenes;
        for (UIScene *scene in connectedScenes) {
            if ([scene isKindOfClass:[UIWindowScene class]]) {
                UIWindowScene *windowScene = (UIWindowScene *)scene;
                orientation = windowScene.interfaceOrientation;
                break;
            }
        }
    } else {
        // 对于iOS 13以下版本,使用应用程序的状态栏方向
        orientation = [[UIApplication sharedApplication] statusBarOrientation];
    }
    // 如果还是未知,则使用UIDevice作为后备
    if (orientation == UIInterfaceOrientationUnknown) {
        UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;
        if (UIDeviceOrientationIsValidInterfaceOrientation(deviceOrientation)) {
            switch (deviceOrientation) {
                case UIDeviceOrientationPortrait:
                    orientation = UIInterfaceOrientationPortrait;
                    break;
                case UIDeviceOrientationPortraitUpsideDown:
                    orientation = UIInterfaceOrientationPortraitUpsideDown;
                    break;
                case UIDeviceOrientationLandscapeLeft:
                    orientation =  UIInterfaceOrientationLandscapeRight;// 由于设备与界面方向不同;
                    break;
                case UIDeviceOrientationLandscapeRight:
                    orientation = UIInterfaceOrientationLandscapeLeft;// 由于设备与界面方向不同
                    break;
                default:
                    orientation = UIInterfaceOrientationPortrait;
                    break;
            }
        }
    }
    return orientation;
}

手动强制横竖屏的代码

- (void)setScreenOrientation:(UIInterfaceOrientationMask)orientation controller:(UIViewController *)H5{
    UIInterfaceOrientation currentOrientation = [H5 getDeviceOrientation];
    UIInterfaceOrientation targetOrientation;
    if (orientation == UIInterfaceOrientationMaskPortrait) {
        targetOrientation = UIInterfaceOrientationPortrait;
    } else if (orientation == UIInterfaceOrientationMaskLandscapeLeft) {
        targetOrientation = UIInterfaceOrientationLandscapeLeft;
    } else if (orientation == UIInterfaceOrientationMaskLandscapeRight) {
        targetOrientation = UIInterfaceOrientationLandscapeRight;
    } else {
        NSLog(@"不支持的方向");
        return;
    }
    // 检查是否需要旋转
    if (currentOrientation == targetOrientation) {
    // 不旋转但是可能需要更新UI,根据业务逻辑来
       [self updateUI];
        return;
    }
    // 这里用来设置具体支持的方法,appdelegate中会用到
    [manager sharedManager].orientation = orientation;
    @try {
        if (@available(iOS 16.0, *)) {
            // iOS 16 及以上版本
            NSArray *array = [[[UIApplication sharedApplication] connectedScenes] allObjects];
            UIWindowScene *scene = [array firstObject];
            UIWindowSceneGeometryPreferencesIOS *geometryPreferences =
            [[UIWindowSceneGeometryPreferencesIOS alloc] initWithInterfaceOrientations:orientation];
            [H5 setNeedsUpdateOfSupportedInterfaceOrientations];
            [scene requestGeometryUpdateWithPreferences:geometryPreferences errorHandler:^(NSError *_Nonnull error) {
            NSLog(@"错误:%@",error);
            }];
        } else {
            // iOS 16 以下版本
            UIDeviceOrientation deviceOrientation;
            switch (targetOrientation) {
                case UIInterfaceOrientationPortrait:
                    deviceOrientation = UIDeviceOrientationPortrait;
                    break;

                case UIInterfaceOrientationLandscapeLeft:
                    deviceOrientation = UIDeviceOrientationLandscapeRight;
                    break;

                case UIInterfaceOrientationLandscapeRight:
                    deviceOrientation = UIDeviceOrientationLandscapeLeft;
                    break;
                default:
                    deviceOrientation = UIDeviceOrientationPortrait;
            }
            if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)]) {
                SEL selector = NSSelectorFromString(@"setOrientation:");
                NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:
                                                             [UIDevice instanceMethodSignatureForSelector:selector]];
                [invocation setSelector:selector];
                [invocation setTarget:[UIDevice currentDevice]];
                [invocation setArgument:&deviceOrientation atIndex:2];
                [invocation invoke];
            }
        }
    } @catch (NSException *exception) {

    } @finally {

    }

}

搞完!!!!!!!!!!!!!!!!!!!!!!!!!用到了辛苦,点个赞,谢谢!