2

以下に示すプロジェクトには、InitialViewController「Show Popover」というラベルのボタンが 1 つある があります。そのボタンがタップされると、アプリは 2 番目のビュー コントローラー ( PopoverViewController) をポップオーバーとして表示することになっています。2 番目のビュー コントローラーには、"Popover!" というラベルが付いています。

絵コンテ画像

これは、InitialViewControllerが のインスタンス化PopoverViewController、取得、popoverPresentationControllerおよび popoverPresentationController のdelegateそれ自体 (へInitialViewController) の設定を処理する場合に正常に機能します。以下に結果を示します。

InitialViewController で委譲が発生した場合のアプリの機能

InitialViewControllerただし、再利用性を最大限に高めるには、プレゼンテーション コントローラがどのように委任されるかについて何も知る必要がなければ、すばらしいことです。PopoverViewControllerが popoverPresentationController として設定できるはずだと思いますdelegateviewDidLoadまたは のviewWillAppear関数でこれを試しましたPopoverViewController。ただし、PopoverViewController以下に示すように、どちらの場合もモーダルで表示されます。

ここに画像の説明を入力

すべてのコードは と だけに含まれてInitialViewControllerPopoverViewControllerます。の失敗したバージョンで使用されるコードをInitialViewController以下に示します。

import UIKit

// MARK: - UIViewController subclass

class InitialViewController: UIViewController {

    struct Lets {
        static let storyboardName = "Main"
        static let popoverStoryboardID = "Popover View Controller"
    }

    @IBAction func showPopoverButton(_ sender: UIButton) {

        // instantiate & present the popover view controller
        let storyboard = UIStoryboard(name: Lets.storyboardName,
                                      bundle: nil )
        let popoverViewController =
            storyboard.instantiateViewController(withIdentifier: Lets.popoverStoryboardID )
        popoverViewController.modalPresentationStyle = .popover
        guard let popoverPresenter = popoverViewController.popoverPresentationController
            else {
                fatalError( "could not retrieve a pointer to the 'popoverPresentationController' property of popoverViewController")
        }
        present(popoverViewController,
                animated: true,
                completion: nil )

        // Retrieve and configure UIPopoverPresentationController
        // after presentation (per
        // https://developer.apple.com/documentation/uikit/uipopoverpresentationcontroller)

        popoverPresenter.permittedArrowDirections = .any
        let button = sender
        popoverPresenter.sourceView = button
        popoverPresenter.sourceRect = button.bounds

    }
}

失敗し たコードをPopoverViewController以下に示します。

import UIKit


// MARK: - main UIViewController subclass

class PopoverViewController: UIViewController {

    // MARK: API
    var factorForMarginsAroundButton: CGFloat = 1.2

    // MARK: outlets and actions
    @IBOutlet weak var popoverLabel: UILabel!

    // MARK: lifecycle

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

        // set the preferred size for popover presentations
        let labelSize =
            popoverLabel.systemLayoutSizeFitting( UILayoutFittingCompressedSize )
        let labelWithMargins =
            CGSize(width: labelSize.width * factorForMarginsAroundButton,
                   height: labelSize.height * factorForMarginsAroundButton )
        preferredContentSize = labelWithMargins

        // set the delegate for the popoverPresentationController to self
        popoverPresentationController?.delegate = self

    }
}
// MARK: - UIPopoverPresentationControllerDelegate
//       (inherits from protocol UIAdaptivePresentationControllerDelegate)

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

ポップオーバーとして表示されているビュー コントローラーを独自のデリゲートにすることは可能popoverPresentationControllerですか?

Xcode 8.0、Swift 3.1 を使用しており、ターゲットは iOS 10.0 です

4

1 に答える 1