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.
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 ! :)