iOS屏幕旋轉(zhuǎn)

一秸抚、UIDeviceOrientation 與 UIInterfaceOrientation的區(qū)別

UIDeviceOrientation 是機(jī)器硬件的當(dāng)前旋轉(zhuǎn)方向速和,這個(gè)枚舉只能取值,不能手動(dòng)設(shè)置剥汤,通過(guò)UIDeviceOrientationDidChangeNotification可以監(jiān)聽(tīng)其方向的改變颠放。網(wǎng)上有屌絲用以下方式進(jìn)行修改,在這里不建議這樣做

NSNumber *value = [NSNumber numberWithInt:UIDeviceOrientationPortrait];
[[UIDevice currentDevice] setValue:value forKey:@"orientation"];

UIDeviceOrientation枚舉值如下:

typedef NS_ENUM(NSInteger, UIDeviceOrientation) {
    UIDeviceOrientationUnknown,
    UIDeviceOrientationPortrait,            // Device oriented vertically, home button on the bottom
    UIDeviceOrientationPortraitUpsideDown,  // Device oriented vertically, home button on the top
    UIDeviceOrientationLandscapeLeft,       // Device oriented horizontally, home button on the right
    UIDeviceOrientationLandscapeRight,      // Device oriented horizontally, home button on the left
    UIDeviceOrientationFaceUp,              // Device oriented flat, face up
    UIDeviceOrientationFaceDown             // Device oriented flat, face down
}

UIInterfaceOrientation 是程序界面當(dāng)前旋轉(zhuǎn)方向吭敢,通過(guò)UIApplicationDidChangeStatusBarOrientationNotification可以監(jiān)聽(tīng)到即界面的布局方向發(fā)生了改變碰凶。(只有布局改變了才能收到通知)并且這個(gè)枚舉是可以手動(dòng)設(shè)置的。(可以理解為屏幕相對(duì)的home鍵方向)

UIInterfaceOrientation枚舉值如下:

// Note that UIInterfaceOrientationLandscapeLeft is equal to UIDeviceOrientationLandscapeRight (and vice versa).
// This is because rotating the device to the left requires rotating the content to the right.
typedef NS_ENUM(NSInteger, UIInterfaceOrientation) {
    UIInterfaceOrientationUnknown            = UIDeviceOrientationUnknown,
    UIInterfaceOrientationPortrait           = UIDeviceOrientationPortrait,
    UIInterfaceOrientationPortraitUpsideDown = UIDeviceOrientationPortraitUpsideDown,
    UIInterfaceOrientationLandscapeLeft      = UIDeviceOrientationLandscapeRight,
    UIInterfaceOrientationLandscapeRight     = UIDeviceOrientationLandscapeLeft
}

二、如果你的App不支持屏幕旋轉(zhuǎn)欲低,有以下兩種方式處理

  1. 設(shè)置AppDelegate里的一下方法辕宏,返回值即為屏幕固定方向
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
    return UIInterfaceOrientationMaskLandscapeRight;
}
  1. General-Deployment Info-Device Orientation對(duì)支持的方向進(jìn)行勾選

兩種方式都可以觸發(fā)UIDeviceOrientationDidChangeNotification通知

三、如果你的App需要屏幕自適應(yīng)重力感應(yīng)進(jìn)行旋轉(zhuǎn)砾莱,并且需要針對(duì)每個(gè)VC進(jìn)行單獨(dú)控制

當(dāng)然這種情況你完全可以手動(dòng)地對(duì)每個(gè)控制器的view布局匾效,在監(jiān)聽(tīng)到UIDeviceOrientationDidChangeNotification通知后做旋轉(zhuǎn)處理。一兩個(gè)界面還好恤磷,如果控制多的話(huà)面哼,還是需要按一下方式處理

  • General-Deployment Info-Device Orientation勾選所有支持的方向,代碼設(shè)置的支持旋轉(zhuǎn)方向都會(huì)在此基礎(chǔ)上
  • 對(duì)項(xiàng)目中導(dǎo)航控制器的父控制器增加方法扫步,所有想說(shuō)的都在代碼里
// 是否支持屏幕旋轉(zhuǎn)
- (BOOL)shouldAutorotate
{
    return self.topViewController.shouldAutorotate;
}

/**
 適用于Push進(jìn)去的子類(lèi)調(diào)用

 @return 屏幕支持的旋轉(zhuǎn)方向
 */
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
    return self.topViewController.supportedInterfaceOrientations;
}


/**
 適用于modal進(jìn)去的子類(lèi)調(diào)用

 @return 屏幕支持的旋轉(zhuǎn)方向
 */
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return self.topViewController.preferredInterfaceOrientationForPresentation;
}
  • 在push的控制器中魔策,如果想關(guān)閉屏幕旋轉(zhuǎn),做如下操作
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
    return (toInterfaceOrientation == UIInterfaceOrientationPortrait);
}

// 設(shè)置屏幕旋轉(zhuǎn)方向
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait;
}

// 設(shè)置是否支持屏幕旋轉(zhuǎn)
-(BOOL)shouldAutorotate
{
    return NO;
}
  • 如果想在另一個(gè)push的控制器再開(kāi)啟屏幕旋轉(zhuǎn)
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
    return (toInterfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}

// 設(shè)置屏幕旋轉(zhuǎn)方向
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskAllButUpsideDown;
}

// 設(shè)置是否支持屏幕旋轉(zhuǎn)
-(BOOL)shouldAutorotate
{
    return YES;
}
  • 如果想在modal的控制器中河胎,關(guān)閉屏幕旋轉(zhuǎn)
// 設(shè)置屏幕是否支持旋轉(zhuǎn)
- (BOOL)shouldAutorotate
{
    return NO;
}

// 設(shè)置屏幕方向
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return UIInterfaceOrientationLandscapeLeft;
}

四闯袒、遇到的問(wèn)題

自己寫(xiě)了一個(gè)視頻錄制的控制器,本來(lái)是通過(guò)UIDeviceOrientationDidChangeNotification監(jiān)聽(tīng)手機(jī)旋轉(zhuǎn)方向來(lái)對(duì)視頻方向進(jìn)行調(diào)整游岳,實(shí)現(xiàn)視頻的橫豎屏錄制(視頻的方向枚舉AVCaptureVideoOrientation,有興趣的童鞋可以了解下)

typedef NS_ENUM(NSInteger, AVCaptureVideoOrientation) {
    AVCaptureVideoOrientationPortrait           = 1,
    AVCaptureVideoOrientationPortraitUpsideDown = 2,
    AVCaptureVideoOrientationLandscapeRight     = 3,
    AVCaptureVideoOrientationLandscapeLeft      = 4,
}

但是如果系統(tǒng)禁止了屏幕旋轉(zhuǎn)功能政敢,通知就監(jiān)聽(tīng)不到旋轉(zhuǎn)了,原因是因?yàn)榇藭r(shí)系統(tǒng)會(huì)默認(rèn)你當(dāng)前的屏幕狀態(tài)一直都是你鎖屏?xí)r的狀態(tài)胚迫。

解決方法

目前大多數(shù)用戶(hù)的蘋(píng)果手機(jī)基本都有螺旋儀和加速器喷户,可以根據(jù)這個(gè)東西來(lái)判斷,這時(shí)候需要引入CoreMotion.framework這個(gè)框架访锻。

  1. 初始化一個(gè)螺旋儀對(duì)象
// 系統(tǒng)禁止屏幕旋轉(zhuǎn)后褪尝,可以監(jiān)聽(tīng)到屏幕方向
// 螺旋儀
@property (nonatomic, strong) CMMotionManager *motionManager;
- (void)initialMotionManager
{
    if (_motionManager == nil)
    {
        _motionManager = [[CMMotionManager alloc] init];
    }
    // 提供設(shè)備運(yùn)動(dòng)數(shù)據(jù)到指定的時(shí)間間隔(輪詢(xún)間隔)
    _motionManager.deviceMotionUpdateInterval = 0.3;
    // 確定"是否使用任何可用的態(tài)度參考幀來(lái)決定設(shè)備的運(yùn)動(dòng)"是否可用?
    if (_motionManager.deviceMotionAvailable)
    {
        // 啟動(dòng)設(shè)備的運(yùn)動(dòng)更新,通過(guò)給定的隊(duì)列向給定的處理程序提供數(shù)據(jù)
        [_motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMDeviceMotion * _Nullable motion, NSError * _Nullable error) {
           
            // 調(diào)用處理函數(shù)
            [self performSelectorOnMainThread:@selector(handleDeviceMotion:) withObject:motion waitUntilDone:YES];
        }];
    } else {
        self.motionManager = nil;
    }
}
  1. 根據(jù)重力感應(yīng)來(lái)判斷目前屏幕方向并可以做對(duì)應(yīng)處理
- (void)handleDeviceMotion:(CMDeviceMotion *)deviceMotion
{
    double x = deviceMotion.gravity.x;
    double y = deviceMotion.gravity.y;
    // 豎屏
    if (fabs(y) >= fabs(x))
    {
        // 這個(gè)地方注意
//        if (y >= 0)
//        {
//            // UIDeviceOrientationPortraitUpsideDown;
//        } else {
//            // UIDeviceOrientationPortrait;
//        }
        self.recordOrientation = UIDeviceOrientationPortrait;
    } else {
        if (x >= 0)
        {
            self.recordOrientation = UIDeviceOrientationLandscapeRight;
        } else {
            self.recordOrientation = UIDeviceOrientationLandscapeLeft;
        }
    }
}

這里因?yàn)槲冶旧淼捻?xiàng)目需求期犬,只是全局記錄下了屏幕當(dāng)前方向河哑,然后KVO監(jiān)聽(tīng)recordOrientation,再對(duì)視頻錄制寫(xiě)入方向進(jìn)行處理龟虎。

  1. 注意一定要在控制器消失前璃谨,關(guān)閉輪詢(xún)。否則會(huì)造成內(nèi)存泄漏
// 關(guān)閉螺旋儀
    [self.motionManager stopDeviceMotionUpdates];

至此鲤妥,所有我要說(shuō)的都表達(dá)完了佳吞。碼農(nóng)共勉!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末旭斥,一起剝皮案震驚了整個(gè)濱河市容达,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌垂券,老刑警劉巖花盐,帶你破解...
    沈念sama閱讀 217,826評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件羡滑,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡算芯,警方通過(guò)查閱死者的電腦和手機(jī)柒昏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)熙揍,“玉大人职祷,你說(shuō)我怎么就攤上這事〗烨簦” “怎么了有梆?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,234評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀(guān)的道長(zhǎng)意系。 經(jīng)常有香客問(wèn)我泥耀,道長(zhǎng),這世上最難降的妖魔是什么蛔添? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,562評(píng)論 1 293
  • 正文 為了忘掉前任痰催,我火速辦了婚禮,結(jié)果婚禮上迎瞧,老公的妹妹穿的比我還像新娘夸溶。我一直安慰自己,他們只是感情好凶硅,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,611評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布缝裁。 她就那樣靜靜地躺著,像睡著了一般咏尝。 火紅的嫁衣襯著肌膚如雪压语。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,482評(píng)論 1 302
  • 那天编检,我揣著相機(jī)與錄音,去河邊找鬼扰才。 笑死允懂,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的衩匣。 我是一名探鬼主播蕾总,決...
    沈念sama閱讀 40,271評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼琅捏!你這毒婦竟也來(lái)了生百?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,166評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤柄延,失蹤者是張志新(化名)和其女友劉穎蚀浆,沒(méi)想到半個(gè)月后缀程,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,608評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡市俊,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,814評(píng)論 3 336
  • 正文 我和宋清朗相戀三年杨凑,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片摆昧。...
    茶點(diǎn)故事閱讀 39,926評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡撩满,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出绅你,到底是詐尸還是另有隱情伺帘,我是刑警寧澤,帶...
    沈念sama閱讀 35,644評(píng)論 5 346
  • 正文 年R本政府宣布忌锯,位于F島的核電站伪嫁,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏汉规。R本人自食惡果不足惜礼殊,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,249評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望针史。 院中可真熱鬧晶伦,春花似錦、人聲如沸啄枕。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,866評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)频祝。三九已至泌参,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間常空,已是汗流浹背沽一。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,991評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留漓糙,地道東北人铣缠。 一個(gè)月前我還...
    沈念sama閱讀 48,063評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像昆禽,于是被迫代替她去往敵國(guó)和親蝗蛙。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,871評(píng)論 2 354

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