UI篇-關於單個頁面螢幕旋轉要注意的問題
前言
有時候,我們會需要在整個專案中,使某一個ViewController支援螢幕旋轉,而其他的ViewController並不能自動旋轉。這是一個很常見的需求,下面就螢幕旋轉相關問題做個小結。
強制頁面旋轉(假的螢幕旋轉)
最多見的是,視屏播放中的橫屏模式,點選全屏按鈕,播放頁面橫屏最大化。使用
CGAffineTransformMakeRotation旋轉操作配合動畫即可。
-(void)fullScreenClick: (UIButton *)btn {
btn.selected = !btn.selected;
if (btn.selected) {
self.mySuperView = self.superview;
[UIView animateWithDuration:0.3 animations:^{
[[UIApplication sharedApplication].keyWindow addSubview:self];
self.transform = CGAffineTransformMakeRotation(M_PI / 2);
} completion:nil];
self.frame = self.bigFrame;
}else {
[self removeFromSuperview];
[self.mySuperView addSubview:self];
[UIView animateWithDuration:0.3 animations:^{
self.transform = CGAffineTransformMakeRotation(M_PI * 2);
} completion:nil];
self.frame = self.smallFrame;
}
}
強制帶有導航條的整個頁面旋轉
- (void)changeScreent :(BOOL)toRight
{
CGFloat duration = [UIApplication sharedApplication].statusBarOrientationAnimationDuration;
[UIView animateWithDuration:duration animations:^{
// 修改狀態列的方向及view的方向進而強制旋轉螢幕
[[UIApplication sharedApplication] setStatusBarHidden:toRight];
self.navigationController.view.transform = toRight?CGAffineTransformMakeRotation(M_PI_2): CGAffineTransformIdentity;
if (toRight) {
self.navigationController.view.bounds = CGRectMake(self.navigationController.view.bounds.origin.x, self.navigationController.view.bounds.origin.y, [UIScreen mainScreen].bounds.size.height, [UIScreen mainScreen].bounds.size.width);
}else{
self.navigationController.view.bounds = CGRectMake(self.navigationController.view.bounds.origin.x, self.navigationController.view.bounds.origin.y, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);
}
}];
}
注意狀態列無法強制旋轉,在手機方向不變的情況下,所以,最好把狀態列隱藏掉,回覆的時候再顯示出來。不可使用self.view.frame.size.width self.view.frame.size.height,這樣會出現第一次旋轉出現上下部分白邊的Bug,需要使用 [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height。
自動螢幕旋轉
系統支援橫屏的順序
系統支援橫屏順序為以下幾種,前面的會使後面的方法失效,優先順序依次降低。
- 預設讀取plist裡面設定的方向(優先順序最高)等同於Xcode Geneal設定裡面勾選
-
application window設定的級別次之
application支援所有 - (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window { return UIInterfaceOrientationMaskAll;//支援所有方向 }
-
UINavigationcontroller裡設定
- (BOOL)shouldAutorotate//是否支援旋轉螢幕{ return YES; } - (NSUInteger)supportedInterfaceOrientations//支援哪些方向{ return UIInterfaceOrientationMaskPortrait; }
級別最低的是viewcontroller裡的設定
如何實現某一個頁面螢幕旋轉,而其他頁面不旋轉
首先, - (BOOL)shouldAutorotate 必須在 self.window.rootViewController 中才能有效果,而且每當手機發生旋轉時,就會掉用 rootViewController 的 - (BOOL)shouldAutorotate 方法。
首先我們要保證工程設定為未勾選的狀態才行。
一般我們的rootViewController 都是UINavigationcontroller ,所有我們在UINavigationcontroller中設定如下方法
#獲取棧最頂端的controller對旋轉的支援狀態即可,
#然後在每一個VC中都要設定 - (BOOL)shouldAutorotate 來確定當前的VC是否支援橫豎屏
# 如果支援,還需要設定 - (NSUInteger)supportedInterfaceOrientations//支援哪些方向
- (BOOL)shouldAutorotate
{
return self.topViewController.shouldAutorotate;
}
如果rootViewController 都是 tarBarController ,所有我們在tarBarController中設定如下方法
- (BOOL)shouldAutorotate{
return self.selectedViewController.shouldAutorotate;
}
這樣的情況下,每個VC都是預設支援旋轉的,那麼我們需要在每個VC中都設定- (BOOL)shouldAutorotate嗎?答案是否定的。我們可以建立一個controller的基類BaseViewController每個controller都繼承BaseViewController ,在BaseViewController中重寫- (BOOL)shouldAutorotate 方法中 return NO; 預設關閉,,在需要開啟的子類中再次重寫- (BOOL)shouldAutorotate 方法,在方法中return YES即可。
下面是一個支援旋轉螢幕VC的程式碼
- (BOOL)shouldAutorotate
{
return YES;
}
# 點選全屏
- (IBAction)large:(id)sender
{
NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft];
[[UIDevice currentDevice] setValue:value forKey:@"orientation"];
}
# 全屏返回
- (IBAction)largeBack:(id)sender
{
NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationPortrait];
[[UIDevice currentDevice] setValue:value forKey:@"orientation"];
}
# 在這個方法中設定螢幕旋轉時的 頁面設定。
- (void)willRotateToInterfaceOrientation: (UIInterfaceOrientation)toInterfaceOrientation
duration:(NSTimeInterval)duration
{
self.navigationController.navigationBarHidden = NO;
self.toolBar.hidden = NO;
self.largeBackButton.hidden = YES;
self.bottomView.hidden = NO;
self.largeTitleLabel.hidden = YES;
self.localRecrodContraint.constant = 10;
if(toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft ||
toInterfaceOrientation == UIInterfaceOrientationLandscapeRight)
{
self.navigationController.navigationBarHidden = YES;
self.localRecrodContraint.constant = 50;
self.toolBar.hidden = YES;
self.largeTitleLabel.hidden = NO;
self.largeBackButton.hidden = NO;
self.bottomView.hidden = YES;
}
}
******************更新****************
上面的方法完美解決了我一個工程的單頁面螢幕旋轉問題,可是在另一個工程中,上面的方法確出現了一個Bug,真的很蛋疼。
按照上面的方法我確實達到了,單頁面旋轉,其他頁面不旋轉的效果,但是有個問題: 在頁面不旋轉的情況下,狀態列確會隨著手機的旋轉而旋轉,著實蛋疼。目前不清楚為什麼一樣的設定,在兩個專案中效果不一樣。
解決方法:
# AppDelegate 中
@property (strong, nonatomic) MyNavigationController* nav;
//手機方向發生變化時就會掉用
手機方向不發生變化時就不會掉用
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
return self.nav.topViewController.supportedInterfaceOrientations;//支援所有方向
}
# MyNavigationController中
- (BOOL)shouldAutorotate
{
return self.topViewController.shouldAutorotate;
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
return self.topViewController.supportedInterfaceOrientations;
}
# BaseViewController中
- (BOOL)shouldAutorotate
{
return NO;
}
//不設定的話,雖然頁面是沒有旋轉,但是狀態列會隨著手機旋轉而旋轉。
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
#需要旋轉的VC中
- (BOOL)shouldAutorotate
{
return YES;
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAllButUpsideDown;
}
可見,狀態列的方向跟頁面支援的方向是一樣的。所以頁面支援的方向是一定要設定的,不設定的話就是預設的:左中右。
螢幕旋轉中的其它問題
-
如何應用程式剛啟動時判斷裝置方向呢?之前說的那些都是都是在rootViewController之後去判斷的,但是,在程式剛剛啟動時做這些判斷都是無效的。下面是網上的一個方法(未驗證),在didFinishLaunchingWithOptions函式中:
//註冊通知 UIDevice *device = [UIDevice currentDevice]; [device beginGeneratingDeviceOrientationNotifications]; [[NSNotificationCenterdefaultCenter] addObserver: self selector: @selector(deviceOrientationDidChangeAction:) name: UIDeviceOrientationDidChangeNotification object: nil]; [device endGeneratingDeviceOrientationNotifications]; //轉屏處理函式: - (void) deviceOrientationDidChangeAction:(NSNotification *)note { NSInteger currentOrientation = [[note object] orientation]; switch (currentOrientation) { case0: { //未知方向 break; } case1: { //home鍵向下 break; } case2: { //home鍵向上 break; } case3: { //home鍵向左 break; } case4: { //home鍵向右 break; } default: break; } } 還要在恰當的時候移除通知 不然會被反覆呼叫: [[NSNotificationCenterdefaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil];
-
螢幕旋轉時,狀態列會預設隱藏的,如何顯示出來
//iOS8 橫屏的時候系統預設隱藏了 [UIApplication sharedApplication].statusBarHidden = YES; [UIApplication sharedApplication].statusBarHidden = NO; # 請注意,上面的倆條一條都不可以少,而且也不可以顛倒順序。我看著也醉了。但是卻是有作用。
小結
關於螢幕旋轉的問題,目前先寫這些,後續如果有新的東西收穫,會更新上去的。
相關文章
- Swift橫豎屏切換、自動旋轉螢幕、手動旋轉螢幕、鎖定當前螢幕禁止轉屏、橫豎屏頁面跳轉過度、橫豎屏UI適配SwiftUI
- ubuntu螢幕旋轉Ubuntu
- orientationchange 螢幕旋轉事件事件
- 關於在頁面中解決列印的幾個問題 (轉)
- 螢幕旋轉的適配問題以及遇到的一些坑
- Android 禁止螢幕旋轉Android
- mui 控制旋轉螢幕方向UI
- 關於RF對於不在螢幕內的頁面元素的處理辦法
- iOS螢幕旋轉解決方案iOS
- 360奇酷手機自動旋轉螢幕怎麼關閉 360奇酷手機自動旋轉螢幕關閉教程
- 【求助】關於響應式設計螢幕解析度和螢幕尺寸的問題
- 關於螢幕程式設計(轉)程式設計
- 判斷螢幕旋轉的事件程式碼事件
- 樂1s自動旋轉螢幕怎麼關閉 樂視超級手機1s自動旋轉螢幕關閉教程
- 關於頁面中彈窗的定位問題
- iOS感測器:實現一個隨螢幕旋轉的圖片iOS
- 關於離開頁面時執行的操作問題
- ios一句程式碼搞定螢幕旋轉iOS
- IBM筆記本螢幕旋轉解決IBM筆記
- js頁面跳轉的問題(跳轉到父頁面、最外層頁面、本頁面)JS
- iOS開發 詳解強制螢幕旋轉的方法iOS
- 關於如何寫UI及螢幕適配的一些技巧(上)UI
- 關於如何寫UI及螢幕適配的一些技巧(下)UI
- 關於兩個簡單問題的分析
- WPF --- 觸控式螢幕下的兩個問題
- 關於angularjs中路由頁面強制更新的問題AngularJS路由
- 關於微信 H5 頁面切換 webview 的問題H5WebView
- 請問一下關於socket跟頁面請求的問題
- js判斷螢幕是否旋轉程式碼例項JS
- 小程式視訊旋轉的相關問題
- 如何解決開啟網頁螢幕不停閃爍的問題網頁
- 關於 Laravel 分頁的問題?Laravel
- android螢幕適配的問題Android
- Win10系統下怎麼禁止螢幕旋轉Win10
- iOS螢幕旋轉之Apple Document(蘋果文件翻譯)iOSAPP蘋果
- 問一個關於oracle8的簡單的問題!Oracle
- 關於Kerberos安裝的幾個問題(轉)ROS
- 新手問個關於找不到tcltk庫的問題(轉)