記錄於2013/8/5
在切換橫豎屏的時候調用到的一些委託方法:
#pragma mark - UIApplicationDelegate
//寫在Appdelegate中,在具體的某一視圖控制器沒有重寫supportedInterfaceOrientations或者shouldAutorotateToInterfaceOrientation的狀況下指定該視圖的支持方向;若是該方法沒有實現,則應用程序使用Info.plist文件中默認設置的值
- (NSUInteger)application:(UIApplication*)application supportedInterfaceOrientationsForWindow:(UIWindow*)window{
//返回UIInterfaceOrientationMask類型數據 ,能夠找到具體某一個視圖控制器加以控制
return UIInterfaceOrientationMaskPortrait;
}
#pragma mark - UIViewController
//>=ios6.0
// 是否自動旋轉方向 設置爲NO時其實就不會旋轉了
- (BOOL)shouldAutorotateNS_AVAILABLE_IOS(6_0);
// 返回該視圖控制器支持的方向,返回UIInterfaceOrientationMaskPortrait類型數據
- (NSUInteger)supportedInterfaceOrientations NS_AVAILABLE_IOS(6_0);
// 在使用presentViewController時調用該方法,只能返回一個數值,其餘設置對該界面沒有影響,不過在該界面前兩個方法就不要調用了
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{
returnUIInterfaceOrientationLandscapeRight;
}
//<=ios5
// 在ios6以後已遺棄,不過適配ios5以前的版本時須要加上
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation NS_DEPRECATED_IOS(2_0, 6_0);
若是支持橫豎屏則須要重繪視圖:
寫一個排版的函數,注意須要在
viewwillappear、 supportedInterfaceOrientations 、willAnimateRotationToInterfaceOrientation三處都要重排一下
ios6中須要指定某一個界面爲橫豎屏,其餘界面與之不一樣,如今試驗得出如下方法暫時可能,還沒找到會出問題
對於iOS6, 因爲是由top-most controller來設置orientation [self topViewController]就是指向當前頁面的視圖控制器
1、當主控制器爲UINavigationController時,繼承重寫UINavigationController,在其.m文件中編寫以下代碼,表示某個具體類支持的方向
有兩種方法:
一、只在UINavigationController繼承的子類中設置方向,其餘頁面都不須要設置 (這裏的方法只有在頁面初始化和旋轉的時候纔會調用到)
-(NSUInteger)supportedInterfaceOrientations{
if([[self topViewController] isKindOfClass:[ThirdViewController class]])
return UIInterfaceOrientationMaskAllButUpsideDown;
return UIInterfaceOrientationMaskPortrait;
}
- (BOOL)shouldAutorotate{
return YES;
}
二、下面代碼寫在UINavigationController繼承的子類中, 同時還要在對應的頁面重寫這些代碼(默認是支持除倒置意外的全部方向)
-(NSUInteger)supportedInterfaceOrientations{
//返回頂層視圖支持的旋轉方向
return self.topViewController.supportedInterfaceOrientations;
}
- (BOOL)shouldAutorotate{
//返回頂層視圖的設置
return self.topViewController.shouldAutorotate;
}
三、其實有時候也能夠將以上兩個結合起來使用,指定某些頁面調用第二種方法,並在那個頁面中重寫。 其餘的設置返回某一中類型。
注意:須要在.plist文件中配置全部支持的方向,且在AppDelegate和其餘界面不要編寫控制轉向的代碼。 AppDelegate中寫了有出錯,其餘界面還沒發現,不過暫時以爲最好仍是不要編寫。
可是上面的方法有個很差的地方是:這樣可使得在main view and sub view裏沒法打橫,而sub sub view橫豎都行。但問題來了,若是在sub sub view時打橫,而後back to sub view,那麼sub view是打橫顯示的!
目前想到的解決方法只能是把sub sub view脫離nav controller,以modal view方式來顯示。這樣就能夠在modal view裏設置打橫打豎,而在nav controller裏設置只打豎。
如今找到的方法是在sub view 頁面上頁加上
-(NSUInteger)supportedInterfaceOrientations{(當前視圖支持的方向)
returnUIInterfaceOrientationMaskPortrait;
}
同時presentViewController方法是不受NavigationController控制的
或者採起如下方法來加載頁面,就能夠在該頁面設置轉向代碼。 已脫離UINavgationController
- (void)presentViewController:(UIViewController *)viewControllerToPresent animated: (BOOL)flag completion:(void (^)(void))completion
UIViewController的shouldAutorotateToInterfaceOrientation方法被deprecated。在ios6裏,是使用supportedInterfaceOrientations and shouldAutorotate 2個方法來代替shouldAutorotateToInterfaceOrientation。注意:爲了向後兼容iOS 4 and 5,仍是須要在你的app裏保留shouldAutorotateToInterfaceOrientation。
for ios 4 and 5, 若是沒有重寫shouldAutorotateToInterfaceOrientation,那麼對於iphone來說,by default是隻支持portrait,不能旋轉。
for ios 6, 若是沒有重寫shouldAutorotate and supportedInterfaceOrientations,by default, iphone則是"能夠旋轉,支持非upside down的方向",而ipad是"能夠選擇,支持全部方向"
example 1: for ios 4 and 5, iphone device, 若要"能夠旋轉,支持非upside down的方向",則能夠在view controller裏
[cpp]
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation != UIDeviceOrientationPortraitUpsideDown);
}
example 2: for ios 6, iphone device, 若要「不能旋轉,只支持portait",則能夠在view controller裏
[cpp]
- (BOOL)shouldAutorotate
{
return NO;
}
example 3: for ios 6, ipad device, 若要「能夠旋轉,只支持landscape",則能夠在view controller裏
[cpp]
-(NSUInteger)supportedInterfaceOrientations{
爀攀琀甀爀渀 UIInterfaceOrientationMaskLandscape;
}
- (BOOL)shouldAutorotate
{
return YES;
}
* 在iOS 4 and 5,都是由具體的view controller來決定對應的view的orientation設置。而在iOS 6,則是由top-most決定view的orientation設置。
舉個例子:你的app的rootViewController是navigation controller "nav", 在」nav"裏的stack依次是:main view -> sub view > sub sub view,而main view裏有一個button會present modal view "modal view".
那麼for ios 4 and 5,在ipad裏,若是你要上述view都僅支持橫屏orientation,你須要在上面的main view, sub view, sub sub view, model view裏都添加
[cpp]
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation==UIInterfaceOrientationLandscapeRight);
}
而對於iOS6, 因爲是由top-most controller來設置orientation,所以你在main view, sub view, sub sub view裏添加下面的代碼是沒有任何效果的,而應該是在nav controller裏添加下列代碼。而modal view則不是在nav container裏,所以你也須要在modal view裏也添加下列代碼。
[cpp]
-(NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskLandscape;
}
- (BOOL)shouldAutorotate
{
return YES;
}
注意:
*你須要自定義一個UINavigationController的子類for "nav controller",這樣才能夠添加上述代碼。
* 和navigation controller相似,tab controller裏的各個view的orientation設置應該放在tab controller裏
for ios6的top-most controller決定orientation設置,致使這樣一個問題:在 top-most controller裏的views沒法擁有不相同的orientation設置。例如:for iphone, 在nav controller裏,你有main view, sub view and sub sub view,前2個都只能打豎,而sub sub view是用來播放video,能夠打橫打豎。那麼在ios 4 and 5裏能夠經過在main view and sub view的shouldAutorotateToInterfaceOrientation裏設置只能打豎,而在sub sub view的shouldAutorotateToInterfaceOrientation設置打豎打橫便可。而在ios 6裏則沒法實現這種效果,由於在main view, sub view and sub sub view的orientation設置是無效的,只可以在nav controller裏設置。那麼你可能想着用下列代碼在nav controller裏控制哪一個view打豎,哪一個view打橫
[cpp]
-(NSUInteger)supportedInterfaceOrientations{
if([[self topViewController] isKindOfClass:[SubSubView class]])
return UIInterfaceOrientationMaskAllButUpsideDown;
else
return UIInterfaceOrientationMaskPortrait;
}
是的,這樣可使得在main view and sub view裏沒法打橫,而sub sub view橫豎都行。但問題來了,若是在sub sub view時打橫,而後back to sub view,那麼sub view是打橫顯示的!
目前想到的解決方法只能是把sub sub view脫離nav controller,以modal view方式來顯示。這樣就能夠在modal view裏設置打橫打豎,而在nav controller裏設置只打豎。
* 說了那麼多,其實若是你的app的全部view的orientation的設置是統一的,那麼你能夠簡單的在plist file裏設置便可,不用添加上面的代碼。而若是你添加了上面的代碼,就會覆蓋plist裏orientation的設置。
* in iOS 6, 當view controller present時,不會call willRotateToInterfaceOrientation:duration:, willAnimateRotationToInterfaceOrientation:duration:, and didRotateFromInterfaceOrientation: methods,只有在發生rotate的時候纔會call
有的是本身的root controller,試一下
//[self.window addSubview:myRootViewConroller.view]; 替換成下面的狀況
// Begin 6.0
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 6.0) {
self.window.rootViewController = myRootViewConroller;
}
else
{
[self.window addSubview:myRootViewConroller.view];
}
// End 6.0