-1

私はいくつかの UITabBarController を持っています。横向きでは、tabBar を非表示にしてコンテンツ ビューを展開します。コードは次のようになります。

-(void)viewWillLayoutSubviews {
  [super viewWillLayoutSubviews];

  UIView *transView = [self.view.subviews objectAtIndex:0];
  if(UIInterfaceOrientationIsLandscape(self.interfaceOrientation)) {
      transView.frame = self.view.bounds;
      self.tabBar.hidden = YES;
    } else {
      self.tabBar.hidden = NO;
      CGRect frame = self.view.bounds;
      frame.size.height = self.tabBar.frame.origin.y;
      transView.frame = frame;
    }
}

これにより、向きの変更が問題なく処理されます。

の使用法を追加したときに問題が発生しましたUIImagePickerUIImagePicker表示時に縦向きを強制します (Apple は独自の UI 規則に違反しています: 向きを強制しません)。
アプリケーションが横向きでUIImagePicker表示されてviewWillLayoutSubviewsいる場合、 が 2 回呼び出されてUIInterfaceOrientationIsLandscape(self.interfaceOrientation)が返されますYES
ここまでは順調ですね。が閉じられると (写真の選択またはキャンセルによって)、が呼び出されてが返されるので、問題ないはずですが、結果は次のようになります
UIImagePickerviewWillLayoutSubviewsUIInterfaceOrientationIsLandscape(self.interfaceOrientation)YESスクリーンショット

ご覧のとおり、ステータス バーは横向き (ok)、UI は縦向き (失敗): UI は縦向きで表示され、UIControllerステータス バー用のスペースも残されています (左側に黒いストライプ)、UI もステータスによって上部が切り取られています。バー。

これは iOS のバグのように見えUIInterfaceOrientationIsLandscape(self.interfaceOrientation)ますYESが、UI は縦向きのままです。

環境:iOS 6.1.3 iPod Touch 5g。

それを修正する方法はありますか: ステータス バーを左側に残すか、UI を横向きに強制しますか?


更新willRotateToInterfaceOrientation:さらに調査した結果、didRotateFromInterfaceOrientationこのシナリオでは呼び出されないことに気付きました。このログをさまざまな場所に追加しましたが、常に「3 3 3 3」と出力されます ( UIInterfaceOrientationLandscapeLeft):

NSLog(@"%d %d %d %d",
      self.navigationController.interfaceOrientation, 
      self.interfaceOrientation, 
      self.selectedViewController.interfaceOrientation, 
      [UIDevice currentDevice].orientation);

状態情報には記載されてUIInterfaceOrientationLandscapeLeftいますが、縦向きの UI と横向きのステータス バーが表示されます。


ローテーションがいつ実行されるかを確認するために、この種のログを追加しました。

  UIView *view = self.view;
  int i=0;
  while(view) {
    CGAffineTransform trans = view.transform;
    NSLog(@"Transform: %d %@", i, NSStringFromCGAffineTransform(trans));
    ++i;
    view = view.superview;
  }

通常の回転 (縦から横) の場合、ログは次のようになります。

Transform: 0 [1, 0, 0, 1, 0, 0]
Transform: 1 [1, 0, 0, 1, 0, 0]
Transform: 2 [1, 0, 0, 1, 0, 0]
Transform: 3 [0, 1, -1, 0, 0, 0]
Transform: 4 [1, 0, 0, 1, 0, 0]

問題のあるケース: 横向きのデバイス、閉じるUIImagePicker:

Transform: 0 [1, 0, 0, 1, 0, 0]
Transform: 1 [1, 0, 0, 1, 0, 0]
Transform: 2 [1, 0, 0, 1, 0, 0]
Transform: 3 [1, 0, -0, 1, 0, 0]
Transform: 4 [1, 0, 0, 1, 0, 0]
Transform: 5 [1, 0, 0, 1, 0, 0]

これは、ビュー スタックが変更された (1 増加した) 奇妙なことです。また、インデックス付きのビューに3問題があることもわかります。

4

1 に答える 1

0

この不思議な問題で EVIL HACK を見つけました。

- (void)doAWorkaroudnOnUnwantedRotation {
  // check if is workaround nesesery:
  if (UIInterfaceOrientationIsLandscape([UIDevice currentDevice].orientation)) {
    double delayInSeconds = 0.5;
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
      UIViewController *fake = [[[UIViewController alloc] init] autorelease];
      UIViewController *rootController = [UIApplication sharedApplication].keyWindow.rootViewController;
      [rootController presentModalViewController: fake animated: NO];
      [fake dismissModalViewControllerAnimated: NO];
    });
  }
}

UIImagePickerが却下されたときにこのメソッドを呼び出します。ピッカーがアニメーション化されているため何も起こらずdispatch_after、アニメーションが終了するまでこの回避策は機能しません。

于 2013-09-18T10:42:50.647 に答える