What is UISplitViewController?
UISplitViewController
is a specialized UIViewController
used for displaying two view controllers side-by-side in a master-detail layout. It is commonly used in iPad applications and adapts dynamically to different screen sizes.
1. Key Features of UISplitViewController
✅ Master-Detail Interface – Shows two view controllers at once.
✅ Adaptive Layout – Automatically adjusts for different devices (iPhone/iPad).
✅ Automatic Collapsing – Collapses into a single view on smaller screens.
✅ Built-in Navigation Support – Easily integrates with UINavigationController
.
✅ Customizable Display Modes – Supports .automatic
, .primaryOverlay
, .secondaryOnly
, etc.
2. Creating a UISplitViewController
You can set up a UISplitViewController
in two ways:
- Using Storyboard
- Programmatically
2.1 Using Storyboard
- Drag a
UISplitViewController
onto the canvas. - Assign a
MasterViewController
(left panel) andDetailViewController
(right panel). - Embed both in
UINavigationController
(recommended). - Set
UISplitViewController
as the initial view controller.
2.2 Creating UISplitViewController Programmatically
import UIKit
class SplitViewController: UISplitViewController, UISplitViewControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let masterVC = UINavigationController(rootViewController: MasterViewController())
let detailVC = UINavigationController(rootViewController: DetailViewController())
self.viewControllers = [masterVC, detailVC]
self.delegate = self
self.preferredDisplayMode = .oneBesideSecondary // Controls layout behavior
}
}
✅ This sets up a basic Split View with a Master and Detail view.
3. UISplitViewController Display Modes
UISplitViewController
has different display modes that define how views appear:
Mode | Description |
---|---|
.automatic | Automatically chooses the best mode based on the device. |
.oneBesideSecondary | Shows master and detail side-by-side (default for iPads). |
.oneOverSecondary | Overlays master view over the detail view. |
.oneOverPrimary | Overlays detail view over master (useful for compact layouts). |
.secondaryOnly | Hides the master and shows only the detail. |
Example: Setting Display Mode
self.preferredDisplayMode = .oneBesideSecondary
4. Handling View Collapsing on Small Screens
By default, UISplitViewController
collapses into a single view on iPhones. To handle this, implement the collapseSecondaryViewController
delegate method.
func splitViewController(
_ splitViewController: UISplitViewController,
collapseSecondary secondaryViewController: UIViewController,
onto primaryViewController: UIViewController) -> Bool {
return true // Returns true to collapse the detail view into the master view
}
✅ This ensures the detail view does not open separately on small screens.
5. Passing Data Between Master and Detail
5.1 Using Delegates
- Create a Protocol in MasterViewController
protocol MasterViewControllerDelegate: AnyObject {
func didSelectItem(_ item: String)
}
- Implement Protocol in DetailViewController
class DetailViewController: UIViewController, MasterViewControllerDelegate {
let detailLabel = UILabel()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
setupLabel()
}
func setupLabel() {
detailLabel.frame = CGRect(x: 50, y: 100, width: 300, height: 50)
view.addSubview(detailLabel)
}
func didSelectItem(_ item: String) {
detailLabel.text = "Selected: \(item)"
}
}
- Set Delegate in SplitViewController
if let masterNav = viewControllers.first as? UINavigationController,
let masterVC = masterNav.viewControllers.first as? MasterViewController,
let detailVC = (viewControllers.last as? UINavigationController)?.viewControllers.first as? DetailViewController {
masterVC.delegate = detailVC
}
✅ This allows the MasterViewController to send data to DetailViewController.
6. Example: Complete UISplitViewController Implementation
import UIKit
class MasterViewController: UITableViewController {
weak var delegate: MasterViewControllerDelegate?
let items = ["Item 1", "Item 2", "Item 3"]
override func viewDidLoad() {
super.viewDidLoad()
title = "Master"
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
delegate?.didSelectItem(items[indexPath.row])
}
}
class DetailViewController: UIViewController, MasterViewControllerDelegate {
let detailLabel = UILabel()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
setupLabel()
}
func setupLabel() {
detailLabel.frame = CGRect(x: 50, y: 100, width: 300, height: 50)
view.addSubview(detailLabel)
}
func didSelectItem(_ item: String) {
detailLabel.text = "Selected: \(item)"
}
}
class SplitViewController: UISplitViewController, UISplitViewControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let masterVC = UINavigationController(rootViewController: MasterViewController())
let detailVC = UINavigationController(rootViewController: DetailViewController())
self.viewControllers = [masterVC, detailVC]
self.delegate = self
self.preferredDisplayMode = .oneBesideSecondary
if let master = masterVC.viewControllers.first as? MasterViewController,
let detail = detailVC.viewControllers.first as? DetailViewController {
master.delegate = detail
}
}
}
// Setting SplitViewController as the root in SceneDelegate
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(
_ scene: UIScene,
willConnectTo session: UISceneSession,
options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }
window = UIWindow(windowScene: windowScene)
window?.rootViewController = SplitViewController()
window?.makeKeyAndVisible()
}
}
✅ This creates a functional UISplitViewController with a Master-Detail interface!
7. Summary
✔️ UISplitViewController
is ideal for iPad apps and works with adaptive layouts.
✔️ Supports multiple display modes for better user experience.
✔️ Automatically collapses on smaller screens like iPhones.
✔️ Uses delegates or NotificationCenter to pass data between Master and Detail views.
Would you like help with customizing animations or transitions in UISplitViewController
? 🚀