17

iOS 8 の新しい適応型の「Present As Popover」機能を使用しています。プレゼンテーションを行うために、StoryBoard に単純なセグエを配線しました。ビューをポップオーバーとして表示するため、iPhone 6 Plus ではうまく機能し、iPhone 4s では全画面表示 (シート スタイル) として表示します。

問題は、全画面表示として表示される場合です。ビューに「完了」ボタンを追加して、dismissViewControllerAnimated を呼び出せるようにする必要があります。また、ポップオーバーとして表示されているときに「完了」ボタンを表示したくありません。

ここに画像の説明を入力

presentationController と popoverPresentationController の両方のプロパティを調べてみましたが、実際にポップオーバーとして表示されているかどうかを示すものは何も見つかりません。

NSLog( @"View loaded %lx", (long)self.presentationController.adaptivePresentationStyle );          // UIModalPresentationFullScreen
NSLog( @"View loaded %lx", (long)self.presentationController.presentationStyle );                  // UIModalPresentationPopover
NSLog( @"View loaded %lx", (long)self.popoverPresentationController.adaptivePresentationStyle );   // UIModalPresentationFullScreen
NSLog( @"View loaded %lx", (long)self.popoverPresentationController.presentationStyle );           // UIModalPresentationPopover

AdaptivePresentationStyle は常に UIModalPresentationFullScreen を返し、presentationStyle は常に UIModalPresentationPopover を返します。

UITraitCollection を見ると、実際にポップオーバーとして表示されたときにのみ 1 に設定された "_UITraitNameInteractionModel" という特性が見つかりました。ただし、Apple は popoverPresentationController の traitCollection を介してその特性に直接アクセスすることはできません。

4

8 に答える 8

10

ビューがレイアウトされた後、popoverPresentationController の arrowDirection が設定されているかどうかを確認します。私の目的では、これは十分に機能し、小さな画面のデバイスでのポップオーバーのケースをカバーしています.

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)

    if (popoverPresentationController?.arrowDirection != UIPopoverArrowDirection.Unknown) {
        // This view controller is running in a popover
        NSLog("I'm running in a Popover")
    }
}
于 2014-12-14T14:17:53.283 に答える
3

この投稿に記載されているすべてのソリューションをテストしました。申し訳ありませんが、すべての場合に正しく機能するものはありません。たとえば、iPad の分割ビューでは、分割ビューの線をドラッグすると表示スタイルが変わる可能性があるため、そのための特定の通知が必要です。数時間の調査の後、リンゴのサンプル (swift) で解決策を見つけました: https://developer.apple.com/library/ios/samplecode/AdaptivePhotos/Introduction/Intro.html#//apple_ref/doc/uid/TP40014636

obj-c での同じソリューションを次に示します。

最初に prepareForSegue 関数で popoverPresentationController デリゲートを設定します。MyViewController の「init」でも設定できますが、「viewDidLoad」では設定できません (最初に willPresentWithAdaptiveStyle が viewDidLoad の前に呼び出されるため)。

MyViewController *controller = [segue destinationViewController];
        controller.popoverPresentationController.delegate = (MyViewController *)controller;

これで、MyViewController オブジェクトは、最初の表示を含め、iOS が表示スタイルを変更するたびにこの通知を受け取ります。これは、navigationController で「閉じる」ボタンを表示/非表示にする実装例です。

- (void)presentationController:(UIPresentationController *)presentationController
  willPresentWithAdaptiveStyle:(UIModalPresentationStyle)style
         transitionCoordinator:(nullable id<UIViewControllerTransitionCoordinator>)transitionCoordinator {
    if (style == UIModalPresentationNone) {
        // style set in storyboard not changed (popover), hide close button
        self.topViewController.navigationItem.leftBarButtonItem = nil;
    } else {
        // style changed by iOS (to fullscreen or page sheet), show close button
        UIBarButtonItem *closeButton =
            [[UIBarButtonItem alloc] initWithTitle:@"Close" style:UIBarButtonItemStylePlain target:self action:@selector(closeAction)];
        self.topViewController.navigationItem.leftBarButtonItem = closeButton;
    }
}

- (void)closeAction {
    [self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
}
于 2016-05-12T07:54:35.980 に答える
2

マルチタスクで動作するソリューション

表示コントローラーをポップオーバーのデリゲートとして割り当てます

...
controller.popoverPresentationController.delegate = controller;
[self presentViewController:controller animated:YES completion:nil];

次に、コントローラーでデリゲート メソッドを実装します。

- (void)presentationController:(UIPresentationController *)presentationController willPresentWithAdaptiveStyle:(UIModalPresentationStyle)style transitionCoordinator:(id<UIViewControllerTransitionCoordinator>)transitionCoordinator
{
    if (style != UIModalPresentationNone)
    {
        // Exited popover mode
        self.navigationItem.leftBarButtonItem = button;
    }
}

- (void)prepareForPopoverPresentation:(UIPopoverPresentationController *)popoverPresentationController
{
    // Entered popover mode
    self.navigationItem.leftBarButtonItem = nil;
}
于 2016-10-06T23:33:27.237 に答える
2

UIPresentationControllerView Controller を管理する は、 を に設定することで表示されmodalPresentationStyleますUIModalPresentationPopover

UIViewController 参照に従って:

プレゼンティングViewController

  • このView Controllerを提示したView Controller。(読み取り専用)

modalPresentationStyle

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

したがって、次のようにチェックすることで、View Controller がポップオーバー内にあるか、モーダルに表示されているかを判断できますhorizontalSizeClass(ボタンは であると仮定しましたUIBarButtonItem) 。

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    if (self.presentingViewController.traitCollection.horizontalSizeClass == UIUserInterfaceSizeClassRegular)
        self.navigationItem.leftBarButtonItem = nil; // remove the button
}

これをチェックする最も安全な場所は、viewWillAppear:それ以外のpresentingViewController場合はnil.

于 2014-11-20T11:00:03.360 に答える
2

これを実装する公式の方法は、最初にビュー コントローラーから [完了] ボタンを削除し、2 番目に、ビュー コントローラーをナビゲーション コントローラーにコンパクトに埋め込むときに、[完了] ボタンをナビゲーション アイテムとして追加することです。

func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle {
    return UIModalPresentationStyle.FullScreen
}

func presentationController(controller: UIPresentationController, viewControllerForAdaptivePresentationStyle style: UIModalPresentationStyle) -> UIViewController? {
    let navigationController = UINavigationController(rootViewController: controller.presentedViewController)
    let btnDone = UIBarButtonItem(title: "Done", style: .Done, target: self, action: "dismiss")
    navigationController.topViewController.navigationItem.rightBarButtonItem = btnDone
    return navigationController
}

func dismiss() {
    self.dismissViewControllerAnimated(true, completion: nil)
}

完全なチュートリアル

スクリーンショット

于 2016-03-01T13:44:01.507 に答える