ScrollView 中的 SwiftUI TabView

Posted

技术标签:

【中文标题】ScrollView 中的 SwiftUI TabView【英文标题】:SwiftUI TabView inside a ScrollView 【发布时间】:2021-05-19 19:56:10 【问题描述】:

问题:我的TabViewPageTabViewStyle 的内容高度不同。我可以在不同的页面之间滑动,但是在ScrollView 内部,我的TabView 会缩小到 0 高度。

预期:TabView 具有最大子视图的高度。

我之前也遇到过类似的问题,只是硬编码了最大视图的近似帧高度,但这似乎不是正确的方法。任何想法都非常感谢。

struct ContentView: View 
    var body: some View 
//        ScrollView 
            VStack 
                TabView 
                    ForEach(1..<5, id:\.self)  index in
                        VStack 
                            DifferentSizeViews(times: index)
                            Spacer()
                        
                    
                
                .tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
                
                Text("Some other content")
            
        
//    


struct DifferentSizeViews: View 
    var times: Int
    var body: some View 
        VStack 
            ForEach(0..<times, id:\.self)  index in
                Text("some text \(index)")
            
        
    

【问题讨论】:

正如你所说的“我的带有 PageTabViewStyle 的 TabView 具有不同高度的内容。”。在我看来,您应该将 ScrollView 放在内容视图(DifferentSizeViews)中。 如果我将 ScrollView 放在内容视图中,则 TabView 将调整为 0 高度 对于我来说,在 DifferentSizeViews 中的 ScrollView 都很好用。在 macos 11.4、xcode 12.5、目标 ios 14.5 和 macCatalyst。你用的是什么系统? 你找到解决办法了吗? 【参考方案1】:

经过数小时的痛苦后,我找到了这个解决方案。希望对您有所帮助。

@State var selection: Int = 0
@State var height: CGFloat = 0

@State var sizeArray: [CGSize] = [.zero, .zero, .zero]
@State var initialHeight: CGFloat = 0

var body: some View 
    ScrollView 
        VStack(spacing: 0) 
            Color.red
                .frame(height: 100)
            
            TabView(selection: $selection) 
                Text("1\n1\n1")
                    .fixedSize()
                    .readSize(onChange:  size in
                        sizeArray[0] = size
                        if initialHeight == 0 
                            initialHeight = size.height
                        
                    )
                    .tag(0)
                Text("2\n2\n2\n2\n2")
                    .fixedSize()
                    .readSize(onChange:  size in
                        sizeArray[1] = size
                    )
                    .tag(1)
                Text("3")
                    .fixedSize()
                    .readSize(onChange:  size in
                        sizeArray[2] = size
                    )
                    .tag(2)
            
            .tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
            .background(Color.white)
            .frame(height: height)
            .onChange(of: selection)  newValue in
                withAnimation 
                    height = sizeArray[newValue].height
                
            
            .onChange(of: initialHeight)  newValue in
                height = newValue
            
        
    
    .background(Color.green)

还有View 分机

extension View 
    func readSize(onChange: @escaping (CGSize) -> Void) -> some View 
        background(
            GeometryReader  geometryProxy in
                Color.clear
                    .preference(key: SizePreferenceKey.self, value: geometryProxy.size)
            
        )
            .onPreferenceChange(SizePreferenceKey.self, perform: onChange)
    

【讨论】:

以上是关于ScrollView 中的 SwiftUI TabView的主要内容,如果未能解决你的问题,请参考以下文章

水平 ScrollView (SwiftUI) 中的动画展开/折叠组

ScrollView 中的 SwiftUI TabView

SwiftUI:在 ScrollView 中居中内容

ScrollView 中的动画缺少 SwiftUI 中的最后一个对象

使 ScrollView 中的滚动条在 SwiftUI 中始终可见

UITextView 在 SwiftUI 中可表示不尊重 ScrollView 中的宽度界限