Skip to content

Commit

Permalink
Fix an invalid behavior after switching to a new layout object (#611)
Browse files Browse the repository at this point in the history
* Added a test for the use case, ControllerTests.test_switching_layout()
  • Loading branch information
scenee committed Nov 4, 2023
1 parent dd23888 commit dbef6a6
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 7 deletions.
4 changes: 3 additions & 1 deletion Sources/Core.swift
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,9 @@ class Core: NSObject, UIGestureRecognizerDelegate {
contentOffset = scrollView?.contentOffset
}

if layoutAdapter.validStates.contains(state) == false {
state = layoutAdapter.initialState
}
layoutAdapter.updateStaticConstraint()
layoutAdapter.activateLayout(for: state, forceLayout: forceLayout)

Expand Down Expand Up @@ -725,7 +728,6 @@ class Core: NSObject, UIGestureRecognizerDelegate {
}

guard shouldAttract(to: target) else {
self.state = target
self.updateLayout(to: target)
self.unlockScrollView()
// The `floatingPanelDidEndDragging(_:willAttract:)` must be called after the state property changes.
Expand Down
6 changes: 0 additions & 6 deletions Sources/Layout.swift
Original file line number Diff line number Diff line change
Expand Up @@ -782,12 +782,6 @@ class LayoutAdapter {
NSLayoutConstraint.activate(constraint: self.fitToBoundsConstraint)
}

var state = state

if validStates.contains(state) == false {
state = layout.initialState
}

// Recalculate the intrinsic size of a content view. This is because
// UIView.systemLayoutSizeFitting() returns a different size between an
// on-screen and off-screen view which includes
Expand Down
30 changes: 30 additions & 0 deletions Tests/ControllerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,36 @@ class ControllerTests: XCTestCase {
fpc.move(to: .tip, animated: false)
XCTAssertEqual(fpc.surfaceView.frame.height, fpc.view.bounds.height - fpc.surfaceLocation(for: .tip).y)
}

func test_switching_layout() {
final class FirstLayout: FloatingPanelLayout {
let position: FloatingPanelPosition = .bottom
let initialState: FloatingPanelState = .half
let anchors: [FloatingPanelState : FloatingPanelLayoutAnchoring] = [
.full: FloatingPanelLayoutAnchor(absoluteInset: 16.0, edge: .top, referenceGuide: .safeArea),
.half: FloatingPanelLayoutAnchor(absoluteInset: 262, edge: .top, referenceGuide: .safeArea),
.tip: FloatingPanelLayoutAnchor(absoluteInset: 44.0, edge: .bottom, referenceGuide: .safeArea)
]
}
final class SecondLayout: FloatingPanelLayout {
let position: FloatingPanelPosition = .bottom
let initialState: FloatingPanelState = .half
let anchors: [FloatingPanelState : FloatingPanelLayoutAnchoring] = [
.half: FloatingPanelLayoutAnchor(absoluteInset: 262, edge: .top, referenceGuide: .safeArea)
]
}
let fpc = FloatingPanelController()
fpc.layout = FirstLayout()
fpc.showForTest()

fpc.move(to: .tip, animated: false)

// Switch to another layout
fpc.layout = SecondLayout()
fpc.invalidateLayout()

XCTAssertEqual(fpc.state, .half)
}
}

private class MyZombieViewController: UIViewController, FloatingPanelLayout, FloatingPanelBehavior, FloatingPanelControllerDelegate {
Expand Down

0 comments on commit dbef6a6

Please sign in to comment.