2019年12月29日日曜日

[Xcode11 SDK13] UISplitViewControllerでメニューが引っ込まない

Xcode6(SDK8)で非推奨になったのに、放っておいたら、「戻る」ボタンは表示されないし、メニューとして使っているプライマリビューは隠れないし、たいへんなことになってしまった。

willHideViewController:withBarButtonItem:forPopoverController:
のforPopoverControllerでメニューのオブジェクトを取得し、メニューを隠すのに使っていたのだが、SDK13からforPopoverControllerは何も返さなくなってしまった。

修正点は以下の2点。

1. メニューを隠す


縦画面の時だけ隠したいので、端末の向きを、

// NotificationCenter登録


[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(changedOrientation:) name:UIDeviceOrientationDidChangeNotification object:nil];

// ハンドラ


- (void)changedOrientation:(NSNotificationCenter*)center {
    switch ([UIDevice currentDevice].orientation) {
        case UIDeviceOrientationLandscapeLeft:
        case UIDeviceOrientationLandscapeRight:
        case UIDeviceOrientationPortrait:
        case UIDeviceOrientationPortraitUpsideDown:
            _orientation = [UIDevice currentDevice].orientation;
            _splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModeAutomatic;
            break;
        default: //FaceUp及びFaceDownでは何もしない。
            break;
    }
}

で_orientationを取得した上で、今までどおり、ゆっくり隠したいので0.3秒を指定。

// メニューを押した後に、以下を実装


switch (_orientation) {
    case UIDeviceOrientationPortrait:
    case UIDeviceOrientationPortraitUpsideDown: {
        [UIView animateWithDuration:0.3 animations:^{
        _splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModePrimaryHidden; }];
        break; }
    default:
        break;
}

2. 「戻る」ボタンを表示する


以下のようなものをviewDidLoadに実装するだけで、あとは自動的にやってくれる

navigationItem.leftBarButtonItem = splitViewController.displayModeButtonItem;

はずだったのだが、起動時の一発目に、左上の文字がでないことがあった。
白紙から作り直せばうまくいくのだが、そういう訳にもいかないので、viewDidAppearに以下を実装。

navigationItem.leftBarButtonItem.title = @"●●●";






1 件のコメント:

  1. [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]は、SDK13では呼ばなくてもよさそう。おそらく常に有効なのだろう。

    またNotificationCenterではなく、viewWillTransitionToSizeでもいいはずなのだが、仰向けの状態で起動した時、faceUpしか返ってこないので使えなかった。
    faceUpが返ってくるのは仕様としてあるべき姿なんだろうけど、今回はLandscapeかPortraitなのかを区別するのが目的だったので、NotificationCenterのままとした。
    この辺の仕様は揺れてるみたいなので、将来のSDKアップデート時には、こっそり変更される可能性が高い。

    返信削除