iOS 橫屏豎屏切換問(wèn)題

首先系統(tǒng)設(shè)置只能豎屏

1谆级、UITabBarController 繼承類實(shí)現(xiàn)

//是否自動(dòng)旋轉(zhuǎn)

-(BOOL)shouldAutorotate{

? ? return self.selectedViewController.shouldAutorotate;

}

//支持哪些屏幕方向

- (UIInterfaceOrientationMask)supportedInterfaceOrientations {

? ? return [self.selectedViewController supportedInterfaceOrientations];

}

// persent出頁(yè)面時(shí)的默認(rèn)方向,

// 網(wǎng)上很多文章認(rèn)為是進(jìn)入頁(yè)面時(shí)的默認(rèn)方向, 這個(gè)是不對(duì)的, 這個(gè)方法只針對(duì)present出來(lái)的vc, 注意看方法名后面? ForPresentation

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{

? ? return [self.selectedViewController preferredInterfaceOrientationForPresentation];

}


2、UINavigationController 繼承類實(shí)現(xiàn)

/是否自動(dòng)旋轉(zhuǎn)

-(BOOL)shouldAutorotate{

? ? return self.topViewController.shouldAutorotate;

}

//支持哪些屏幕方向

- (UIInterfaceOrientationMask)supportedInterfaceOrientations {

? ? return [self.topViewController supportedInterfaceOrientations];

}

// persent出頁(yè)面時(shí)的默認(rèn)方向,

// 網(wǎng)上很多文章認(rèn)為是進(jìn)入頁(yè)面時(shí)的默認(rèn)方向, 這個(gè)是不對(duì)的, 這個(gè)方法只針對(duì)present出來(lái)的vc, 注意看方法名后面? ForPresentation

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{

? ? return [self.topViewController preferredInterfaceOrientationForPresentation];

}

3橄登、AppDelegate.m實(shí)現(xiàn)

- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window

{

?? ??//避免導(dǎo)航欄導(dǎo)致bug

? ? [[UIApplication sharedApplication] setStatusBarHidden:NO];

//_allowRotate 自己定義的屬性舰攒,隨便可以定義bool值败富,目的就是在某個(gè)viewController讓window先支持屏幕旋轉(zhuǎn)

? ? if (_allowRotate == 1) {

? ? ? ? ? ? return UIInterfaceOrientationMaskAll;

? ? ? ? }else{

? ? ? ? ? ? return (UIInterfaceOrientationMaskPortrait);

? ? ? ? }

}


4、viewController 頁(yè)面

//1.決定當(dāng)前界面是否開啟自動(dòng)轉(zhuǎn)屏摩窃,如果返回NO兽叮,后面兩個(gè)方法也不會(huì)被調(diào)用,只是會(huì)支持默認(rèn)的方向

- (BOOL)shouldAutorotate {

? ? ? return YES;

}


//2.返回支持的旋轉(zhuǎn)方向

//iPad設(shè)備上猾愿,默認(rèn)返回值UIInterfaceOrientationMaskAllButUpSideDwon

//iPad設(shè)備上鹦聪,默認(rèn)返回值是UIInterfaceOrientationMaskAll

- (UIInterfaceOrientationMask)supportedInterfaceOrientations{

???return UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskPortrait;

}

// persent出頁(yè)面時(shí)的默認(rèn)方向,

// 網(wǎng)上很多文章認(rèn)為是進(jìn)入頁(yè)面時(shí)的默認(rèn)方向, 這個(gè)是不對(duì)的, 這個(gè)方法只針對(duì)present出來(lái)的vc, 注意看方法名后面? ForPresentation

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {

? ? return UIInterfaceOrientationPortraitUpsideDown;

}

-(void)viewWillAppear:(BOOL)animated

{

? ? [super viewWillAppear:animated];

? ? [self.navigationController setNavigationBarHidden:YES animated:animated];

? ? //在視圖出現(xiàn)的時(shí)候,將allowRotate改為1

?? ? AppDelegate * delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;

?? ? delegate.allowRotate = 1;

}

到此為止蒂秘,屏幕就可以根據(jù)你設(shè)置支持的方向進(jìn)行旋轉(zhuǎn)了

//當(dāng)發(fā)生轉(zhuǎn)屏事件時(shí)泽本,系統(tǒng)的回調(diào)方法是:

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {

? ? [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];

? ? // 即將開始轉(zhuǎn)屏

? ? [self viewWillBeginTransitionWithSize:size];

? ? WS(weakSelf)

? ? [coordinator animateAlongsideTransition:nil completion:^(id<UIViewControllerTransitionCoordinatorContext>? _Nonnull context) {

? ? ? ? [weakSelf viewDidEndTransitionWithSize:size];

? ? }];

}

/// 子視圖即將開始旋轉(zhuǎn)

- (void)viewWillBeginTransitionWithSize:(CGSize)size {

? ? if (size.width > size.height) { // 橫屏

? ? ? ? // 橫屏布局 balabala

? ?[self.view.layer setNeedsLayout];

? ? [self.view.layer layoutIfNeeded];

? ? } else {

? ? ? ? // 豎屏布局 balabala

? ?[self.view.layer setNeedsLayout];

? ? [self.view.layer layoutIfNeeded];

? ? }

}

/// 子視圖旋轉(zhuǎn)完成

- (void)viewDidEndTransitionWithSize:(CGSize)size {

? ? if (size.width > size.height) { // 橫屏

? ? ? ? // 橫屏布局 balabala

? ? ?[self.view.layer setNeedsLayout];

? ? ?[self.view.layer layoutIfNeeded];

? ? } else {

? ? ? ? // 豎屏布局 balabala

? [self.view.layer setNeedsLayout];

? ? [self.view.layer layoutIfNeeded];

? ? }

}


//最好刷新下view

? [self.view.layer setNeedsLayout];

? ?[self.view.layer layoutIfNeeded];

我項(xiàng)目里用的是監(jiān)聽的方法,監(jiān)聽屏幕發(fā)聲變化的時(shí)候

//在viewDidLoad 監(jiān)聽屏幕變化姻僧,但是這個(gè)方法不能判斷屏幕到底向左還是向右规丽,如果支持多個(gè)方向的話蒲牧,遇到劉海屏還得適配,不然劉海屏有可能遮住UI赌莺,還有一個(gè)方法監(jiān)聽屏幕方向的

?//屏幕方向通知

? ? [[NSNotificationCenter defaultCenter] addObserver:self

?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? selector:@selector(onDeviceOrientationDidChange) name:UIDeviceOrientationDidChangeNotification

?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? object:nil];

//屏幕尺寸變化的時(shí)候

? ? [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(videoListdetectOrientation) name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];

#pragma mark - Notification:

- (void)videoListdetectOrientation{

? ??[self.view.layer setNeedsLayout];

? ? [self.view.layer layoutIfNeeded];

? ?if(self.view.frame.size.width > self.view.frame.size.height){

? ? ? //橫屏

? }else{


? }

}

#pragma mark - 屏幕方向通知

- (BOOL)onDeviceOrientationDidChange{

? ? //獲取當(dāng)前設(shè)備Device

? ? UIDevice *device = [UIDevice currentDevice];

? ? //識(shí)別當(dāng)前設(shè)備的旋轉(zhuǎn)方向

? ? switch (device.orientation) {

? ? ? ? case UIDeviceOrientationFaceUp:

? ? ? ? ? ? DLog(@"屏幕幕朝上平躺");

? ? ? ? ? ?

? ? ? ? ? ? break;

?? ? ? ? ? ?

? ? ? ? case UIDeviceOrientationFaceDown:

? ? ? ? ? ? DLog(@"屏幕朝下平躺");

?? ? ? ? ?

? ? ? ? ? ? break;

? ? ? ? case UIDeviceOrientationUnknown:

? ? ? ? ? ? //系統(tǒng)當(dāng)前無(wú)法識(shí)別設(shè)備朝向冰抢,可能是傾斜

? ? ? ? ? ? DLog(@"未知方向");

?? ? ? ? ?

? ? ? ? ? ? break;

?? ? ? ? ? ?

? ? ? ? case UIDeviceOrientationLandscapeLeft:{

?? ? ? ? ? ?

? ? ? ? ? ? DLog(@"屏幕向左橫置"); //只支持的方向

? ? ? ? ? ??break;

? ? ? ? }

? ? ? ? case UIDeviceOrientationLandscapeRight:

? ? ? ? ? ? DLog(@"屏幕向右橫置");

? ? ? ? ? ? break;

?? ? ? ? ? ?

? ? ? ? case UIDeviceOrientationPortrait:{

? ? ? ? ? ? DLog(@"屏幕直立");? ? ? ? ? ??

? ? ? ? ? ? break;

? ? ? ? }

? ? ? ? case UIDeviceOrientationPortraitUpsideDown:

? ? ? ? ? ? DLog(@"屏幕直立,上下顛倒");

? ? ? ? ? ? break;

?? ? ? ? ? ?

? ? ? ? default:

? ? ? ? ? ? DLog(@"無(wú)法識(shí)別");

? ? ? ? ? ??break;

? ? }

? ? return YES;

}


//屏幕適配問(wèn)題艘狭,橫屏的時(shí)候獲取不到狀態(tài)欄高度挎扰,如果豎屏的時(shí)候self.view.layer layoutIfNeeded 不刷新view也獲取不到狀態(tài)欄高度,所以最好是豎屏的時(shí)候先用個(gè)屬性賦值下缓升,用Masonry 和 frame 都沒(méi)切換 的時(shí)候都沒(méi)問(wèn)題鼓鲁,橫屏的時(shí)候在調(diào)橫屏子view的約束,一開始可以在-(instancetype)initWithFrame:(CGRect)frame

{

? ? if (self = [super initWithFrame:frame]) {

?? ?

? ? ? ? [self initsubviews];

? ? }

? ? return self;

}

只初始化添加港谊,而不加約束


5骇吭、重點(diǎn),豎屏的時(shí)候點(diǎn)擊按鈕push跳轉(zhuǎn)沒(méi)問(wèn)題歧寺,橫屏的時(shí)候push跳轉(zhuǎn)過(guò)去之后燥狰,下個(gè)頁(yè)面布局錯(cuò)亂

解決辦法,一定要在跳轉(zhuǎn)之前先把橫屏變成豎屏在跳轉(zhuǎn)斜筐。

注意點(diǎn):如果只是寫在-(void)viewWillDisappear:(BOOL)animated 方法里是不管用的龙致,因?yàn)樗麜?huì)先執(zhí)行下個(gè)頁(yè)面的viewDidLoad 在執(zhí)行旋轉(zhuǎn),這個(gè)時(shí)候下個(gè)頁(yè)面的view的寬高是橫屏狀態(tài)顷链,導(dǎo)致頁(yè)面錯(cuò)亂目代,顯示的是豎屏的樣式,實(shí)際寬高是橫屏

- (void)orientationPortrait{

?? ? ? AppDelegate * delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;

?? ? ? delegate.allowRotate = 0;

? ?

? ? if (@available(iOS 16.0, *)) {

? ? ? ? // iOS 16新增加了一個(gè)方法setNeedsUpdateOfSupportedInterfaceOrientations 方法是 UIViewController 的方法嗤练。這和更新狀態(tài)欄的方法有點(diǎn)像榛了,簡(jiǎn)單點(diǎn)說(shuō)就是你想轉(zhuǎn)屏可以,需要通知UIViewController 你已經(jīng)準(zhǔn)備好要轉(zhuǎn)屏的方向了煞抬,然后再調(diào)用轉(zhuǎn)屏方法即可(轉(zhuǎn)屏方法后面會(huì)講到)

? ? ? ? [self setNeedsUpdateOfSupportedInterfaceOrientations];

? ? ? ? NSArray *array = [[[UIApplication sharedApplication] connectedScenes] allObjects];

? ? ? ? UIWindowScene *scene = [array firstObject];

? ? ? ? // 屏幕方向

? ? ? ? UIInterfaceOrientationMaskorientation =? UIInterfaceOrientationMaskPortrait;

? ? ? ? UIWindowSceneGeometryPreferencesIOS *geometryPreferencesIOS = [[UIWindowSceneGeometryPreferencesIOS alloc] initWithInterfaceOrientations:orientation];

? ? ? ? // 開始切換

? ? ? ? [scenerequestGeometryUpdateWithPreferences:geometryPreferencesIOS errorHandler:^(NSError * _Nonnull error) {

? ? ? ? ? ?

? ? ? ? }];

? ? }else{

?? ? ? ?

? ? ? ? //這個(gè)方法只有在- (BOOL)shouldAutorotate( return YES; )時(shí)霜大,才會(huì)生效。并且請(qǐng)注意使用的枚舉值的不同革答。

?? ? ? ? if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)]) {

? ? ? ? ? ? ? ? SEL selector = NSSelectorFromString(@"setOrientation:");

? ? ? ? ? ? ? ? NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[UIDevice instanceMethodSignatureForSelector:selector]];

? ? ? ? ? ? ? ? [invocationsetSelector:selector];

? ? ? ? ? ? ? ? [invocationsetTarget:[UIDevice currentDevice]];

? ? ? ? ? ? ? ? int val = UIInterfaceOrientationPortrait;

? ? ? ? ? ? ? ? [invocationsetArgument:&val atIndex:2];

? ? ? ? ? ? ? ? [invocationinvoke];

? ? ? ? ? ? }

?? ? ? ?

?? ? ? ? ? //會(huì)強(qiáng)制系統(tǒng)嘗試將界面旋轉(zhuǎn)到新的方向(必須加战坤,不然橫屏的時(shí)候跳到下個(gè)頁(yè)面,下個(gè)頁(yè)面會(huì)錯(cuò)亂)

?? ? ? ? ? [UIViewController attemptRotationToDeviceOrientation];

?? ? ? ?

? ? }

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末残拐,一起剝皮案震驚了整個(gè)濱河市途茫,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蹦骑,老刑警劉巖慈省,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡边败,警方通過(guò)查閱死者的電腦和手機(jī)袱衷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)笑窜,“玉大人致燥,你說(shuō)我怎么就攤上這事∨沤兀” “怎么了嫌蚤?”我有些...
    開封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)断傲。 經(jīng)常有香客問(wèn)我脱吱,道長(zhǎng),這世上最難降的妖魔是什么认罩? 我笑而不...
    開封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任箱蝠,我火速辦了婚禮,結(jié)果婚禮上垦垂,老公的妹妹穿的比我還像新娘宦搬。我一直安慰自己,他們只是感情好劫拗,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開白布间校。 她就那樣靜靜地躺著,像睡著了一般页慷。 火紅的嫁衣襯著肌膚如雪憔足。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天酒繁,我揣著相機(jī)與錄音四瘫,去河邊找鬼。 笑死欲逃,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的饼暑。 我是一名探鬼主播稳析,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼弓叛!你這毒婦竟也來(lái)了彰居?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤撰筷,失蹤者是張志新(化名)和其女友劉穎陈惰,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體毕籽,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡抬闯,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年井辆,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片溶握。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡杯缺,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出睡榆,到底是詐尸還是另有隱情萍肆,我是刑警寧澤,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布胀屿,位于F島的核電站塘揣,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏宿崭。R本人自食惡果不足惜亲铡,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望劳曹。 院中可真熱鬧奴愉,春花似錦、人聲如沸铁孵。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)蜕劝。三九已至檀头,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間岖沛,已是汗流浹背暑始。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留婴削,地道東北人廊镜。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像唉俗,于是被迫代替她去往敵國(guó)和親嗤朴。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容