From e5503895cf69a89e4aae4c5325bc8508b0a2fb70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gwendal=20Roue=CC=81?= Date: Tue, 21 May 2019 10:36:34 +0200 Subject: [PATCH] Introduce FloatingPanelController.begin/endUpdateLayout() --- .../Sources/FloatingPanelController.swift | 20 +++++++++++++++++++ Framework/Sources/FloatingPanelLayout.swift | 20 +++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/Framework/Sources/FloatingPanelController.swift b/Framework/Sources/FloatingPanelController.swift index 97d0871c..6e0637ef 100644 --- a/Framework/Sources/FloatingPanelController.swift +++ b/Framework/Sources/FloatingPanelController.swift @@ -516,6 +516,26 @@ open class FloatingPanelController: UIViewController, UIScrollViewDelegate, UIGe setUpLayout() } + /// Prepares an update to the layout object from the delegate. + /// + /// This method must eventually be balanced with a call to endUpdateLayout(). + /// It can be called in an animation block. + public func beginUpdateLayout() { + floatingPanel.layoutAdapter.beginUpdateHeight() + } + + /// Balances a previous call to beginUpdateLayout(), and updates the layout + /// object from the delegate and lays out the views managed by the + /// controller immediately. + /// + /// This method updates the `FloatingPanelLayout` object from the delegate and + /// then it calls `layoutIfNeeded()` of the root view to force the view + /// to update the floating panel's layout immediately. It can be called in an + /// animation block. + public func endUpdateLayout() { + updateLayout() + } + /// Returns the y-coordinate of the point at the origin of the surface view. public func originYOfSurface(for pos: FloatingPanelPosition) -> CGFloat { switch pos { diff --git a/Framework/Sources/FloatingPanelLayout.swift b/Framework/Sources/FloatingPanelLayout.swift index c0774766..ac1e1471 100644 --- a/Framework/Sources/FloatingPanelLayout.swift +++ b/Framework/Sources/FloatingPanelLayout.swift @@ -412,6 +412,26 @@ class FloatingPanelLayoutAdapter { } } + // Support for FloatingPanelController.beginUpdateLayout/endUpdateLayout. + // + /// This method must eventually be balanced with a call to updateHeight(). + func beginUpdateHeight() { + guard vc != nil else { return } + + // Deactivate the hard height constraint until updateHeight() + if let const = self.heightConstraint { + NSLayoutConstraint.deactivate([const]) + } + + // Activate a very weak temporary height constraint which makes sure the + // surface view is not totally free-form. + let heightConstraint = surfaceView.heightAnchor.constraint(equalToConstant: 0) + heightConstraint.priority = UILayoutPriority(1) + + NSLayoutConstraint.activate([heightConstraint]) + self.heightConstraint = heightConstraint + } + func updateInteractiveTopConstraint(diff: CGFloat, allowsTopBuffer: Bool) { defer { surfaceView.superview!.layoutIfNeeded() // MUST call here to update `surfaceView.frame`