From e911de01e9e862fb2e1cfcd62ab03ff76179ce71 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Thu, 12 Jul 2018 14:01:22 -0600 Subject: [PATCH] Ensure delegate is informed of dismissal // FREEBIE --- .../MenuActionsViewController.swift | 51 ++++++++++++++++++- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/Signal/src/ViewControllers/MenuActionsViewController.swift b/Signal/src/ViewControllers/MenuActionsViewController.swift index af44f5ca7..c4ad64f60 100644 --- a/Signal/src/ViewControllers/MenuActionsViewController.swift +++ b/Signal/src/ViewControllers/MenuActionsViewController.swift @@ -35,6 +35,12 @@ class MenuActionsViewController: UIViewController, MenuActionSheetDelegate { private let focusedView: UIView private let actionSheetView: MenuActionSheetView + deinit { + Logger.verbose("\(logTag) in \(#function)") + assert(didInformDelegateOfDismissalAnimation) + assert(didInformDelegateThatDisappearenceCompleted) + } + @objc required init(focusedView: UIView, actions: [MenuAction]) { self.focusedView = focusedView @@ -49,6 +55,8 @@ class MenuActionsViewController: UIViewController, MenuActionSheetDelegate { fatalError("init(coder:) has not been implemented") } + // MARK: View LifeCycle + var actionSheetViewVerticalConstraint: NSLayoutConstraint? override func loadView() { @@ -75,6 +83,17 @@ class MenuActionsViewController: UIViewController, MenuActionSheetDelegate { self.animatePresentation() } + override func viewDidDisappear(_ animated: Bool) { + Logger.debug("\(logTag) in \(#function)") + super.viewDidDisappear(animated) + + // When the user has manually dismissed the menu, we do a nice animation + // but if the view otherwise disappears (e.g. due to resigning active), + // we still want to give the delegate the information it needs to restore it's UI. + ensureDelegateIsInformedOfDismissalAnimation() + ensureDelegateIsInformedThatDisappearenceCompleted() + } + // MARK: Present / Dismiss animations var presentationFocusOffset: CGFloat? @@ -184,17 +203,45 @@ class MenuActionsViewController: UIViewController, MenuActionSheetDelegate { snapshotView.frame.origin.y -= presentationFocusOffset // this helps when focused view is above navbars, etc. snapshotView.alpha = 0 - self.delegate?.menuActions(self, isDismissingWithVerticalFocusChange: presentationFocusOffset) + self.ensureDelegateIsInformedOfDismissalAnimation() }, completion: { _ in self.view.isHidden = true - self.delegate?.menuActionsDidHide(self) + self.ensureDelegateIsInformedThatDisappearenceCompleted() if let action = action { action.block(action) } }) } + var didInformDelegateThatDisappearenceCompleted = false + func ensureDelegateIsInformedThatDisappearenceCompleted() { + guard !didInformDelegateThatDisappearenceCompleted else { + Logger.debug("\(logTag) in \(#function) ignoring redundant 'disappeared' notification") + return + } + didInformDelegateThatDisappearenceCompleted = true + + self.delegate?.menuActionsDidHide(self) + } + + var didInformDelegateOfDismissalAnimation = false + func ensureDelegateIsInformedOfDismissalAnimation() { + guard !didInformDelegateOfDismissalAnimation else { + Logger.debug("\(logTag) in \(#function) ignoring redundant 'dismissal' notification") + return + } + didInformDelegateOfDismissalAnimation = true + + guard let presentationFocusOffset = self.presentationFocusOffset else { + owsFail("\(self.logTag) in \(#function) presentationFocusOffset was unexpectedly nil") + self.delegate?.menuActionsDidHide(self) + return + } + + self.delegate?.menuActions(self, isDismissingWithVerticalFocusChange: presentationFocusOffset) + } + // MARK: Actions @objc