Removed the `pre > .zero` condition from `FloatingPanelLayoutAnchor` as it was not appropriate for zero or negative `absoluteInset` values.
Added documentation for `shouldScrollingContentInMoving(from:to:)` to prevent similar mistakes in the future.
use a separate `scrollLocked` var instead of abusing the scrollView's properties to store the locked state;
fixes an issue where the scroll indicators were no longer visible because lockScrollView() was executed twice before unlockScrollView() was called (due to the user changing `showsVerticalScrollIndicator` mid-animation);
The state was not changed after moving a panel without attractive
interaction. For example, a panel is moved from half to full and
the scroll content continues to scroll with its deceleration
animation. We can test it on 'Show tracking(TextView)' in Samples app.
dbef6a6 commit causes this issue.
This is because the `state` argument of `Core.isScrollable(state:)` is
not always equal to `FloatingPanelController.state` property. Therefore,
the API should pass the `state` property of `Core.isScrollable(state:)`.
On `DebugTableViewController` in the Samples app, the panel does not move
when a finger move up from the menu area to the grabber area.
`scrollViewFrame` is not necessary due to the same condition is already
checked at Core.swift:L578.
The new `floatingPanel(_:shouldAllowToScroll)` delegate method allows the
library user to determine whether the content scrolls or not in certain
state. `Core.isScrollable(state:)` and `LayoutAdpter.offset(from:)` are
added for this feature.
In Maps example, the scroll indicator of the table view doesn't show
even if `UIScrollView.showsVerticalScrollIndicator` is set to `true`.
This is due to the occurrence of two loose scroll locks before the
scroll content is displayed.
Sometimes, the content offset of the tracking scroll view would become
less than the content inset (e.g. when a panel moves from half to full
state displaying content with a top bar similar to 'Show Navigation
Controller' in the Samples app). This resulted in the content getting
fixed in an unintended position.
For this issue, this commit completely changes the scroll offset pinning
logic from one shot pinning by DispatchQueue at Core:L43-L56
That old logic was added when the UIViewPropertyAnimator was used to move
the panel. But now, the custom animator using CADisplayLink allows
fine-grained control of panel movement and then the scroll offset is
able to be pinned during its panel transitions.
Previously, the panel might not consistently keep its scroll content
offset when moving from its most expanded state to another.
Changes made in this commit:
* Keep the content offset of tracking scroll view in the following cases.
A panel is moved...
1. Outside of the tracking scroll view.
2. Inside of a navigation bar/toolbar over the tracking scroll view.
* Stopped the scroll offset reset of the `stopScrollDeceleration` flag
in the `panningEnd` method when the panel transitions from its most
expanded state because there is no issue without the reset.
These issues arose in 'Show Navigation Controller' sample of Samples app.
1. The scrollView's contentOffset always becomes (0, 0) instead of (0, -44),
which is normal if there is a UINavigationBar.
2. The scrollView's contentOffset sometimes becomes (0, 0) after moving
a panel quickly like picking.
Case 1 is caused by 7511ce5 commit.
Case 2 is caused by a workaround added at 81fd85e commit.
I tested this library from iOS 11 to iOS 16, and then I confirmed this
workaround doesn't need anymore.
Related to #602, #603.
This problem arose after 6611ec8 commit. The root cause is linked to
this condition: `0 == layoutAdapter.offsetFromMostExpandedAnchor` at
line 589 in the method `Core.shouldScrollViewHandleTouch(_:point:velocity:)`.
If the value of `layoutAdapter.offsetFromMostExpandedAnchor` has a
floating point error, the condition evaluates to false. As a result,
the panel moves even when the tracking scroll view is intended to
scroll.
This problem may not occur if there is no floating point error.
The Logging API document says that `os_log` is one of the legacy logging
symbols. However, this library needs to be supported below iOS 14 so
`log(level:_:)` cannot be used.
This was noticed when updating contained SwiftUI views rapidly.
This change is what fixed a certain bug the scroll content can be locked at a negative offset. It was most obvious when the whitespace was large, hence the offset was something around -100.0. At the same time, the contents (like buttons) were non-interactive.
Co-authored-by: Sören Gade <soeren.gade@lichtblick.de>
This is the revised version of commit 448fc5c.
Commit 448fc5c has a critical regression in scroll tracking that can cause the
scroll content to bounce after moving a panel, for example, pulling down it from
full to half state.
By re-investigating #524, I found that this problem only occurred with the
`fitToBounds` content mode and a small scroll view content.
Therefore I fixed it in the more specific way.
UIScrollView would unexpectedly change its scroll offset after updating the bounces property when dealing with small scrollable content. This fixes issue #524, "Scrolling jumps when tableView content is small".
This commit sets the initial scroll offset to the pinning offset.
The previous implementation, which set it to the current content offset,
leads various scroll tracking bugs. This reproduction is one of issues.
Using 'Scroll tracking(UITableView)' in Samples app.
1. Bounce the scroll content at the top most anchor.
2. Pull down the panel in bouncing at a minus content offset. (the
scroll content stops at the minus offset.)
3. Pull up it
The previous implementation was implemented for #526/#527. But now the
issue hasn't been reproduced in v2.5.6.
This fixes#572 to change the backdrop alpha when the view size or
its size class changes.
The main change is that `true` is passed as a
`forceLayout` parameter into `viewWillTransition(to:with:)` callbacks.
Because it's necessary for the backdrop alpha's update when the view
size or its size class changes.
This also fixes a regression at `9c45c31` commit.
```diff
- layoutAdapter.activateLayout(for: state, forceLayout: true)
+ layoutAdapter.activateLayout(for: state, forceLayout: forceLayout)
```
The behavior before the above change indicates that the method has
worked well even when `forceLayout` is set to `true` in their callbacks.
Additional improvements:
* Format `activateLayout(forceLayout:contentInsetAdjustmentBehavior:)`
* Add `_floor` function for `test_updateBackdropAlpha()`
The backdrop alpha of a panel must be updated only in `Controller.show(animated:completion:)`.
Because that prevents a backdrop flicking just before presenting a panel.
Resolve#466.
* Add test_updateBackdropAlpha
* Fix backdrop alpha's flickers in Maps.app
This issue occurs when swinging down a panel with all one's might.
The trigger is here.
```
func floatingPanelWillEndDragging(_ vc: FloatingPanelController, withVelocity velocity: CGPoint, targetState: UnsafeMutablePointer<FloatingPanelState>) {
if targetState.pointee != .full {
owner.searchVC.hideHeader(animated: true)
}
if targetState.pointee == .tip {
>>> vc.contentMode = .static
}
}
```
However, any library users expect to affect the backdrop by this code.
And then I reconsidered the reason why the backdrop alpha changes in
activateLayout(for:forceLayout:) and it's because the animation using
CAAnimation on v1.
Therefore I decided to move the point to change the backdrop alpha into
the move animation's completion handler.
And also the responsibility of `setBackdropAlpha(of:)` was moved into
`Core` because `Core` takes on a role of changing the backdrop alpha.