如何在 SwiftUI 中禁用 ScrollView 弹跳

问题描述 投票:0回答:7

有任何

Modifier
可以阻止
ScrollView
swiftUI
的反弹吗?

struct RoomDetailsView: View {

    var body: some View {
        ScrollView(showsIndicators: false) {
            Image("test")
            Text("Hello Text")
            ...
            ...
        }
    }
}

我尝试了下面的代码,但它对我不起作用。看起来它已被弃用

ScrollView(alwaysBounceVertical: true) {
       Image("test")
       Text("Hello Text")
       ...
       ...
}
scrollview swiftui bounce
7个回答
36
投票

尝试使用这行代码:

UIScrollView.appearance().bounces = false

您可以这样使用它:-

struct RoomDetailsView: View {
   init() {
      UIScrollView.appearance().bounces = false
   }

   var body: some View {
      ScrollView(showsIndicators: false) {
         Image("test")
         Text("Hello Text")
         ...
         ...
          }
      }
  }

或者您可以在 AppDelegate 中编写此行,以将此行为应用到您的应用程序中。

 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    UIScrollView.appearance().bounces = false
 }

10
投票
  1. 将 ScrollView 的 shownIndicators 参数设置为 false,以便与视图交互的用户不会激活滚动指示器(即使未启用滚动也可能发生)。
ScrollView(showsIndicators: false)
  1. 在 ScrollView 的 onAppear 修饰符中,添加此行。
UIScrollView.appearance().bounces = false
  1. 在 ScrollView 的 onDisappear 修饰符中,添加此行。
UIScrollView.appearance().bounces = true

如果您在 init 中将 UIScrollView.appearance().bounces 设置为 false,它将阻止您应用程序的所有 ScrollView 弹跳。通过在 onAppear 修饰符中将其设置为 true 并在 onDisappear 修饰符中将其设置为 false,可以确保它只影响一个 ScrollView。

你的 ScrollView 应该看起来像这样。

ScrollView(showsIndicators: false) {
    ...
    ...
    ...
}
.onAppear {
    UIScrollView.appearance().bounces = false
}
.onDisappear {
    UIScrollView.appearance().bounces = true
}

7
投票

Apple 在 iOS 16.4 中引入了一个名为

scrollBounceBehavior
的新修饰符,可用于防止 ScrollView 在内容小于屏幕时弹起。

https://developer.apple.com/documentation/swiftui/view/scrollbouncebehavior(_:axes:)

struct RoomDetailsView: View {

    var body: some View {
        ScrollView(showsIndicators: false) {
            Image("test")
            Text("Hello Text")
            ...
            ...
        }
        .scrollBounceBehavior(.basedOnSize)
    }
}

6
投票

您可以使用 SwiftUI-Introspect 库:

ScrollView {
    // some content
}
.introspectScrollView { scrollView in
    scrollView.alwaysBounceVertical = false
}

1
投票

更好的解决方案是使用 viewbuilder 并创建自己的滚动视图,当内容大小小于滚动视图框架大小时,该滚动视图不会弹起。

import SwiftUI

struct BounceVerticalDisableScrollView<Content: View>: View {
    
    @State private var alwaysBounceVertical = false
    let content: Content
    
    init(@ViewBuilder content: () -> Content) {
        self.content = content()
    }
    
    var body: some View {
        GeometryReader { scrlViewGeometry in
            ScrollView {
                content
                    .background(
                        GeometryReader {
                            // calculate height by clear background
                            Color.clear.preference(key: SizePreferenceKey.self,
                                                   value: $0.frame(in: .local).size.height)
                        }.onPreferenceChange(SizePreferenceKey.self) {
                            self.alwaysBounceVertical = $0 < scrlViewGeometry.size.height
                        }
                    )
            }
            // disable scroll when content size is less than frame of scrollview
            .disabled(self.alwaysBounceVertical)
        }
    }
}
// return size
public struct SizePreferenceKey: PreferenceKey {
    public static var defaultValue: CGFloat = .zero
    
    public static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) {
        value += nextValue()
    }
}

因此,您可以将滚动视图用作:

var body: some View {
        VStack (alignment: .leading, spacing: 10) {
            BounceVerticalDisableScrollView{
                VStack (alignment: .leading, spacing: 10)  {
                   ....
                   .... 
                }.padding()
            }
            
        }
    }  
 

0
投票

老实说,可用的选项并不是很好,因为它们不向后兼容并且往往完全禁用滚动。

解决方法是增加滚动视图的高度。


0
投票

我创建了一个小的ViewModifier,以便在特定视图中禁用滚动弹跳:

import SwiftUI

extension View {
  func disableBounces() -> some View {
    modifier(DisableBouncesModifier())
  }
}

struct DisableBouncesModifier: ViewModifier {
  func body(content: Content) -> some View {
    content
      .onAppear {
        UIScrollView.appearance().bounces = false
      }
      .onDisappear {
        UIScrollView.appearance().bounces = true
      }
  }
}

然后你可以简单地在你的视图上调用它作为任何普通的 viewModifier

// Your view definition... 
.disableBounces()
© www.soinside.com 2019 - 2024. All rights reserved.