Как обнаружить, когда popover отклоняется в iOS 9

Я обновляю приложение, чтобы использовать универсальные раскадровки. Я создал popover segue для нового диспетчера представлений, используя построитель интерфейсов, перетаскивая его с помощью кнопки на мой новый диспетчер представлений и выбрав "Present As Popover" как вид segue.

Когда пользователь нажимает за пределы popover (отклоняя его), мне нужно получить уведомление в контроллере представления, чтобы я мог отменить их действия. Как я могу это сделать?

Как правило, я бы создал popover вручную и сделал myviewcontroller делегатом popover; позволяя мне использовать обратный вызов popoverControllerDidDismissPopover. Тем не менее, это устарело в iOS9, и даже если бы это было не так, я понятия не имел, где найти popover, чтобы я мог установить его делегат на свой контроллер представления.

Ответ 1

Не уверен, какой метод вы считаете устаревшим, но вы все равно можете использовать UIPopoverPresentationControllerDelegate для достижения этого. Что-то вроде:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "popoverSegue" {
        let vc = segue.destinationViewController
        sortVC.modalPresentationStyle = .Popover
        sortVC.popoverPresentationController?.sourceRect = filterButton.bounds
        sortVC.preferredContentSize = CGSizeMake(216, 150)
        sortVC.popoverPresentationController!.delegate = self
    }
}

И затем используйте

func popoverPresentationControllerDidDismissPopover(popoverPresentationController: UIPopoverPresentationController)

для обработки его увольнения.

Ответ 2

Метод popoverControllerDidDismissPopover: был заменен на popoverPresentationControllerShouldDismissPopover:, потому что UIPopoverControllerDelegate был заменен на UIPopoverPresentationControllerDelegate.

С вашего контроллера представления представления, совместим с новым протоколом и установите делегат для контроллера представления popover в prepareForSegue::

class MyPresentingViewController: UIViewController, UIPopoverPresentationControllerDelegate {

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {         
        if let popoverPresentationController = segue.destinationViewController.popoverPresentationController {
            popoverPresentationController.delegate = self
        }
    }

    func popoverPresentationControllerShouldDismissPopover(popoverPresentationController: UIPopoverPresentationController) -> Bool {
        return true
    }
}

Затем вы можете использовать метод делегата для обработки обнаружения увольнения так, как вы ранее предполагали.

Ответ 3

Я обнаружил, что вместо использования делегатов, которые обнаруживают только при касании вне представления, если вы хотите обнаружить все отклонения, тогда я считаю, что лучше всего использовать замыкание, которое вызывается в viewWillDisappear(). Таким образом вы поймаете все увольнения в одном месте.

class SecondViewController: UIViewController {
    var leaveAction: (() -> Void)?

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        leaveAction?()
    }
}
class FirstViewController: UIViewController {
    private var isShowingPopover = false

    // ...

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "popoverSegue" {
            let vc = segue.destinationViewController
            isShowingPopover = true
            vc.leaveAction = { [weak self] in
                // Gets called when leaveAction?() is called in SecondViewController
                self?.isShowingPopover = false
            }
            vc.modalPresentationStyle = .popover
            vc.popoverPresentationController?.sourceRect = filterButton.bounds
            vc.preferredContentSize = CGSizeMake(216, 150)
            vc.popoverPresentationController!.delegate = self
        }
    }
}

// MARK: - Popover delegates
extension FirstViewController: UIPopoverPresentationControllerDelegate {
    func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
        return .none
    }

    func popoverPresentationControllerShouldDismissPopover(_ popoverPresentationController: UIPopoverPresentationController) -> Bool {
        return true
    }
}