SwiftUI ScrollView 中的默认空间

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

我正在尝试创建一个自定义滚动视图,如果用户滚动到末尾,它可以通知父视图。

这就是我的实现方式:

struct CustomVerticalScrollView<Content: View>: View {
    let content: Content
    
    init(@ViewBuilder content: () -> Content) {
        self.content = content()
    }
    
    var body: some View {
        ScrollView {
            content
            
            Color
                .clear
                .frame(width: 0, height: 0)
                .modifier(ViewAppearsOnScreen())
                .onPreferenceChange(IsOnScreenKey.self) { value in
                    if value == true {
                        print("Has reached end!")
                    }
                }
        }
        .background(.green)
    }
}

struct ViewAppearsOnScreen: ViewModifier {
    func body(content: Content) -> some View {
        GeometryReader { geometry in
            // Check if this view's frame intersects with the visible screen bounds
            content
                .preference(
                    key: IsOnScreenKey.self,
                    value: isViewVisible(geometry: geometry)
                )
        }
    }
    
    // Determines if the view is visible within the screen's bounds
    private func isViewVisible(geometry: GeometryProxy) -> Bool {
        let frame = geometry.frame(in: .global) // Get the frame in global space
        let screenBounds = UIScreen.main.bounds // Screen boundaries
        
        return screenBounds.intersects(frame) // Check if it intersects with screen bounds
    }
}

此处用于检测滚动视图结束的代码取自此answer

然后这就是我的使用方式:

struct ContentView: View {
    var body: some View {
        
        CustomVerticalScrollView{
            VStack(spacing: .zero) {
                Color
                    .blue
                    .frame(maxWidth: .infinity)
                    .frame(height: 1000)
            }
        }
    }
}

该功能运行良好,但是,这给了我以下带有一些额外间距的结果:

Custom scrollview swiftUI end of scroll reached

  1. 当我没有清晰的彩色视图时,它似乎没有在末尾添加任何间距,即使没有填充、间距并且视图的高度为0(表中的第三项)
  2. 当我添加清晰的颜色视图时,它在末尾添加了一些相当大的间距(表中的第一项)
  3. 如果我从表中的第二项中删除提到的两个修饰符,仍然有一些填充 - 可能几何阅读器在这里发挥作用

虽然将高度设置为 0 并使用几何读取器不会影响间距。

只是想知道如何消除所有这些额外的间距,以便我可以在其中获得额外的视图。

ios swift swiftui swiftui-scrollview
1个回答
0
投票
在这种情况下,

GeometryReader
会将自身调整到理想高度,该高度恰好是一个小的非零值。您可以将
frame(width: 0, height: 0)
移至
onPreferenceChange
之后来修复此问题。

每个 SwiftUI 视图在所有四个边缘上都有自己的“首选间距”,并且此间距可能会根据其他视图的类型而有所不同。例如,

Text
Image
之间的首选间距比两个
Text
之间的首选间距稍大。默认布局行为遵循此间距首选项。在实现您自己的
Layout
时,您可以使用
LayoutSubview.spacing
读取此首选间距。

使用带有显式

VStack
参数的
spacing:
会使
VStack
布局不尊重间距首选项。

ScrollView {
    VStack(spacing: 0) {
        content
        Color
            .clear
            .modifier(ViewAppearsOnScreen())
            .onPreferenceChange(IsOnScreenKey.self) { ... }
            .frame(width: 0, height: 0)
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.