             // offscreen.
             startInstalling(newValue, animated: animated)
 
-            UIView.performWithoutAnimation(view.layoutIfNeeded)
-
-            paletteContainer.transform = animated ? CGAffineTransform(translationX: 0, y: paletteContainer.bounds.height) : .identity
-
-            completion = { _ in
-                self.finishInstalling(newValue)
-            }
+            UIView.performWithoutAnimation {
+                self.view.layoutIfNeeded()
+                paletteContainer.transform = animated ? CGAffineTransform(translationX: 0, y: paletteContainer.bounds.height) : .identity
+            }
+
+            paletteTransformAtEnd = .identity
+
+            completion = { _ in }
         case let (oldValue?, newValue?) where oldValue !== newValue:
             // Transition from a to b. Not really animated, but this is expected
             // to be rare; could throw in fade or something instead.
             startUninstalling(oldValue, animated: animated)
             startInstalling(newValue, animated: animated)
 
+            paletteTransformAtEnd = .identity
+
             completion = { _ in
                 self.finishUninstalling(oldValue)
-                self.finishInstalling(newValue)
             }
         case (let oldValue?, nil):
             // Collapse the palette to animate offscreen - don't slide so we
             // don't do a layout pass on the moribund view controller.
             startUninstalling(oldValue, animated: animated)
 
-            let constraint = paletteContainer.contentView.heightAnchor.constraint(equalToConstant: 0)
-            constraint.isActive = true
+            paletteTransformAtEnd = animated ? CGAffineTransform(translationX: 0, y: paletteContainer.bounds.height) : .identity
 
             completion = { _ in
-                constraint.isActive = false
                 self.finishUninstalling(oldValue)
             }
         default:

        // Rather than duration = 0 when not animated, spare extra layout.
        if animated {
            UIView.animate(withDuration: 0.35, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 0, options: .beginFromCurrentState, animations: {
                self.paletteContainer.transform = .identity
                self.view.layoutIfNeeded()
            }, completion: completion)
        } else {

    /// If `animated` is `true`, will also reflow the content of the selected
    /// view controller.
    func setPaletteViewController(_ newValue: UIViewController?, animated: Bool) {
        let paletteTransformAtEnd: CGAffineTransform
        let completion: (Bool) -> Void

        let oldValue = paletteViewController
