iOS设置屏幕方向代码示例
UIDevice+Orientation.h
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface UIDevice ()
/** 设置屏幕方向,小于iOS16 */
- (void)setOrientation:(UIInterfaceOrientation)orientation API_DEPRECATED("iOS16+使用setOrientationIOS16:", ios(2.0, 16.0));
@end
@interface UIDevice (Orientation)
/** 设置屏幕方向,iOS16+ */
- (void)setOrientationIOS16:(UIInterfaceOrientationMask)orientation API_AVAILABLE(ios(16.0));
- (void)setOrientationIOS16:(UIInterfaceOrientationMask)orientation errorHandler:(nullable void (^)(NSError *error))errorHandler API_AVAILABLE(ios(16.0));
@end
NS_ASSUME_NONNULL_END
UIDevice+Orientation.m
#import "UIDevice+Orientation.h"
@implementation UIDevice (Orientation)
- (void)setOrientationIOS16:(UIInterfaceOrientationMask)orientation
{
[self setOrientationIOS16:orientation errorHandler:nil];
}
- (void)setOrientationIOS16:(UIInterfaceOrientationMask)orientation errorHandler:(nullable void (^)(NSError *error))errorHandler
{
if(@available(iOS 16.0,*)){
UIWindowScene *scene = (UIWindowScene *)UIApplication.sharedApplication.connectedScenes.allObjects.firstObject;
UIWindowSceneGeometryPreferencesIOS *geometryPreferences = [[UIWindowSceneGeometryPreferencesIOS alloc] init];
geometryPreferences.interfaceOrientations = orientation;
if(errorHandler){
[scene requestGeometryUpdateWithPreferences:geometryPreferences errorHandler:errorHandler];
}else{
[scene requestGeometryUpdateWithPreferences:geometryPreferences errorHandler:^(NSError * _Nonnull error) {
NSLog(@"屏幕旋转失败: %@",error);
}];
}
}
}
@end
优化版本(推荐使用)
UIDevice+Orientation.h
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
/**
用于设置UI界面方向的自定义枚举值
*/
typedef NS_ENUM(NSInteger, TKInterfaceOrientation){
TKInterfaceOrientationPortrait,
TKInterfaceOrientationPortraitUpsideDown,
TKInterfaceOrientationLandscapeLeft,
TKInterfaceOrientationLandscapeRight
};
@interface UIDevice (Orientation)
/** 手动设置屏幕方向 */
- (void)setUIOrientation:(TKInterfaceOrientation)orientation;
/** 手动设置屏幕方向,新增错误操作回调 */
- (void)setUIOrientation:(TKInterfaceOrientation)orientation errorHandler:(nullable void (^)(NSError *error))errorHandler;
@end
NS_ASSUME_NONNULL_END
UIDevice+Orientation.m
#import "UIDevice+Orientation.h"
@interface UIDevice ()
/**
功能:设置屏幕方向,小于iOS16(手动旋转)
说明: 直接使用扩展来访问是有方法,即只声明不实现。
注意: 如果出现上架错误请直接使用以前的老方法实现。
*/
- (void)setOrientation:(UIInterfaceOrientation)orientation API_DEPRECATED("iOS16+使用setOrientationIOS16:", ios(2.0, 16.0));
@end
@implementation UIDevice (Orientation)
- (void)setUIOrientation:(TKInterfaceOrientation)orientation
{
[self setUIOrientation:orientation errorHandler:nil];
}
- (void)setUIOrientation:(TKInterfaceOrientation)orientation errorHandler:(nullable void (^)(NSError *error))errorHandler
{
NSInteger realOrientation = [self obtainOrientationRealValueWith:orientation];
if(@available(iOS 16.0,*)){
UIWindowScene *scene = (UIWindowScene *)UIApplication.sharedApplication.connectedScenes.allObjects.firstObject;
UIWindowSceneGeometryPreferencesIOS *geometryPreferences = [[UIWindowSceneGeometryPreferencesIOS alloc] init];
geometryPreferences.interfaceOrientations = realOrientation;
if(errorHandler){
[scene requestGeometryUpdateWithPreferences:geometryPreferences errorHandler:errorHandler];
}else{
[scene requestGeometryUpdateWithPreferences:geometryPreferences errorHandler:^(NSError * _Nonnull error) {
NSLog(@"屏幕旋转失败: %@",error);
}];
}
}else{
[self setOrientation:realOrientation];
}
}
/**
根据不同的系统版本获取TKInterfaceOrientation枚举对应的真实值
*/
- (NSInteger)obtainOrientationRealValueWith:(TKInterfaceOrientation)orientation
{
NSInteger real = 0;
if(@available(iOS 16.0,*)){
switch (orientation) {
case TKInterfaceOrientationPortrait:
real = UIInterfaceOrientationMaskPortrait;
break;
case TKInterfaceOrientationPortraitUpsideDown:
real = UIInterfaceOrientationMaskPortraitUpsideDown;
break;
case TKInterfaceOrientationLandscapeLeft:
real = UIInterfaceOrientationMaskLandscapeLeft;
break;
case TKInterfaceOrientationLandscapeRight:
real = UIInterfaceOrientationMaskLandscapeRight;
break;
}
}else{
switch (orientation) {
case TKInterfaceOrientationPortrait:
real = UIInterfaceOrientationPortrait;
break;
case TKInterfaceOrientationPortraitUpsideDown:
real = UIInterfaceOrientationPortraitUpsideDown;
break;
case TKInterfaceOrientationLandscapeLeft:
real = UIInterfaceOrientationLandscapeLeft;
break;
case TKInterfaceOrientationLandscapeRight:
real = UIInterfaceOrientationLandscapeRight;
break;
}
}
return real;
}
@end
解释
扩展了一个没有实现的方法:setOrientation:(UIInterfaceOrientation)orientation,来支持iOS16以下的屏幕方向设置。
这种写法就是使用了OC扩展的特性来访问私有方法。
不使用传统方式调用其目的就是简化代码,如果审核不通过就是用老的方式进行调用即可。