简体   繁体   English

SwiftUI - LazyVStack pinnedViews in another

[英]SwiftUI - LazyVStack pinnedViews in another

How to create something like this如何创建这样的东西

LazyVStack(spacing: 0, pinnedViews: [.sectionHeaders]) {
    Section(header: Text("foo") ) {
        LazyVStack(spacing: 0, pinnedViews: [.sectionHeaders]) {
            Section (header: Text("bar") ) {
                Text("1")
                Text("2")
                ...
            }
            Section (header: Text("baz") ) {
                Text("1")
                Text("2")
                ...
            }
        }
    }
}

I need two fixed header but in this solution headers colide when fixed position我需要两个固定的标头,但在此解决方案中,标头在固定位置时会发生碰撞

Thanks谢谢

You can give the sub headers a background (in white / bg color), and also have to push the first header back using zIndex .您可以为子标题提供背景(白色/ bg 颜色),并且还必须使用zIndex将第一个标题推回。

在此处输入图像描述

struct ContentView: View {
    var body: some View {
        ScrollView {
            LazyVStack(alignment: .leading, pinnedViews: [.sectionHeaders]) {

                Section(header:
                    Text("Overall Header")
                    .zIndex(-1) // zIndex here
                ) {
                    
                    LazyVStack(alignment: .leading, pinnedViews: [.sectionHeaders]) {
                        
                        Section (header:
                                    Text("Header One")
                            // give background here
                            .frame(maxWidth: .infinity, alignment: .leading)
                            .background(.gray)
                        ) {
                            ForEach(0..<30) { item in
                                Text("Item \(item)")
                            }
                        }

                        Section (header:
                                    Text("Header Two")
                                 // give background here
                                 .frame(maxWidth: .infinity, alignment: .leading)
                                 .background(.gray)
                        ) {
                            ForEach(0..<50) { item in
                                Text("Item \(item)")
                            }
                        }
                    }
                }
            }
        }
        .font(.title2)
        .padding()
    }
}

Here is some hack :)这是一些技巧:)
It' using the package "SwiftUITrackableScrollView" to be found here: "https://github.com/maxnatchanon/trackable-scroll-view".它使用包“SwiftUITrackableScrollView”可以在这里找到:“https://github.com/maxnatchanon/trackable-scroll-view”。
But there are several solutions for a trackable scrollview you can find, or implement one by yourself.但是您可以找到几种可跟踪滚动视图的解决方案,或者自己实现一个。

It works fine, the only problem is to get/define the relevant positions of headers.它工作正常,唯一的问题是获取/定义标题的相关位置。 Its easy if you have a predefined/fixed item height.如果您有预定义/固定的项目高度,这很容易。

在此处输入图像描述

import SwiftUI
import SwiftUITrackableScrollView


struct MyHeaders: Identifiable {
    let id = UUID()
    let title: String
    let position: CGFloat
    var active: Bool = false
}


struct ContentView: View {
    
    @State private var offset = CGFloat.zero // Content offset available to use

    @State private var myHeaders = [
        MyHeaders(title: "Outer Header One", position: 0),
        MyHeaders(title: "Inner Header One", position: 0),
        MyHeaders(title: "Inner Header Three", position: 264),
        MyHeaders(title: "Outer Header Two", position: 525),
        MyHeaders(title: "Inner Header Three", position: 525),
    ]

    var body: some View {
        
        TrackableScrollView(.vertical, showIndicators: false, contentOffset: $offset) {
            LazyVStack(alignment: .leading) {
                
                Text("Outer Header One")

                Text("Inner Header One")
                ForEach(0..<10) { item in
                    Text("Item \(item)")
                }
                Text("Inner Header Two")
                ForEach(0..<10) { item in
                    Text("Item \(item)")
                }

                Text("Outer Header Two")

                Text("Inner Header Three")
                ForEach(0..<30) { item in
                    Text("Item \(item)")
                }
                
            }
        }
        .onChange(of: offset) { newValue in
            print(offset)
            for i in 0..<myHeaders.count {
                myHeaders[i].active = myHeaders[i].position < offset
            }
        }
        .overlay(
            VStack(alignment: .leading) {
                ForEach(myHeaders) { header in
                    if header.active {
                        Text(header.title)
                    }
                }
            }
                .frame(maxWidth: .infinity, alignment: .leading)
                .foregroundColor(.orange)
                .background(.background)
            , alignment: .topLeading
        )
        .font(.title2)
        .padding()
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM