说新版本之前先了解下旧版本的适配,直接上代码:(我们公司的项目是根据按钮强制横竖屏的)
1.在AppDelegate类上这个方法:根据按钮设置做出响应
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
UIDevice *device = [UIDevice currentDevice];
if (!_shouldRotate||device.orientation == UIDeviceOrientationPortraitUpsideDown){
return UIInterfaceOrientationMaskPortrait;
}else{
return UIInterfaceOrientationMaskLandscapeLeft;
}
}
2.在点击按钮的ViewController类中写下列方法
- (void)clickScreenBtn:(UIButton*)btn{
//放大
btn.selected = !btn.selected;
if (btn.selected) {//放大
AppDelegate *delegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
delegate.shouldRotate = YES;
NSNumber *value = [NSNumber numberWithInt:UIDeviceOrientationLandscapeLeft];
[[UIDevice currentDevice] setValue:value forKey:@"orientation"];
}else{//还原
AppDelegate *delegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
delegate.shouldRotate = NO;
NSNumber *value = [NSNumber numberWithInt:UIDeviceOrientationPortrait];
[[UIDevice currentDevice] setValue:value forKey:@"orientation"];
}
}
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id <UIViewControllerTransitionCoordinator>)coordinator{
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
kWSelf(self)
if (size.width>size.height) {//横屏
self.navigationController.navigationBar.hidden = YES;
[coordinator animateAlongsideTransition:nil completion:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
//更新view的位置与大小 下面是我的界面可以换成你自己的
weakself.playerView.frame = CGRectMake(0, 0, kScreenWidth, kScreenHeight);
weakself.avLayer.frame = weakself.playerView.bounds;
weakself.toolBarView.frame = CGRectMake(0, kScreenHeight-40, kScreenWidth, kScreenHeight-40);
weakself.infoView.hidden = YES;
}];
}else{
self.navigationController.navigationBar.hidden = NO;
[coordinator animateAlongsideTransition:nil completion:^(id<UIViewControllerTransitionCoordinatorContext> context){
//更新view的位置与大小 下面是我的界面可以换成你自己的
weakself.playerView.frame = CGRectMake(0, 0, kScreenWidth, 250);
weakself.avLayer.frame = weakself.playerView.bounds;
weakself.toolBarView.frame = CGRectMake(0, 210, kScreenWidth, 40);
weakself.infoView.hidden = NO;
}];
}
}
4.以上是旧版本的,从IOS16.0开始苹果更改了屏幕的旋转机制,以后都要用UIWindowScene api的类
// 获取当前屏幕横竖屏状态
+ (UIInterfaceOrientation)interfaceOrientation {
if (@available(iOS 13.0, *)) {
return [UIApplication sharedApplication].windows.firstObject.windowScene.interfaceOrientation;
}
return [[UIApplication sharedApplication] statusBarOrientation];
}
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
/// 旋转屏幕
/// - Parameters:
/// - interfaceOrientation: 目标屏幕方向
/// - viewController: 所在的视图控制器
/// - errorHandler: 错误回调
+ (void)rotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation viewController:(UIViewController *)viewController errorHandler:(void (^)(NSError *))errorHandler {
#if __IPHONE_16_0 //兼容 Xcode13
if (@available(iOS 16.0, *)) {
UIWindowScene *windowScene = viewController.view.window.windowScene;
if (!windowScene) {
return;
}
[viewController setNeedsUpdateOfSupportedInterfaceOrientations];
UIWindowSceneGeometryPreferencesIOS *geometryPreferences = [[UIWindowSceneGeometryPreferencesIOS alloc] init];
switch (interfaceOrientation) {
case UIInterfaceOrientationPortrait:
geometryPreferences.interfaceOrientations = UIInterfaceOrientationMaskPortrait;
break;
case UIInterfaceOrientationPortraitUpsideDown:
geometryPreferences.interfaceOrientations = UIInterfaceOrientationMaskPortraitUpsideDown;
break;
case UIInterfaceOrientationLandscapeLeft:{
geometryPreferences.interfaceOrientations = UIInterfaceOrientationMaskLandscapeLeft;
NSLog(@"横屏");
}
break;
case UIInterfaceOrientationLandscapeRight:
geometryPreferences.interfaceOrientations = UIInterfaceOrientationMaskLandscapeRight;
break;
default:
break;
}
[windowScene requestGeometryUpdateWithPreferences:geometryPreferences errorHandler:^(NSError * _Nonnull error) {
//业务代码
//NSLog(@"menglc errorHandler error %@", error);
if (errorHandler) {
errorHandler(error);
}
}];
return;
}
#endif
if([[UIDevice currentDevice]respondsToSelector:@selector(setOrientation:)]) {
SEL selector = NSSelectorFromString(@"setOrientation:");
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[UIDevice instanceMethodSignatureForSelector:selector]];
[invocation setSelector:selector];
[invocation setTarget:[UIDevice currentDevice]];
int val = UIInterfaceOrientationLandscapeRight;//横屏UIInterfaceOrientationPortrait
[invocation setArgument:&val atIndex:2];
[invocation invoke];
}
}
不仅可以在上述方法case更新view位置与大小;还可以在第二项第二个方法中更新view位置与大小 - (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id <UIViewControllerTransitionCoordinator>)coordinator