タブベースのアプリを作りました。横向きモードにする必要はありませんが、いくつかのビューが必要です。 iOS5でも問題なく動作し、結果にはかなり満足していました。ただし、iOS6では、何もいじることなく、すべてのビューが回転するようになり、結果は良くありません。
タブベースのアプリであるため、ランドスケープで必要な2つのビューはmodalViewsです。そうすれば、タブバーをいじることなく、ビルドオプションの[サポートされている向き]設定でポートレートを選択して、次のように設定するだけで済みました。
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
風景が欲しかった景色に。
IOS6では、このビューも縦向きモードになっていて、デバイスを回転させても横向きモードは表示されません。同様に、「サポートされている方向」ですべての方向を許可すると、上記の方法で何を行っても、すべて回転します。
すべてのビューで、ストーリーボードの[自動レイアウトを使用する]チェックボックスをオンにしていません。
ここで何か助けはありますか?
* [〜#〜] edit [〜#〜]**これで、私が使用しているアプリデバイスは正常に動作します。 Xcodeからではなく、プロモーションコードをインストールして、顧客に問題があるかどうかを確認しました。幸いなことに、そうではありません。しかし、問題は残っています。
この問題について私が見つけたドキュメントの最も重要な部分は次のとおりです。
ユーザーがデバイスの向きを変更すると、システムは、ルートビューコントローラーまたはウィンドウ全体に表示される最上位のビューコントローラーでこのメソッドを呼び出します。
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(UIViewControllerサブクラスであるintroScreenViewController)を表示し、self.window.rootViewControllerを設定したため、次のようになります。
nvc = [[MyNavigationController alloc] initWithRootViewController:introScreenViewController];
nvc.navigationBarHidden = YES;
self.window.rootViewController = nvc;
[window addSubview:nvc.view];
[window makeKeyAndVisible];
これは、タブバーコントローラーを使用している場合の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];
デリゲートでrootViewControllerを設定していますか?例えば、
self.window.rootViewController = self.navigationController;
IOS6のテストを行っていたときは、それを行うまで正しく機能しませんでした...
私はクロス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
}
これは私のために働くものです。
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;
}
または、portraitとportraitUpsideDownだけに移動したいビューにこれを追加します
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return
(interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown);
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown ;
}
- (BOOL)shouldAutorotate
{
return YES;
}
あなたは再確認するかもしれませんサポートインターフェースの向き
以前のバージョンでは、それは何の意味もありませんが、現在はアプリケーション全体に影響します。
注:「逆さま」オプションは、iOS6で有効または無効にしても機能しません。
ShouldAutorotateToInterfaceOrientationに関するAppleのドキュメントから:
代わりに、supportedInterfaceOrientationsメソッドとpreferredInterfaceOrientationForPresentationメソッドをオーバーライドします。
このコードは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;
}
IOS6.0で自動回転が変更されました。詳細については、これを確認してください リンク 。
IOS 6では自動回転が変更されています。iOS6では、UIViewControllerのshouldAutorotateToInterfaceOrientation:メソッドは非推奨になりました。代わりに、supportedInterfaceOrientationsメソッドとshouldAutorotateメソッドを使用する必要があります。
IOS6では自動回転の構造が変更されたため、これを機能させるために処理する必要のあることがいくつかあります。オートローテーションの決定方法の構造が逆になりました。以前は、個々のビューコントローラがその決定で自動回転を制御できましたが、現在、「shouldAutorotate」はナビゲーションの最上位の親(この場合はtabBar)によって決定されます。
例えば:
- (BOOL)shouldAutorotate
{
return self.selectedViewController.shouldAutorotate;
}
ビューコントローラでは、shouldAutorotateを実装し、そこで決定を下します。
IOS6のアプリ「SamePicture」の場合、向きを変更する必要があります。UIViewControllerに向きが通知されることはありません。これは、写真オーバーレイであり、didrotateが適切に機能する可能性があります。
- (void)didRotate: ( NSNotification* )note
{
[self performSelector:@selector(rotateRecalculDiffere) withObject:nil afterDelay:0.3 ];
}
遅延通話で細かいサイズ調整を行います。通知から最終的な方向を知るのは簡単です
少し実験を行いました:既存のアプリ(iOS-6では回転しませんでしたが、以前は回転していました)を取得し、AppDelegateに1行self.window.rootViewController = navCtlr;
を追加しました。これにより、アプリは(少なくとも最初は赤面して)正常に回転しているように見えます。
次に、好奇心から、RotationCanaryクラスを作成し、そのインスタンスをself.window.rootViewControllerにプラグインしました。アプリを起動して、避けられない「認識されないセレクター」を待ち、RotationCanaryでその名前の新しいメソッドを作成して、再実行します。新しいメソッドは、realnav 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の設定を、アプリがiOS6ローテーション用に変更されたことを示す方法として純粋に使用しています-それ以外の場合は実際の機能はありません。
FWIW:呼び出し元がrespondsToSelector
を使用していて、一部の呼び出しをスキップしている可能性があることに気付いたので、resolveInstanceMethod:
の実装をRotationCanaryに追加してそのような試みをトラップしました。何も発生しませんでした。