In apps like the Settings app, when the UISplitViewContoller
is collapsed, the UITableView
cells display the standard '>' disclosure accessory icons:
On devices like the Plus-sized iPhones when rotating to landscape and the full UISplitViewController
becomes visible, the disclosure icons disappear:
When configuring the cells initially, it's possible to simply call self.splitViewController.isCollapsed
to find out what the current state of the split view controller is. However when a transition occurs after that point, I'm not sure what the best way to receive notifications of that occurrence.
The easiest solution I've considered is to just call self.tableView.reloadData()
inside the view controller's viewWillTransitionToSize
method, but that seems like a really 'brute-force' way of doing it.
Has anyone done this sort of implementation? How did you solve it?
Aha! I discovered how to do it! The Apple iOS 8 sample code on size classes demonstrates how to do it.
I was setting up my UITableViewCell
instances only in the cellForRowAtIndexPath
data source method, which of course, only gets called once for each cell's creation.
Apple's sample code configures the table cell accessory view in the willDisplayCell
delegate method, and this method appears to be called on each visible cell automatically when a UISplitViewController
transition occurs. :)
Edit: Okay, on further exploration, it turns out it's not automatic. It's an NSNotification
.
Here's the code from the Apple Sample app. In the view controller's viewDidLoad
:
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(ListTableViewController.showDetailTargetDidChange(_:)), name: NSNotification.Name.UIViewControllerShowDetailTargetDidChange, object: nil)
}
And the method the notification triggers:
func showDetailTargetDidChange(_ notification: Notification) {
/*
Whenever the target for showDetailViewController: changes, update all
of our cells (to ensure they have the right accessory type).
*/
for cell in tableView.visibleCells {
if let indexPath = tableView.indexPath(for: cell) {
tableView(tableView, willDisplay: cell, forRowAt: indexPath)
}
}
}