swift ScrollView在其上方的两个视图之间重叠,使内容显示在两个视图之间,如何修复?

nzkunb0c  于 2023-09-30  发布在  Swift
关注(0)|答案(1)|浏览(113)

我正在尝试做一个标签系统。它看起来像这样:

但是当我向上滚动时,scrollview内容在标签和标题之间溢出。

下面是我的代码:

你看到的风景

struct ItineraryDetailView: View {
    let itinerary: ItineraryDisplay
    @State var currentTab: Int = 0
    var body: some View {
        VStack {
            Text("\(itinerary.numberOfDays) Days in \(itinerary.city)")
                .font(.largeTitle)
                .frame(alignment: .center)
            
            ZStack(alignment: .top) {
                TabView(selection: self.$currentTab) {
                    ScrollView {
                        Spacer()
                            .frame(height: 60)
                        // Details
                        ForEach(Array(itinerary.activities.enumerated()), id: \.offset) { index, element in
                            Text("Day \(index + 1)")
                                .font(.title)
                            
                            ForEach(element, id: \.self) { activity in
                                VStack {
                                    Text("\u{2022} \(activity)")
                                        .padding(5)
                                }
                                .frame(minWidth: 0, maxWidth: .infinity, alignment: .leading) // Achieves the Text() alignment we want
                            }
                            
                            Divider()
                        }
                        .padding(5)
                    }
                    .tag(0)
                    
                    // Highlights
                    Text("hi")
                        .tag(1)
                }
                .tabViewStyle(.page(indexDisplayMode: .never))
                .edgesIgnoringSafeArea(.all)
                
                TopTabBarView(currentTab: self.$currentTab)
            }
        }
    }
}

自定义页签实现:

struct TopTabBarView: View {
    @Binding var currentTab: Int
    @Namespace var namespace

    var tabBarOptions: [String] = ["Plan", "Details"]
    var body: some View {
        ScrollView(.horizontal, showsIndicators: false) {
            HStack(spacing: 20) {
                ForEach(Array(zip(self.tabBarOptions.indices, self.tabBarOptions)), id: \.0) { index, name in
                    TopTabBarItem(currentTab: self.$currentTab, namespace: namespace.self, tabBarItemName: name, tab: index)
                }
            }
            .padding(.horizontal)
        }
        .background(Color.white)
        .frame(height: 80)
        .edgesIgnoringSafeArea(.all)
        .padding(10)
    }
}

struct TopTabBarItem: View {
    @Binding var currentTab: Int
    let namespace: Namespace.ID

    var tabBarItemName: String
    var tab: Int
    
    var body: some View {
        Button {
            self.currentTab = tab
        } label: {
            VStack {
                Text(tabBarItemName)
                if currentTab == tab {
                    Color.black
                        .frame(height: 2)
                        .matchedGeometryEffect(id: "underline", in: namespace, properties: .frame)
                } else {
                    Color.clear.frame(height: 2)
                }
            }
            .animation(.spring(), value: self.currentTab)
        }
        .buttonStyle(.plain)
    }
}

我做错了什么?我已经拔出了一半的头发试图解决这个问题,我的头的右侧几乎是秃头在这一点上。先谢了。

u91tlkcl

u91tlkcl1#

首先应用frame,然后在background中着色。

struct TopTabBarView: View {
    ...
    var body: some View {
        ScrollView(.horizontal, showsIndicators: false) {
            ...
        }
        // notice the change in order here:
        .frame(height: 80)
        .background(Color.white)
        .edgesIgnoringSafeArea(.all)
        // the horizontal padding added here also reveals the scroll view on the sides
        // .padding(10)
    }
}

滚动视图实际上不需要那么高。因此,如果你在滚动视图的背景中着色,然后允许它在一个更高的框架中布局,它会在该框架中垂直居中,留下一些“透明”空间。
还可以考虑使用.frame(height: 80, alignment: .bottom)将条定位在80高框架的底部。

相关问题