You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI如何禁用ScrollView顶部上滑与底部下滑的弹性滚动

问题描述
  • 正常滚动视图效果:滚动视图正常显示效果
  • 不希望出现的效果:不希望出现的效果

我希望禁止用户在ScrollView已处于顶部时继续上滑,或处于底部时继续下滑,请问实现该需求的最佳方案是什么?


分平台实现方案

Android 端

通过自定义ScrollView,重写触摸事件拦截逻辑:

public class CustomScrollView extends ScrollView {
    private float startY;

    public CustomScrollView(Context context) {
        super(context);
    }

    public CustomScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CustomScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        int scrollY = getScrollY();
        int scrollRange = getChildAt(0).getHeight() - getHeight();

        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                startY = ev.getY();
                return super.onTouchEvent(ev);
            case MotionEvent.ACTION_MOVE:
                float deltaY = ev.getY() - startY;
                // 顶部状态下拦截上滑操作
                if (scrollY == 0 && deltaY > 0) {
                    return true;
                }
                // 底部状态下拦截下滑操作
                if (scrollY >= scrollRange && deltaY < 0) {
                    return true;
                }
                break;
        }
        return super.onTouchEvent(ev);
    }
}

使用时直接在布局文件中替换原生ScrollView为该自定义类即可。

iOS 端

自定义UIScrollView,通过手势代理拦截无效滑动:

class CustomScrollView: UIScrollView {
    override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        guard let panGesture = gestureRecognizer as? UIPanGestureRecognizer else {
            return super.gestureRecognizerShouldBegin(gestureRecognizer)
        }
        
        let translation = panGesture.translation(in: self)
        // 顶部拦截上滑
        if contentOffset.y <= -contentInset.top && translation.y > 0 {
            return false
        }
        // 底部拦截下滑
        let bottomOffset = contentSize.height - bounds.height + contentInset.bottom
        if contentOffset.y >= bottomOffset && translation.y < 0 {
            return false
        }
        
        return super.gestureRecognizerShouldBegin(gestureRecognizer)
    }
}

替换原生UIScrollView为该自定义类,即可限制边界处的无效滑动。

Web 端

监听触摸事件,拦截边界处的滑动行为:

const scrollContainer = document.querySelector('.scroll-container');
let startY = 0;

scrollContainer.addEventListener('touchstart', (e) => {
    startY = e.touches[0].clientY;
});

scrollContainer.addEventListener('touchmove', (e) => {
    const currentY = e.touches[0].clientY;
    const deltaY = currentY - startY;
    
    // 顶部拦截上滑
    if (scrollContainer.scrollTop === 0 && deltaY > 0) {
        e.preventDefault();
    }
    // 底部拦截下滑
    const isAtBottom = scrollContainer.scrollTop + scrollContainer.clientHeight >= scrollContainer.scrollHeight;
    if (isAtBottom && deltaY < 0) {
        e.preventDefault();
    }
});

配合CSS确保事件拦截生效:

.scroll-container {
    overflow: scroll;
    touch-action: none;
}

内容的提问来源于stack exchange,提问作者Amin Bagheri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 07:50:25