5

問題:アプリのさまざまな部分で、横向きモード (ロック) と縦向きモード (ロック) の両方を使用するアプリがあります。現在、私は実用的な解決策を持っていますが、それは正しくないようで、独自の問題があります。

最適には、方向の変更を強制したいと思います。必要に応じて、ビューの変換を行うことも考えています。

アプリの基本的な流れ:

  • HomeView (Portrait) (これには、いくつかのサブプッシュ ビューもあり、縦向きでそれにロックされています)。
  • LandscapeView (Landscape) (横向きでもある 5 つのプッシュされたサブビューがあります)

ノート:

  • HomeView には、LandscapeView へのリンクがあります
  • LandscapeView は HomeView に戻ることができます
  • LandscapeView サブビューの最後に、HomeView に戻ります。

さまざまなビューの向きでこれがどのように見えるかを示す基本的な画像。(線はアプリの流れを示し、画像の向きは各画面のあり方を示します)

現在のビューの変更

現在、以下の実装を使用して、[setLockedToPortait:YES] (縦向きビューの場合) などにより、ビューが縦向きモードまたは横向きモードであるかどうかを呼び出し/設定します。

これは、デバイスが回転している場合に、iOS からどのインターフェイスの向きを使用するかをクエリします。

ここで、LandscapeView に移動する場合のために、通常のビューの上に一時的なビューを表示して、携帯電話を横向きに回転させるために使用するように求めます。(横表示から HomeView に戻ると、一時的な表示も表示されます)

したがって、ユーザーがデバイスを回転させると、正しい向きがトリガーされ、一時ビューが非表示になります。

ユーザーがこの時点で携帯電話を回転させて縦に戻すと、横にロックされたままになるため、別のビューの回転はトリガーされません (一時的なビューも表示されません)。


現在の実装コード::

// ---------------------- NavigationController (subclass of UINavigationController)
@interface NavigationController () {
BOOL isOrientationPortrait;
}
@end


@implementation NavigationController {
       UIDeviceOrientation lastAccepted;
       UIDeviceOrientation lastKnown;
 }

-(void)setLockedToPortait:(BOOL)isLocked {
    isOrientationPortrait = isLocked;
}

-(UIDeviceOrientation) getCurrentOrientation {
UIDeviceOrientation orientate = [[UIDevice currentDevice] orientation];
if(orientate == 0) { // needed for simulator
    orientate = (UIDeviceOrientation)[UIApplication sharedApplication].statusBarOrientation;
}
return orientate;
}

// Deprecated in iOS6, still needed for iOS5 support.
- (BOOL)shouldAutorotateToInterfaceOrientation:
(UIInterfaceOrientation)toInterfaceOrientation
{
UIDeviceOrientation orientation = [self getCurrentOrientation];
[self setLastKnownOrientation:orientation];

if(isOrientationPortrait == YES) {
    if([self isLastKnownPortrait] == YES) {
        [self setLastAcceptedOrientation:orientation];
        return YES;
    } else {
        return NO;
    }
} else {
    if([self isLastKnownLandscape] == YES) {
        [self setLastAcceptedOrientation:orientation];
        return YES;
    } else {
        return NO;
    }
}
}

// iOS6/7 support
- (BOOL)shouldAutorotate
{
    // find out the current device orientation
UIDeviceOrientation orientation = [self getCurrentOrientation];
[self setLastKnownOrientation:orientation];
return YES;
}

- (NSUInteger)supportedInterfaceOrientations
{
if(isOrientationPortrait == YES) {
    if([self isLastKnownPortrait] == YES)
    {
        UIDeviceOrientation orientation = [self getCurrentOrientation];
        [self setLastAcceptedOrientation:orientation];
    }
    return (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown);
} else {
    if([self isLastKnownLandscape] == YES)
    {
        UIDeviceOrientation orientation = [self getCurrentOrientation];
        [self setLastAcceptedOrientation:orientation];
    }
    return (UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight );
}
}
-(void)setLastAcceptedOrientation:(UIDeviceOrientation)orient  {
lastAccepted = orient;
}

-(void)setLastKnownOrientation:(UIDeviceOrientation)orient {
    lastKnown = orient;
}

-(BOOL)isLastKnownPortrait {
    return UIDeviceOrientationIsPortrait(lastKnown);
}

-(BOOL)isLastKnownLandscape {
    return UIDeviceOrientationIsLandscape(lastKnown);
}

-(BOOL)isLastAcceptedPortrait {
    return UIDeviceOrientationIsPortrait(lastAccepted);
}

-(BOOL)isLastAcceptedLandscape {
    return UIDeviceOrientationIsLandscape(lastAccepted);
}

現在の問題:

  • デバイスの回転は、ユーザーが縦向きから横向きモードに移行したり、その逆の場合に、ビューが読み込まれた後に常に必要です。
  • ユーザーがデバイスの向きをロックしている場合、これはまったく機能しません。
  • 横向きモードから戻るときに、ユーザーがすでにデバイスを縦向きに回転させている場合 (最後の横向きビューで)、縦向きビューのインターフェースは、ユーザーがデバイスを再度回転させるまで「横向き」レイアウトにロックされます (現在、私はデバイスを回転させるためにオーバーレイを表示しているだけですが、すでに回転しています... ユーザーにとって非常に迷惑です)。上記の実装で現在大きな問題が発生しています。

次のことができるようになりたいです:

  • 現在のビューの方向を電話で強制的に変更します。
  • ビューのプッシュ/ポップ間で強制されるビューの優先レイアウトを設定します。

ここと Apple Dev フォーラムで他の解決策をよく調べましたが、この問題をカバーしていないようです。または、2 つのビュー間の方向のバグも存在します。

助けや指針をありがとう!アドバイスは割引されません:D

-- 編集::

@leo-natanのおかげで解決策が見つかりました!!

したがって、ビューの向きを強制的に変更しようとする代わりに。新しいモーダル ビューをプッシュするだけです。これにより、変更が強制されます。回転を管理するには、上記の方向コードが必要です。

それで、HomeViewControllerに今あるもの:

LandscapeViewController * viewController = [[[LandscapeViewController ViewController alloc] init] autorelease];
UINib * nib = [UINib nibWithNibName:@"NavigationController" bundle:nil];
NavigationController *navController = [[nib instantiateWithOwner:nil options:nil] objectAtIndex:0];
[navController initWithRootViewController:viewController];
[self presentViewController:navController animated:YES completion:^{
    // completion
}];

したがって、このモーダル ビューの新しいナビゲーション コントローラーを再度追加する必要があります。また、上記の「presentViewController」は、モーダル ビューをプッシュする新しい方法です。

ビュー コントローラを管理するために、次のオーバーロードされたメソッドを実装しました。

-(id)initWithRootViewController:(UIViewController *)rootViewController {

self = [super initWithRootViewController:rootViewController];
    if(self){

    }
return self;
}

注:上記は絵コンテを使用していません。この問題は、ストーリーボードを使用し、同じ方法でビューをモーダルに表示することで解決できる場合があります。

4

1 に答える 1