14

タブベースのアプリを作りました。ランドスケープモードである必要はありませんが、いくつかのビューがあります。iOS5でも問題なく動作し、結果にはかなり満足していました。ただし、iOS6では、何もいじることなく、すべてのビューが回転するようになり、結果は良くありません。

タブベースのアプリであるため、ランドスケープで必要な2つのビューはmodalViewsです。そうすれば、タブバーをいじることなく、ビルドオプションの[サポートされている向き]設定でポートレートを選択して、次のように設定するだけで済みました。

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {

    return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
    return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}

私が風景が欲しかった景色について。

iOS6では、このビューもポートレートモードになっていますが、デバイスを回転させてもランドスケープモードは表示されません。同様に、「サポートされている方向」ですべての方向を許可すると、上記の方法で何を実行しても、すべて回転します。

すべてのビューで、ストーリーボードの[自動レイアウトを使用する]チェックボックスをオンにしていません。

ここで何か助けはありますか?

*編集** これで、デバイスにあるアプリは正常に動作します。Xcodeからではなく、プロモーションコードをインストールして、顧客に問題があるかどうかを確認しました。幸いなことに、そうではありません。しかし、問題は残っています。

4

12 に答える 12

36

この問題について私が見つけたドキュメントの最も重要な部分は次のとおりです。

ユーザーがデバイスの向きを変更すると、システムはルートビューコントローラーまたはウィンドウ全体に表示される最上位のビューコントローラーでこのメソッドを呼び出します。

iOS 6でアプリを自動回転で完全に機能させるには、次のことを行う必要がありました。

1)UINavigationControllerの新しいサブクラスを作成し、shouldAutorotateメソッドとsupportedInterfaceOrientationメソッドを追加しました。

// MyNavigationController.h:
#import <UIKit/UIKit.h>

@interface MyNavigationController : UINavigationController

@end

// MyNavigationController.m:
#import "MyNavigationController.h"
@implementation MyNavigationController
...
- (BOOL)shouldAutorotate {
    return YES;
}

- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskAll;
}
...
@end

2)AppDelegateで、新しいサブクラスを使用してルートViewController(introScreenViewController、UIViewControllerサブクラス)を表示し、self.window.rootViewControllerを設定したため、次のようになります。

    nvc = [[MyNavigationController alloc] initWithRootViewController:introScreenViewController];
    nvc.navigationBarHidden = YES;
    self.window.rootViewController = nvc;
    [window addSubview:nvc.view];
    [window makeKeyAndVisible];
于 2012-09-22T03:11:54.053 に答える
10

これは、タブバーコントローラーを使用している場合のiOS6の代替ソリューションです。また、UINavigationControllerまたはUITabBarControllerをオーバーライドする必要がないことも示しています。

xyzAppDelegate.hに、のインターフェイスを追加します。

@interface UITabBarController (MyApp)
@end

そして、xyzAppDelegate.mに次のメソッドを追加します。

@implementation UITabBarController (MyApp) 

-(BOOL)shouldAutorotate
{
  return YES;
}

- (NSUInteger)supportedInterfaceOrientations
{
  // your custom logic for rotation of selected tab
  if (self.selectedIndex==...) {
    return UIInterfaceOrientationMaskAll;
  } 
  else {
    return UIInterfaceOrientationMaskPortrait|UIInterfaceOrientationMaskPortraitUpsideDown;
  }
}

@end

また、アプリウィンドウのルートビューコントローラーを設定します。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  ...
  [self.window setRootViewController:tabBarController];
于 2012-09-24T10:57:34.130 に答える
6

デリゲートでrootViewControllerを設定していますか?例えば、

    self.window.rootViewController = self.navigationController;

私がiOS6のテストを行っていたとき、それを行うまでは正しく機能しませんでした...

于 2012-09-21T19:17:11.960 に答える
5

私はクロス5.0から6.0が機能するための良い解決策を持っています-上記のすべて

-(BOOL)shouldAutorotate{return [self shouldIRotateAnyiOS];}//iOS6

-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{return [self shouldIRotateAnyiOS];}//pre iOS6

-(BOOL)shouldIRotateAnyiOS{
UIInterfaceOrientation interfaceOrientation = [[UIDevice currentDevice] orientation];
//do the rotation stuff
return YES
}
于 2012-10-04T05:08:47.530 に答える
1

サポートインターフェイスの向きを再確認してください

ここに画像の説明を入力してください

以前のバージョンでは、それは何の意味もありませんが、現在はアプリケーション全体に影響します。

注:「逆さま」オプションは、iOS6で有効または無効にしても機能しません。

于 2012-09-26T09:22:37.767 に答える
1

これは私のために働くものです。

UINavigationControllerの新しいサブクラスを作成し、shouldAutorotateメソッドとsupportedInterfaceOrientationメソッドを追加しました。

#import "MyNavigationController.h"

@interface MyNavigationController ()

@end

@implementation MyNavigationController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (BOOL)shouldAutorotate {
    return [self.visibleViewController shouldAutorotate];
}

- (NSUInteger)supportedInterfaceOrientations {
    return [self.visibleViewController supportedInterfaceOrientations];
}

@end

次に、これをデリゲートに追加します

UINavigationController *nvc = [[MyNavigationController alloc] initWithRootViewController:_viewController];
nvc.navigationBarHidden = NO; // YES if you want to hide the navigationBar
self.window.rootViewController = nvc;
[_window addSubview:nvc.view];
[_window makeKeyAndVisible];

これで、すべての方向に回転させたいビューにこれを追加できます

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return YES;
}

-(NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskAll;
}

-(BOOL)shouldAutorotate
{
    return YES;
}

または、これをポートレートとportraitUpsideDownにのみ移動するビューに追加します

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return
    (interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown);
}

- (NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown ;
}

- (BOOL)shouldAutorotate
{
    return YES;
}
于 2012-11-07T10:08:38.667 に答える
0

自動回転はiOS6.0で変更されました。詳細については、このリンクを確認してください。

自動回転はiOS6で変更されています。iOS6では、UIViewControllerのshouldAutorotateToInterfaceOrientation:メソッドは非推奨になりました。代わりに、supportedInterfaceOrientationsメソッドとshouldAutorotateメソッドを使用する必要があります。

于 2012-09-21T19:11:50.617 に答える
0

iOS6では自動回転の構造が変更されているため、これを機能させるために処理する必要のあることがいくつかあります。オートローテーションの決定方法の構造が逆になりました。以前は、個々のビューコントローラがその決定で自動回転を制御できましたが、現在、「shouldAutorotate」はナビゲーションの最上位の親(この場合はtabBar)によって決定されます。

  1. ウィンドウにサブビューとして追加されただけでなく、rootViewControllerが設定されていることを確認する必要があります。
  2. 「supportedInterfaceOrientations」と「shouldAutorotate」の両方を実装するには、tabBarControllerをサブクラス化する必要がある場合があります。
  3. 異なる動作をする必要のあるviewControllerがある場合は、自動回転する必要があるかどうかについて、tabBarControllerに相談してもらう必要があります。

例えば:

- (BOOL)shouldAutorotate
{
    return self.selectedViewController.shouldAutorotate;
}

ビューコントローラでは、shouldAutorotateを実装し、そこで決定を下します。

于 2012-09-21T20:58:41.500 に答える
0

このコードはios5とios6に共通です

-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration {
    if (UIInterfaceOrientationIsLandscape(interfaceOrientation)) {
        [self performSelector:@selector(setframeLandscap) withObject:nil afterDelay:0.2];
    }
    else {
        [self performSelector:@selector(setframePortrait) withObject:nil afterDelay:0.2];
    }
}

-(BOOL)shouldAutorotate {    
    return YES;
}
于 2012-09-26T08:34:36.463 に答える
0

shouldAutorotateToInterfaceOrientationに関するAppleのドキュメントから:

代わりに、supportedInterfaceOrientationsメソッドとpreferredInterfaceOrientationForPresentationメソッドをオーバーライドします。

http://developer.apple.com/library/ios/#documentation/uikit/reference/UIViewController_Class/DeprecationAppendix/AppendixADeprecatedAPI.html#//apple_ref/occ/instm/UIViewController/shouldAutorotateToInterfaceOrientation

于 2012-10-13T09:16:49.120 に答える
0

iOS6のアプリ「SamePicture」の場合、向きを変更する必要があります。UIViewControllerに向きが通知されることはありません。これは、写真オーバーレイであり、didrotateが適切に機能する可能性があります。

- (void)didRotate: ( NSNotification* )note
{
    [self performSelector:@selector(rotateRecalculDiffere) withObject:nil afterDelay:0.3 ];
}

遅延通話で細かいサイズ調整を行います。通知から最終的な方向性を知るのは簡単です

于 2012-11-01T10:05:14.003 に答える
0

少し実験を行いました:既存のアプリ(iOS-6では回転しませんでしたが、以前は回転しました)self.window.rootViewController = navCtlr;を取得し、AppDelegateに1行追加しました。これにより、アプリは(少なくとも最初は赤面して)正常に回転しているように見えます。

次に、好奇心から、RotationCanaryクラスを作成し、そのインスタンスをself.window.rootViewControllerにプラグインしました。アプリを起動して、避けられない「認識されないセレクター」を待ち、RotationCanaryでその名前の新しいメソッドを作成して、再実行します。新しいメソッドは、実際のnav ctlrを呼び出し、その応答をログに記録してから返します。これにより、(予想よりも早く)次のログが生成されました。

2012-12-07 13:08:47.689 MyTestApp[53328:c07] System Version is 6.0;    Supported versions are 5.0.x to 6.0.x
2012-12-07 13:08:47.691 MyTestApp[53328:c07] Host memory (in bytes) used: 3489513472 free: 803893248 total: 4293406720
2012-12-07 13:08:47.692 MyTestApp[53328:c07] Memory in use by task (in bytes): 23719936
2012-12-07 13:08:47.695 MyTestApp[53328:c07] Creating database
2012-12-07 13:08:47.699 MyTestApp[53328:c07] Item Selected: (null)  (null)
2012-12-07 13:08:47.700 MyTestApp[53328:c07] <DetailViewController.m:(27)> Entering Method -[DetailViewController viewDidLoad]
2012-12-07 13:08:47.706 MyTestApp[53328:c07] <SplitContentViewController.m:(57)> Entering Method -[SplitContentViewController viewDidLoad]
2012-12-07 13:08:47.708 MyTestApp[53328:c07] <FamilyMasterViewController.m:(32)> Entering Method -[FamilyMasterViewController viewDidLoad]
2012-12-07 13:08:47.709 MyTestApp[53328:c07] <MasterViewController.m:(41)> Entering Method -[MasterViewController viewDidLoad]
2012-12-07 13:08:47.718 MyTestApp[53328:c07] <FamilyHomeDetailViewController.m:(51)> Entering Method -[FamilyHomeDetailViewController viewDidLoad]
2012-12-07 13:08:47.820 MyTestApp[53328:c07] -[RotationCanary _preferredInterfaceOrientationGivenCurrentOrientation:] - current = 2, result = 2
2012-12-07 13:08:47.821 MyTestApp[53328:c07] -[RotationCanary _existingView] - view = (null)
2012-12-07 13:08:47.824 MyTestApp[53328:c07] -[RotationCanary view] - view = <UILayoutContainerView: 0x9c987f0; frame = (0 0; 768 1024); autoresize = W+H; layer = <CALayer: 0x9c8fa00>>
2012-12-07 13:08:47.825 MyTestApp[53328:c07] -[RotationCanary view] - view = <UILayoutContainerView: 0x9c987f0; frame = (0 0; 768 1024); autoresize = W+H; layer = <CALayer: 0x9c8fa00>>
2012-12-07 13:08:47.826 MyTestApp[53328:c07] -[RotationCanary view] - view = <UILayoutContainerView: 0x9c987f0; frame = (0 0; 768 1024); autoresize = W+H; layer = <CALayer: 0x9c8fa00>>
2012-12-07 13:08:47.827 MyTestApp[53328:c07] -[RotationCanary wantsFullScreenLayout] - result = YES
2012-12-07 13:08:47.827 MyTestApp[53328:c07] -[RotationCanary view] - view = <UILayoutContainerView: 0x9c987f0; frame = (0 0; 768 1024); autoresize = W+H; layer = <CALayer: 0x9c8fa00>>
2012-12-07 13:08:47.830 MyTestApp[53328:c07] -[RotationCanary _tryBecomeRootViewControllerInWindow:] - window = <UIWindow: 0x9c76320; frame = (0 0; 768 1024); opaque = NO; autoresize = RM+BM; layer = <UIWindowLayer: 0x9c76450>>, result = YES
2012-12-07 13:08:47.916 MyTestApp[53328:c07] -[RotationCanary _deepestDefaultFirstResponder] - result = <SignOnViewController: 0x9c942a0>
2012-12-07 13:08:47.916 MyTestApp[53328:c07] Device model: x86_64

不思議なことに、ローテーションを実行するためにクラスが実際に呼び出されることはありませんでした。セットアップ中のみです。

AppleはrootViewControllerの設定を、アプリがiOS 6ローテーション用に変更されたことを示す方法として純粋に使用しているのではないかと思います。それ以外の場合、実際の機能はありません。

FWIW:respondsToSelector発信者が一部の呼び出しを使用してスキップしている可能性があることに気付いたのでresolveInstanceMethod:、RotationCanaryに実装を追加して、そのような試みをトラップしました。何も発生しませんでした。

于 2012-12-07T19:25:38.670 に答える