web-dev-qa-db-ja.com

「UIPopoverController is deprecated」警告を修正するにはどうすればよいですか?

私はこのコードを使用しています:

mediaLibraryPopover = [[UIPopoverController alloc] 
                        initWithContentViewController:avc];
[self.mediaLibraryPopover presentPopoverFromRect:[theButton bounds] 
                          inView:theButton 
                          permittedArrowDirections:UIPopoverArrowDirectionAny 
                          animated:YES];

そして、私はXcode 7でこの警告を受け取っています:

UIPopoverControllerは廃止され、最初にiOS 9.0で廃止されます-UIPopoverControllerは廃止されました。 Popoverは、UIViewControllerプレゼンテーションとして実装されるようになりました。 UIModalPresentationPopoverおよびUIPopoverPresentationControllerのモーダルプレゼンテーションスタイルを使用します。

45
Varun Naharia

View Controllerを表示するためにUIPopoverControllerは必要なくなりました。代わりに、View ControllerのmodalPresentationStyleUIModalPresentationPopoverに設定できます。

そのために次のコードを使用できます。

avc.modalPresentationStyle = UIModalPresentationPopover;
avc.popoverPresentationController.sourceView = theButton;
[self presentViewController:avc animated:YES completion:nil];

UIModalPresentationPopover

水平に規則的な環境で、コンテンツがポップオーバービューで表示されるプレゼンテーションスタイル。背景コンテンツは淡色表示され、ポップオーバーの外側をタップすると、ポップオーバーが閉じられます。タップでポップオーバーを閉じたくない場合は、popoverPresentationControllerプロパティから取得できる、関連付けられたUIPopoverPresentationControllerオブジェクトのpassthroughViewsプロパティに1つ以上のビューを割り当てることができます。

水平方向にコンパクトな環境では、このオプションはUIModalPresentationFullScreenと同じように動作します。

IOS 8.0以降で利用可能。

リファレンス IModalPresentationStyleリファレンス


sourceViewまたはbarButtonItemプロパティのいずれかを設定する必要があります。設定しないと、次のメッセージでクラッシュします。

***キャッチされない例外 'NSGenericException'によるアプリの終了、理由: 'UIPopoverPresentationController(***)は、プレゼンテーションが発生する前に、nil以外のsourceViewまたはbarButtonItemを設定する必要があります。

ポップオーバー矢印を正しく固定するには、sourceRectプロパティも指定する必要があります。

avc.modalPresentationStyle                   = UIModalPresentationPopover;
avc.popoverPresentationController.sourceView = self.view;
avc.popoverPresentationController.sourceRect = theButton.frame;
[self presentViewController:avc animated:YES completion:nil];

詳細については、 sourceView および sourceRect を参照してください。

110
Midhun MP

Appleには、iOS8のポップオーバーを表示および構成する公式の方法があります: https://developer.Apple.com/library/ios/documentation/UIKit/Reference/UIPopoverPresentationController_class/index.html

@MidhunMPの答えに似ていますが、段落に注目する価値があります。

presentViewController:animated:completion:を呼び出した後にポップオーバープレゼンテーションコントローラーを構成すると、直感に反するように見えるかもしれませんが、UIKitはプレゼンテーションを開始するまでプレゼンテーションコントローラーを作成しません。さらに、UIKitは次の更新サイクルまで待機して、新しいコンテンツを画面に表示する必要があります。この遅延により、ポップオーバー用にプレゼンテーションコントローラーを設定する時間が与えられます。

必要に応じて、デリゲートを介して設定とイベントへの応答を行うこともできます( https://developer.Apple.com/library/ios/documentation/UIKit/Reference/UIPopoverPresentationControllerDelegate_protocol/index.html )。

例、デリゲートの使用を脇に置く:

// Present the controller using the popover style.
controller.modalPresentationStyle = UIModalPresentationPopover;
[self presentViewController:controller animated:YES completion:nil];

// Popover presentation controller was created when presenting; now  configure it.
UIPopoverPresentationController *presentationController =
        [controller popoverPresentationController];
presentationController.permittedArrowDirections = UIPopoverArrowDirectionLeft;
presentationController.sourceView = containerFrameOfReferenceView;
// arrow points out of the rect specified here
presentationController.sourceRect = childOfContainerView.frame;

ただし、これも却下する必要があります。デリゲートを使用せずにこれを行うには、プレゼンティングコントローラーが次を呼び出すだけです。

[self dismissViewControllerAnimated:YES completion:nil];

しかし、デバイスを回転させ、ポップオーバーが正しい領域を指していない場合はどうなりますか?提示するコントローラーはそれを処理できます。

// Respond to rotations or split screen changes
- (void)viewWillTransitionToSize:(CGSize)size
       withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
    [coordinator animateAlongsideTransition:nil 
                                 completion:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
        // Fix up popover placement if necessary, after the transition.
        if (self.presentedViewController) {
            UIPopoverPresentationController *presentationController =
                    [self.presentedViewController popoverPresentationController];
            presentationController.sourceView = containerFrameOfReferenceView;
            presentationController.sourceRect = childOfContainerView.frame;
        }
    }];
}
7
qix

ボタンアクションから直接必要な場合は、このコードを使用できます

SecondViewController *destinationViewController = (SecondViewController *)[self.storyboard instantiateViewControllerWithIdentifier:@"second"];
destinationViewController.modalPresentationStyle = UIModalPresentationPopover;
destinationViewController.popoverPresentationController.sourceView = self.customButton;

// Set the correct sourceRect given the sender's bounds
destinationViewController.popoverPresentationController.sourceRect = ((UIView *)sender).bounds;
[self presentViewController:destinationViewController animated:YES completion:nil];
1
Abhishek