0

I am facing very serious problem in my project. The scenario is something like this.

A SwiftUi screen has NavigationBar -> Sticky Header -> Horizontal TabBarItems -> TabView then each TabView has it's own View using ListView or ScrollView as required

Problem is ListView or ScrollView is not auto growing as per content even its not visible until not giving the height to TabView or ContentView and i can't calculate the content height and give it to the page because content ate too dynamic and big.

Sample code is as follow -

struct ContentView: View {
    var body: some View {
        VStack {
            VStack{
                Text("Sticky Header")
            }
            ScrollView {
                HeaderView()
                
                CustomTabView()
                    .frame(height: 100) <--- I don't want to give this height anymore.
            }
        }
        .padding()
    }
}
struct HeaderView: View {
    var body: some View {
       Image("W")
            .resizable()
            .frame(minWidth: 0, maxWidth: .infinity)
            .frame(height: 200)
    }
}

struct CustomTabView: View {
    var body: some View {
        TabView(content: {
            FirstTavView()
            FirstTavView()
            FirstTavView()
        })
        .tabViewStyle(.page(indexDisplayMode: .never))
    }
}

struct FirstTavView: View {
    var body: some View {
        List(0..<100) { index in
            Text("Index number is --- > \(index)")
        }
    }
}

Wireframe is : enter image description here

4 Answers4

0
LazyVStack(spacing: 1, pinnedViews: [.sectionHeaders]) {
    // ...
}

Your solution is just using LazyVStack and StickeyHeader by pinnedViews. Layout inside will grow up with your content instead. And control your parent by set frame for tabview.

TabView(content: {
            FirstTavView()
            FirstTavView()
            FirstTavView()
        })
        .frame(w : h)
        .tabViewStyle(.page(indexDisplayMode: .never))

    ```
Tài Lê
  • 63
  • 1
  • 10
  • Can't give the frame of to any content, it will calculate the height and secondary LazyVStack you can't achieve this, could you send me the working code. – Vikash Kumar Chaubey Apr 14 '23 at 08:46
  • For the inside tab view if the content is larger or something makes it could overlap, why u don't use scroll view or navigation link,.. etc? – Tài Lê Apr 17 '23 at 02:48
  • And your question is very confusing to read and understand, why u don't give a wireframe or something to clearly more? – Tài Lê Apr 17 '23 at 02:49
  • Either you use ScrollView or List, simple is the View inside `TabView is not growing as per content` until not supply the `frame(height: )`. nd avove code is also stated the same, just run the code and remove '.frame(height: 100)` it. you will see the impact clearly. – Vikash Kumar Chaubey Apr 17 '23 at 05:22
0

I'm new in this technology but I think I have the solution.

  LazyVGrid(columns: Array(repeating: GridItem(.flexible(),spacing: 4), count: 3), spacing: 4,content: {
            ForEach(1...19,id: \.self) {index in
                   GeometryReader { post in
//
                           let width = post.frame(in: .global).width
                                    
                            ImageView(index: index, width: width)
                      }
                                .frame(height: 120)
0

The following code worked for me. You are using extra scroll view.

struct ContentView: View {
var body: some View {
    VStack {
        VStack{
            Text("Sticky Header")
        }
        //ScrollView {
            HeaderView()
            
            CustomTabView()
                 //<--- I don't want to give this height anymore.
        }.foregroundColor(.red)
    //}
    .padding()
    
}

}

struct CustomTabView: View {
var body: some View {
    TabView(content: {
        FirstTavView()
            .tabItem {
                Label("tab1", systemImage: "star.fill")
            }
        FirstTavView()
            .tabItem {
                Label("tab2", systemImage: "star.fill")
            }
        FirstTavView()
            .tabItem {
                Label("tab3", systemImage: "star.fill")
            }
    })
    .tabViewStyle(.page(indexDisplayMode: .always))
}

}

struct FirstTavView: View {
var body: some View {
    VStack{
        List(0..<100) { index in
            Text("Index number is --- > \(index)")
        }
        Text("")
    }

}

}

dAre_incRe
  • 31
  • 5
0

You can hit and try a few things that might work

  1. Call .automaticSize() on the ScrollView: This will automatically adjust the height of the ScrollView based on its content.

  2. Call .fixedSize() on the TabView. This prevents the TabView from being constrained by the static ScrollView size.

  3. Use .scrollContentBackground(.hidden) on the scroll views to allow them to automatically size based on content.

  4. Use a .frame(maxHeight: .infinity) on the TabView and scroll view contents to allow them to expand.

  5. Make sure the list/scroll view is the last item in the view hierarchy, so it can expand downwards.

  6. Avoid explicit heights on parent views like the TabView that may constrain the scroll view size.

zavione
  • 919
  • 1
  • 7
  • 14