Search code examples
iosiphoneswiftuisplitviewcontrolleruicontrol

UIControl blocking all my views on iPhone


I got a iPad-designed app using a SplitViewController showing two views, one with a contacts list and another with details of this contact. The SplitView works well on iPad but has some problems on iPhones.

There is a UIControl that take all the size of the Master View, that check if there is any .touchDown interaction by the user and some methods called to enable or disable this UIControl depending if we are on editing contact mode or not allowing user to interact with the screen or not :

private var disableInteractionClosure: (()->())?
    private lazy var interactionOverlay: UIControl = {
        let c = UIControl()
        c.autoresizingMask = [.FlexibleHeight, .FlexibleWidth]
        c.addTarget(self, action: "interactionOverlayAction", forControlEvents: .TouchDown)
        return c
    }()

    func disableInteractionWhileEditingWithClosure(callback: ()->()) {
        if disableInteractionClosure == nil {
            disableInteractionClosure = callback
            /* display control overlay */
            interactionOverlay.frame = navigationController!.view.bounds
            navigationController!.view.addSubview(interactionOverlay)
        }
    }

    func interactionOverlayAction() {
        disableInteractionClosure!()
    }

    func enableInteraction() {
        disableInteractionClosure = nil
        interactionOverlay.removeFromSuperview()
    }

Basically the UIControl is used to block user from switching between contact while user is editing another contact/ creating a new one by blocking interaction with the contact list and if changes have been made on the editing/creating view it fires a method that shows a pop up saying "modifications have been made do you want to continue without saving ? cancel or continue " :

func cancel() {
        self.view.endEditing(true)

        let closure: ()->() = {
            self.layoutView.willResign()
            self.delegate?.tabDetailsControllerDidCancel(self)
        }

            if layoutView.hasChanges() {
                MKAlertViewController().instantaneousAlert(title: "Modification apportées", message: "Êtes-vous sur de vouloir continuer sans sauvegarder les modifications ?", confirmButtonTitle: "Oui", cancelButtonTitle: "Annuler", confirmed: { () -> Void in
                    closure()
                    }, canceled: { () -> Void in

                })
            } else {
                closure()
            }

    }

It works fine on iPad because the UIControl is only above the Master View and is enabled when in editing mode on the Detail View (iPad 3D Debugging view), so the pop up shows only when manually cancelling the editing/creating or when trying to change contact while editing/creating, but as the splitView don't work the same on iPads and iPhones and it appears that on iPhone the Master View is placed above the Detail View, the UIControl is also above (iPhone 3D Debugging view), and it causes to block interactions on all the screen and wherever I click the cancel pop-up is shown.

Can you guys explain me a way to enable/show this UIControl only when the MasterView is showing and not everywhere. Thanks.


Solution

  • I ended up using the viewWillDisappear on the detail view :

    override func viewWillDisappear(animated: Bool) {
    
            super.viewWillDisappear(animated)
    
            if self.isMovingFromParentViewController() || self.isBeingDismissed() {
                if editingMode {
                    shared.contactsListController.disableInteractionWhileEditingWithClosure({ (_) in
                        self.tabDetailsController.cancel()
                    })
                    shared.contactsListController.disableToolbar()
                } else {
                    shared.contactsListController.enableInteraction()
                    shared.contactsListController.enableToolbar()
                }
                self.navigationController?.toolbar.alpha = 1
            }
        }
    

    and modifying the disableInteractionWhileEditingWithClosure method on the master view:

    func disableInteractionWhileEditingWithClosure(callback: ()->()) {
            if disableInteractionClosure == nil {
                disableInteractionClosure = callback
                /* display control overlay */
                interactionOverlay.frame = navigationController!.view.bounds
    
                view.addSubview(interactionOverlay) // this line
            }
        }
    

    and it works ! :)