I need to be able to update my app's UI when the split view controller's display mode changes. Specifically, if it goes from an expanded interface to a collapsed interface, I need to do something, and also if it goes from collapsed to expanded.
I am currently handling this via traitCollectionDidChange and while this seems to be working good for two of my split view controllers, the third one isn't working. It seems this method is getting called too early, so that when I check the displayMode to see if it's UISplitViewcontrollerDisplayModeAllVisible, the split view hasn't yet updated to the new display mode. So it ends up removing buttons that I want to actually want to add, or adds them when I wanted to remove them. If I delay checking that display mode just 0.1 second later, the displayMode value correctly represents what it will be when rotation completes and the appropriate action is taken.
My question is, is there a better method to use to update my app's UI, perhaps is there a way to know when the displayMode changes? I don't want to risk it calling it too early, but I also don't want to wait until rotation completes to update the UI. Delaying the check is a very fragile solution that may easily result in unexpected behavior, sometimes it might not work.
A more robust solution would be to use primaryViewControllerForCollapsingSplitViewController: and primaryViewControllerForExpandingSplitViewController: in the UISplitViewControllerDelegate.
From the documentation it says
If you do not implement this method, or if your implementation returns nil, the split view controller chooses its primary view controller as the one to display.
So implement these methods to track collapse and expand, then return nil and you'll still get the default behavior.
had a similar issue and discovered this delegate method on UISplitViewControllerDelegate
func targetDisplayModeForActionInSplitViewController(svc: UISplitViewController) -> UISplitViewControllerDisplayMode
Only problem is that it when you ask svc.displayMode, it tells you what mode its coming from and not where its going. However, its enough info to be able to prevent the UISplitViewController from going into a particular state.
func targetDisplayModeForActionInSplitViewController(svc: UISplitViewController) -> UISplitViewControllerDisplayMode {
switch svc.displayMode {
case .PrimaryOverlay :
return .AllVisible
case .AllVisible :
return .PrimaryHidden
case .PrimaryHidden :
return .AllVisible
case .Automatic :
return .AllVisible
default:
return .AllVisible
}
}
The other delegate method that I was able to use to know when my UISplitViewController display mode was changing is
func splitViewController(svc: UISplitViewController, willChangeToDisplayMode displayMode: UISplitViewControllerDisplayMode)
Then you can change the view accordingly if you handle the states that matter to you
func splitViewController(svc: UISplitViewController, willChangeToDisplayMode displayMode: UISplitViewControllerDisplayMode) {
println("will change to display mode \(displayMode.rawValue)")
if (displayMode == UISplitViewControllerDisplayMode.AllVisible) {
//do something because EVERYTHING is visible
} else if (displayMode == UISplitViewControllerDisplayMode.PrimaryHidden) {
//something else because the primary is GONE
} else if (self.splitViewController?.displayMode == UISplitViewControllerDisplayMode.PrimaryOverlay){
//handle primary overlay change
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With