web-dev-qa-db-ja.com

iPhoneのUIPopoverPresentationControllerがポップオーバーを生成しない

私は、iPhoneアプリに新しいUIPopoverPresentationControllerを実装しようとしています(Objective Cを使用)。私が欲しいのは、開始ボタンから発せられるテーブルビューを備えたシンプルなポップオーバーです。

-編集-

ここに私の[〜#〜] revised [〜#〜]のコードがあります。これは、ドキュメントSOの研究と、以下のコメントの入力から適合したものです。

- (IBAction)selectCategoryBtn:(UIButton *)sender
{
    [self performSegueWithIdentifier:@"CatSelectSegue" sender:self.selCatButton];
}

-(void) prepareForSegue:(UIStoryboardSegue *) segue Sender:(id) sender
{
    if (sender == self.selCatButton)
    {
        if ([segue.identifier isEqualToString:@"CatSelectSegue"])
        {
            UIPopoverPresentationController *controller = segue.destinationViewController;
            controller.delegate = self;
            controller.sourceView = self.selCatButton;
            controller.sourceRect = self.selCatButton.frame;
        }
    }
}


-(UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller
{
    return UIModalPresentationNone;

これが私のストーリーボードの接続です:

enter image description here

ただし、これは単にテーブルビューをモーダル形式で表示し、下から上昇して画面全体を消費します。

私はグーグルで調べてみましたが、iPhoneの厄介な問題を解決したいと思ったことで混乱したのは私だけではないようです。

誰かが私のコードに不具合を見つけたり、明確なチュートリアルに誘導したりできますか?私は見たことがありますが、おそらくAPIはまったく新しいので、まだ誰もハンドルを握っていません。

ありがとう!

2回目の編集:

上記のコードの結果として表示されるものを次に示します。ポップオーバーとして表示されると予想されるView Controllerのテーブルビューのサイズを小さくしました。ポップオーバーの代わりに何が表示されるかを明確にするために、背景を灰色に色付けしました。

enter image description here

29
rattletrap99

手順:

A)Present As Popoverセグエタイプを使用して、UIButtonをポップオーバーのView Controllerにリンクします。これを表示するには、実際に新しいプロジェクトを作成する必要がありましたが、おそらくベースSDKに関係しています。

B)UIButtonを含むView Controllerが<UIPopoverPresentationControllerDelegate>に準拠するようにします。例えば。 MyViewController.mファイルに以下を追加します。

@interface MyViewController () <UIPopoverPresentationControllerDelegate>

C)UIButtonを含むView Controllerに以下のメソッドを追加します。

- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller {

    return UIModalPresentationNone;
}

D)以下をprepareForSegue:sender:に追加して、segue.identifierチェックを置き換えます:

if ([segue.identifier isEqualToString:@"CatSelectSegue"]) {
    UIViewController *dvc = segue.destinationViewController;
    UIPopoverPresentationController *controller = dvc.popoverPresentationController;
    if (controller) {
        controller.delegate = self;
    }
}

コードのテストと動作の証明:

Popover on iPhone without 3rd Party Controls

編集:魔法が起こる私のテストアプリTPOPViewController.mファイル:

#import "TPOPViewController.h"

@interface TPOPViewController () <UIPopoverPresentationControllerDelegate>//, UIAdaptivePresentationControllerDelegate>

@end

@implementation TPOPViewController

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {

    NSString *identifier = segue.identifier;
    if ([identifier isEqualToString:@"popover"]) {
        UIViewController *dvc = segue.destinationViewController;
        UIPopoverPresentationController *ppc = dvc.popoverPresentationController;
        if (ppc) {
            if ([sender isKindOfClass:[UIButton class]]) { // Assumes the popover is being triggered by a UIButton
                ppc.sourceView = (UIButton *)sender;
                ppc.sourceRect = [(UIButton *)sender bounds];
            }
            ppc.delegate = self;
        }
    }
}

- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller {

    return UIModalPresentationNone;
}

@end

私のテストストーリーボード:

Popover on iPhone test storyboard

73
Robotic Cat

どうやら上記の方法はiOS9/Xcode7では動作しなくなったようです。これは、Interface Builderを使用してセグエスタイルを「ポップオーバー」に設定した場合、Xcodeはアプリケーションをコンパイルするときにそれを無視するためです。さらに、次にプロジェクトを開いたときに自動的にセグエを「プッシュ」に戻します。 Gitのようなバージョン管理ソフトウェアを使用している場合は、この望ましくない変更が行われていることを確認できます。

ただし、ポップオーバーとして表示したいView Controllerを手動で提示すると、iPhone上でiPadスタイルのポップオーバーを取得することはまだ可能です。例Swiftコード:

//  ViewController.Swift
//  PopoverDemo
//
//  Created by bhnascar on 12/2/15.
//  Copyright © 2015 bhnascar. All rights reserved.
//

import UIKit

class ViewController: UIViewController, UIPopoverPresentationControllerDelegate {

    /* The bar button item that will present the popover. */
    var popoverButton: UIBarButtonItem?

    override func viewDidLoad() {
        super.viewDidLoad()
        popoverButton = UIBarButtonItem(title: "Pop!", style: UIBarButtonItemStyle.Plain, target: self, action: "presentPopover")
        self.navigationItem.rightBarButtonItem = popoverButton
    }

    // Mark: - UIPopoverPresentationControllerDelegate

    func prepareForPopoverPresentation(popoverPresentationController: UIPopoverPresentationController) {
        popoverPresentationController.permittedArrowDirections = .any
        popoverPresentationController.barButtonItem = popoverButton
    }

    func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
        return .none
    }

    // Mark: - Callback function for popover button.

    func presentPopover() {
        let popoverContentController = UIViewController()
        popoverContentController.view.backgroundColor = .blue

        // Set your popover size.
        popoverContentController.preferredContentSize = CGSize(width: 300, height: 300)

        // Set the presentation style to modal so that the above methods get called.
        popoverContentController.modalPresentationStyle = .popover

        // Set the popover presentation controller delegate so that the above methods get called.
        popoverContentController.popoverPresentationController!.delegate = self

        // Present the popover.
        self.present(popoverContentController, animated: true, completion: nil)
    }

}
19
bhnascar

Swift 3.X

これにより、画面の中央にポップオーバーが表示されます

class CommonViewController: UIViewController, UIPopoverPresentationControllerDelegate{

    func adaptivePresentationStyle(
        for controller: UIPresentationController,
        traitCollection: UITraitCollection)
        -> UIModalPresentationStyle {
            return .none
    }

    func showPopover() {
        let myViewController = UIViewController()
        myViewController.preferredContentSize = CGSize(width: 320, height: 200)
        myViewController.modalPresentationStyle = .popover

        let popOver = myViewController.popoverPresentationController
        popOver?.delegate = self

        self.present(myViewController, animated: true, completion: nil)
        popOver?.permittedArrowDirections = .up
        popOver?.sourceView = self.view

        let rect = CGRect(
            Origin: CGPoint(x: self.view.frame.width/2,
                            y: self.view.frame.height/2),
            size: CGSize(width: 1, height: 1)
        )
        popOver?.sourceRect = rect
    }
}
6
tsik

IPhone/iPadからUIModalPresentationStyleポップオーバーを表示するには:

-(void)menuButtonPressed:(UIButton *)sender {

    self.menuPopoverController = [[DownloadMenuPopoverController alloc] initWithStyle:UITableViewStylePlain];
    self.menuPopoverController.delegate = self;

    self.menuPopoverController.modalPresentationStyle = UIModalPresentationPopover;
    self.menuPopoverController.popoverPresentationController.delegate = self;
    self.menuPopoverController.preferredContentSize = CGSizeMake(250,80);
    self.menuPopoverController.popoverPresentationController.sourceRect = sender.frame;// rect to show view
    self.menuPopoverController.popoverPresentationController.sourceView = self.view;

    UIPopoverPresentationController *popPC = self.menuPopoverController.popoverPresentationController;
    popPC.permittedArrowDirections = UIPopoverArrowDirectionAny;
    popPC.delegate = self;
    [self presentViewController:self.menuPopoverController animated:YES completion:nil];

}

#pragma mark - UIPresentationController Delegate methods

- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller traitCollection:(UITraitCollection *)traitCollection {
    return UIModalPresentationNone;
}

- (UIViewController *)presentationController:(UIPresentationController *)controller viewControllerForAdaptivePresentationStyle:(UIModalPresentationStyle)style {
    UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:controller.presentedViewController];
    return navController;
}
0
Harshal Wani