ShouldAutorotateToInterfaceOrientation
はiOS 6で非推奨になり、特定のビューをポートレートのみに強制するために使用しましたが、iOS 6でこれを行う正しい方法は何ですか?これはアプリの1つの領域のみで、他のすべてのビューは回転できます。
すべてのNavigation Controllerがトップビューコントローラーを尊重するようにしたい場合は、カテゴリーを使用して、クラス名を変更する必要がありません。
@implementation UINavigationController (Rotation_IOS6)
-(BOOL)shouldAutorotate
{
return [[self.viewControllers lastObject] shouldAutorotate];
}
-(NSUInteger)supportedInterfaceOrientations
{
return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}
@end
いくつかのコメントが指摘しているように、これは問題の簡単な修正です。より良い解決策は、サブクラスUINavigationControllerであり、これらのメソッドをそこに配置します。サブクラスは、6と7のサポートにも役立ちます。
IOS6の最適な方法は、レイウェンダリッヒチームによる「チュートリアルによるiOS6」に具体的に記載されています- http://www.raywenderlich.com/ ほとんどの場合、UINavigationController
をサブクラス化するよりも優れています。
初期ビューコントローラーとしてUINavigationController
セットを含むストーリーボードでiOS6を使用しています。
//AppDelegate.m-このメソッドは、残念ながらiOS6以前では使用できません
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
NSUInteger orientations = UIInterfaceOrientationMaskAllButUpsideDown;
if(self.window.rootViewController){
UIViewController *presentedViewController = [[(UINavigationController *)self.window.rootViewController viewControllers] lastObject];
orientations = [presentedViewController supportedInterfaceOrientations];
}
return orientations;
}
//MyViewController.m-各UIViewController
に対してサポートしたい方向を返します
- (NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortrait;
}
この回答は、OPの投稿のコメントで尋ねられた質問に関連しています。
ビューを強制的に特定の方向に表示するには、viewWillAppearに次のように入力します。
UIApplication* application = [UIApplication sharedApplication];
if (application.statusBarOrientation != UIInterfaceOrientationPortrait)
{
UIViewController *c = [[UIViewController alloc]init];
[self presentModalViewController:c animated:NO];
[self dismissModalViewControllerAnimated:NO];
}
ちょっとしたハックですが、これにより、前のコントローラーが横長であったとしても、UIViewController
がポートレートで表示されます。
iOS7の更新
上記のメソッドは非推奨になったため、iOS 7では次を使用します。
UIApplication* application = [UIApplication sharedApplication];
if (application.statusBarOrientation != UIInterfaceOrientationPortrait)
{
UIViewController *c = [[UIViewController alloc]init];
[c.view setBackgroundColor:[UIColor redColor]];
[self.navigationController presentViewController:c animated:NO completion:^{
[self.navigationController dismissViewControllerAnimated:YES completion:^{
}];
}];
}
興味深いことに、執筆時点では、eitherpresentまたはdismissをアニメーション化する必要があります。どちらでもない場合は、白い画面が表示されます。なぜこれが機能するのかわかりませんが、機能します!視覚効果は、アニメーション化されるものによって異なります。
そのため、ポートレートのみのモーダルビューを表示すると、同じ問題が発生しました。通常、UINavigationController
を作成し、viewController
をrootViewController
として設定し、UINavigationController
をモーダルビューとして表示します。しかし、iOS 6では、viewController
は、navigationControllerにサポートされているインターフェイスの向きを要求するようになりました(デフォルトでは、iPadのすべてで、iPhoneの場合は上下逆になっています)。
ソリューション:UINavigationController
をサブクラス化し、自動回転メソッドをオーバーライドする必要がありました。ラメの種類。
- (BOOL)shouldAutorotate {
return NO;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
// pre-iOS 6 support
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
return (toInterfaceOrientation == UIInterfaceOrientationPortrait);
}
IOS 5
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
IOS 6
-(BOOL)shouldAutorotate{
return YES;
}
-(NSInteger)supportedInterfaceOrientations{
// UIInterfaceOrientationMaskLandscape;
// 24
//
// UIInterfaceOrientationMaskLandscapeLeft;
// 16
//
// UIInterfaceOrientationMaskLandscapeRight;
// 8
//
// UIInterfaceOrientationMaskPortrait;
// 2
// return UIInterfaceOrientationMaskPortrait;
// or
return 2;
}
UIViewControllerの回転メソッドはカテゴリ自体で宣言されているため、別のカテゴリでオーバーライドすると未定義の動作が発生するため、@ apratoの回答には同意しません。 UINavigationController(またはUITabBarController)サブクラスでオーバーライドする方が安全です
また、これは、横向きビューから縦向きのみVCまたはその逆にプッシュ/プレゼン/ポップするシナリオをカバーしません。この困難な問題を解決するには(Appleが決して対処しません)、次のことを行う必要があります。
iOS <= 4およびiOS> = 6:の場合
UIViewController *vc = [[UIViewController alloc]init];
[self presentModalViewController:vc animated:NO];
[self dismissModalViewControllerAnimated:NO];
[vc release];
iOS 5の場合
UIWindow *window = [[UIApplication sharedApplication] keyWindow];
UIView *view = [window.subviews objectAtIndex:0];
[view removeFromSuperview];
[window addSubview:view];
これらは本当に、すべてのshouldAutorotate、supportedInterfaceOrientationsなどをUIKitに再評価させます。
https://stackoverflow.com/a/13982508/2516436 と https://stackoverflow.com/a/17578272/2516436 を組み合わせた非常に良いアプローチがあります
-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
NSUInteger orientations = UIInterfaceOrientationMaskAllButUpsideDown;
if(self.window.rootViewController){
UIViewController *presentedViewController = [self topViewControllerWithRootViewController:self.window.rootViewController];
orientations = [presentedViewController supportedInterfaceOrientations];
}
return orientations;
}
- (UIViewController*)topViewControllerWithRootViewController:(UIViewController*)rootViewController {
if ([rootViewController isKindOfClass:[UITabBarController class]]) {
UITabBarController* tabBarController = (UITabBarController*)rootViewController;
return [self topViewControllerWithRootViewController:tabBarController.selectedViewController];
} else if ([rootViewController isKindOfClass:[UINavigationController class]]) {
UINavigationController* navigationController = (UINavigationController*)rootViewController;
return [self topViewControllerWithRootViewController:navigationController.visibleViewController];
} else if (rootViewController.presentedViewController) {
UIViewController* presentedViewController = rootViewController.presentedViewController;
return [self topViewControllerWithRootViewController:presentedViewController];
} else {
return rootViewController;
}
}
各UIViewControllerでサポートする方向を返します
- (NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortrait;
}
ここで退屈することはありませんが、あなたのサブクラスを共有してくれませんか?ありがとうございました。
編集:まあ、私はついにそれをやった、サブクラスはとても簡単にできた。 navigationController
でAppDelegate
をデフォルトのUINavigationControllerSubclass
の代わりにUINavigationController
として宣言し、サブクラスを次のように変更する必要がありました。
- (BOOL)shouldAutorotate {
return _shouldRotate;
}
viewDidLoad
を呼び出すことで、回転するかどうかの任意のビューを設定できます
_navController = (UINavigationController *)self.navigationController;
[_navController setShouldRotate : YES / NO]
このTweakが他の人にも役立つことを願っています、あなたのヒントをありがとう!
ヒント:活用する
- (NSUInteger)supportedInterfaceOrientations
view Controllerで使用しますので、ポートレートで望みの景色を横向きにしたり、その逆を行ったりすることはありません。
UISplitViewControllerとUISegmentedControllerを使用する比較的複雑なユニバーサルアプリがあり、presentViewController
を使用してランドスケープで表示する必要があるビューがいくつかあります。上記の方法を使用して、iPhone ios 5および6を許容範囲内で動作させることができましたが、何らかの理由でiPadが単にLandscapeとして表示することを拒否しました。最後に、デバイスとiOS 5および6の両方で機能する簡単なソリューション(数時間の読み取りと試行錯誤の後に実装された)を見つけました。
ステップ1)コントローラーで、必要な方向を指定します(上記のように多かれ少なかれ)
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
-(BOOL)shouldAutorotate
{
return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
NSInteger mask = UIInterfaceOrientationMaskLandscape;
return mask;
}
ステップ2)シンプルなUINavigationControllerサブクラスを作成し、次のメソッドを実装します
-(BOOL)shouldAutorotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscape;
}
ステップ3)viewControllerを提示する
vc = [[MyViewController alloc]init];
MyLandscapeNavigationController *myNavigationController = [[MyLandscapeNavigationController alloc] initWithRootViewController:vc];
[self myNavigationController animated:YES completion:nil];
これが誰かに役立つことを願っています。
UINavigationControllerおよびUITabBarControllerクラス内のVCを許可するためにサブクラスまたはカテゴリを使用した回答はうまく機能します。横向きのTab Bar Controllerから縦向きのみのモーダルを起動できませんでした。これを行う必要がある場合は、アニメーション化されていないモーダルビューを表示および非表示にするトリックを使用しますが、viewDidAppearメソッドで行います。 viewDidLoadまたはviewWillAppearでは動作しませんでした。
それとは別に、上記のソリューションは正常に動作します。
Monotouchの場合、次のようにできます。
public override UIInterfaceOrientationMask GetSupportedInterfaceOrientations()
{
return UIInterfaceOrientationMask.LandscapeRight;
}
public override UIInterfaceOrientation PreferredInterfaceOrientationForPresentation()
{
return UIInterfaceOrientation.LandscapeRight;
}
私はそれを自分でテストしませんでしたが、ドキュメントには、これらのメソッドをオーバーライドできるようになったことが記載されています:supportedInterfaceOrientations
およびpreferredInterfaceOrientationForPresentation
。
おそらく、これらのメソッドで必要な方向のみを設定することで、目的を達成できます。
私は多くの答えを見ますが、特定のアイデアと方向についての答えは得られませんが、リンクが方向をよく理解し、ios6の強制回転を削除するのを見ます。
http://www.disalvotech.com/blog/app-development/iphone/ios-6-rotation-solution/
私はそれが完全に役立つと思います。