Read the original article:How to Achieve Elastic Distance at the Edge of Swiper Control
Problem Description
When using Swiper to display content, elastic stretching can be triggered by swiping up or down when the list is at the first or last item. However, the distance of the elastic stretching is too long. Is it possible to set the height of the elastic stretching in Swiper?
Background Knowledge
For Swiper-related content, you can refer to the official documentation Swiper API. The official documentation does not provide a ready-made interface to set the edge bounce distance, so some modifications are needed based on the existing interfaces.
Troubleshooting Process
-
Reproduce & baseline
- Put a
Swiperwith 3–5 items in a simple page. - Swipe past the first/last item vertically and note the overscroll distance (~2/5 of screen).
- Confirm the default edge effect is enabled (the “stretch”/bounce is visible).
- Put a
-
Check for a public API
- Review
Swiperprops & methods (EffectMode,index,onChange, etc.). - Result: No public prop controls the edge-bounce distance (as stated in docs).
- Review
-
Disable system effect
- Set
.EffectMode(EdgeEffect.None)onSwiper. - Expected: built-in stretch is gone; you’ll now need to implement your own.
- Set
-
Prototype a custom overscroll
- Attach a
PanGesture({ direction: PanDirection.Vertical })via.parallelGesture(...). - Track
offsetYonly when:-
index == 0andoffsetY > 0(pulling down at first item), or -
index == lastIndexandoffsetY < 0(pulling up at last item).
-
- Apply
translate({ y: traY })to the visible slide.
- Attach a
Analysis Conclusion
- Root cause:
Swiperdoes not expose any public API to configure the built-in edge-bounce distance. The default system effect can feel too elastic (≈ 2/5 screen). -
Resolution approach: Disable the system edge effect with
.EffectMode(EdgeEffect.None), then implement a custom overscroll using a verticalPanGesturethat:- Activates only at the first/last slide,
- Clamps the translation to a small, predictable limit (e.g., 48–64vp),
- Applies nonlinear resistance for a natural “rubber-band” feel, and
- Animates back quickly on release.
Solution
You can disable the built-in edge bounce effect of Swiper and use a custom edge bounce action. Refer to the following code:
Swiper(this.swiperController) {
Text() // Carousel content
.translate({
x: this.traX,
y: this.traY // Offset set to the captured offset
})
}
.EffectMode(EdgeEffect.None) // Disable built-in edge effects
.parallelGesture(
PanGesture({ direction: PanDirection.Vertical })
.onActionUpdate((event) => {
// Control the sliding distance here, the first one slides down
if (this.index == 0 && event.offsetY < 50) {
this.traY = event.offsetY
}
// Control the sliding distance here, the last one slides up
if (this.index == this.data.totalCount() - 1 && event.offsetY > -50) {
this.traY = event.offsetY
}
})
.onActionEnd((event) => {
console.info(JSON.stringify(event))
animateTo({
duration: 100, // Here you can control the rebound speed
curve: Curve.EaseOut,
iterations: 1,
playMode: PlayMode.Normal,
onFinish: () => {
console.info('play end')
}
}, () => {
this.traY = 0
})
})
)
Verification Result
In cases where the system interface behavior does not align with expectations, the default functionality of the system interface can be disabled, and the relevant interfaces can be rewritten to achieve the desired outcome.
Top comments (0)