     }
     buttonBarViewController.didMove(toParent: self)
     self.buttonBarViewController = buttonBarViewController
+
+    updateSplitViewDetailVisibility(for: nil, animated: false)
+  }
+
+  override func viewWillTransition(to size: CGSize,
+                                   with coordinator: UIViewControllerTransitionCoordinator) {
+    // Update traits *before* calling `super`, which will delegate this call to children.
+    updateSplitViewTraits(for: size)
+    super.viewWillTransition(to: size, with: coordinator)
+  }
+
+  private func updateSplitViewTraits(for size: CGSize) {
+    guard let buttonBarViewController = buttonBarViewController else { return }
+
+    func overrideHorizontalSizeClassToCompact(_ vc: UIViewController) {
+      let horizontallyCompact = UITraitCollection(horizontalSizeClass: .compact)
+      setOverrideTraitCollection(horizontallyCompact, forChild: vc)
+    }
+
+    if traitCollection.userInterfaceIdiom == .pad {
+      if size.isWiderThanTall {
+        setOverrideTraitCollection(nil, forChild: buttonBarViewController)
+      } else {
+        overrideHorizontalSizeClassToCompact(buttonBarViewController)
+      }
+    } else {
+      overrideHorizontalSizeClassToCompact(buttonBarViewController)
+    }
+  }
+
+  private func updateSplitViewDetailVisibility(for vc: UIViewController?, animated: Bool) {
+    let duration = animated ? Metrics.defaultAnimationDuration : 0
+    let shouldShowDetail = vc.map { viewControllerBarItems.keys.contains($0) } ?? false
+    let preferredPrimaryColumnWidthFraction: CGFloat
+    if shouldShowDetail {
+      preferredPrimaryColumnWidthFraction = Metrics.preferredPrimaryColumnWidthFraction
+    } else {
+      preferredPrimaryColumnWidthFraction = preferredPrimaryColumnWidthFractionWhenDetailIsHidden
+    }
+
+    // If we're going to hide the detail, we must first pop any presented VCs to avoid reducing
+    // their width. Failing to do so can result in autolayout warnings or crashes with some
+    // MDC collection view layouts.
+    if !shouldShowDetail && presentedDetailViewController != nil {
+      detailNavController.popViewController(animated: false)
+      presentedDetailViewController = nil
+    }
+
+    UIView.animate(withDuration: duration) {
+      self.svController.preferredPrimaryColumnWidthFraction = preferredPrimaryColumnWidthFraction
+    }
   }
 
   func show(_ vc: UIViewController, with items: [ActionAreaBarItem]) {

  private let detailNavController: UINavigationController = {
    let nc = UINavigationController()
    nc.isNavigationBarHidden = true
    return nc
  }()

  // TODO: Make these non-optional
  private var buttonBarViewController: ActionAreaButtonBarViewController?
  private var svController: UISplitViewController?

  private var viewControllerBarItems: [UIViewController: BarItemMode] = [:]

  private var state: State = .normal {
    willSet {

    }

    didSet {
      guard let presentedDetailViewController = presentedDetailViewController else {
        fatalError("The state can only be changed when a detailViewController is shown.")
      }

      switch state {
      case .normal:
        if presentedDetailViewController.parent == nil {
          // If there's no `parent`, the detail was already dismissed, so we need to clean up.
          viewControllerBarItems.removeValue(forKey: presentedDetailViewController)
          updateActionAreaBar(for: navController.topViewController)
        } else {
          // Otherwise just update the actions
          updateActionAreaBar(for: presentedDetailViewController)
        }
      case .modal:
        updateActionAreaBar(for: presentedDetailViewController)
      }
    }
  }

  // MARK: - Initializers

  init() {
    precondition(FeatureFlags.isActionAreaEnabled,
