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

SwiftUI 中如何禁止 ScrollView 滚动超过指定的顶部边界位置

实现方案

你需要限制ScrollView的顶部滚动偏移,禁止下拉时内容超过顶部边界,根据你支持的iOS版本可以选择不同实现方式:

方案1:iOS 16+ 最简原生实现

直接使用系统提供的scrollBounceBehavior修饰符即可实现效果,代码改动最小:

import SwiftUI

struct ScrollViewIssue: View {
    var body: some View {
        ScrollView {
            VStack {
                Rectangle()
                    .foregroundColor(.gray)
                    .frame(height: 200)
                
                Circle()
                    .frame(width: 300, height: 300)
                Circle()
                    .frame(width: 300, height: 300)
                Circle()
                    .frame(width: 300, height: 300)
                Circle()
                    .frame(width: 300, height: 300)
            }
        }
        // 禁用垂直方向顶部弹跳效果
        .scrollBounceBehavior(.basedOnSize, axes: .vertical)
        .ignoresSafeArea()
    }
}

方案2:全iOS版本兼容实现

如果需要支持iOS15及更低版本,可以通过桥接底层UIScrollView,在滚动代理中强制限制顶部偏移量:

import SwiftUI
import UIKit

struct NoTopBounceScrollView<Content: View>: UIViewRepresentable {
    let content: Content
    
    init(@ViewBuilder content: () -> Content) {
        self.content = content()
    }
    
    func makeUIView(context: Context) -> UIScrollView {
        let scrollView = UIScrollView()
        scrollView.delegate = context.coordinator
        scrollView.showsVerticalScrollIndicator = true
        
        let hostingView = UIHostingController(rootView: content).view!
        hostingView.translatesAutoresizingMaskIntoConstraints = false
        scrollView.addSubview(hostingView)
        
        NSLayoutConstraint.activate([
            hostingView.topAnchor.constraint(equalTo: scrollView.contentLayoutGuide.topAnchor),
            hostingView.bottomAnchor.constraint(equalTo: scrollView.contentLayoutGuide.bottomAnchor),
            hostingView.leadingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.leadingAnchor),
            hostingView.trailingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.trailingAnchor),
            hostingView.widthAnchor.constraint(equalTo: scrollView.frameLayoutGuide.widthAnchor)
        ])
        return scrollView
    }
    
    func updateUIView(_ uiView: UIScrollView, context: Context) {}
    
    func makeCoordinator() -> Coordinator {
        Coordinator()
    }
    
    class Coordinator: NSObject, UIScrollViewDelegate {
        func scrollViewDidScroll(_ scrollView: UIScrollView) {
            // 强制限制顶部偏移,禁止下拉超过内容顶部
            if scrollView.contentOffset.y < 0 {
                scrollView.contentOffset.y = 0
            }
        }
    }
}

// 业务层调用代码
struct ScrollViewIssue: View {
    var body: some View {
        NoTopBounceScrollView {
            VStack {
                Rectangle()
                    .foregroundColor(.gray)
                    .frame(height: 200)
                
                Circle()
                    .frame(width: 300, height: 300)
                Circle()
                    .frame(width: 300, height: 300)
                Circle()
                    .frame(width: 300, height: 300)
                Circle()
                    .frame(width: 300, height: 300)
            }
        }
        .ignoresSafeArea()
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 20:24:05