iosswiftswiftuiscrollview

Weird behavior with ScrollView in SwiftUI


I am currently touching up on my SwiftUI knowledge and I'm building this task screen. However there is this weird section with the ScrollView that I can't explain on how to remove (gray area above tab bar on first screenshot). It seems to disappear when fully scrolled to the bottom of the app.

Note: I have a custom TabBar and in my ContentView all of the Views are in a ZStack

struct DailyTaskView: View {
    var tasks: [Task]
    
    var body: some View {
        ZStack {
            Color.gBlack.ignoresSafeArea(.all)
            
            ScrollView(.vertical, showsIndicators: false) {
                VStack {
                    ForEach(tasks) { task in
                        TaskItemView(task: task)
                            .padding(.vertical, 10)
                    }
                }
            }
        }
    }
}
struct TaskItemView: View {
    var task: Task
    
    var body: some View {
        HStack(alignment: .center, spacing: 40) {
            Circle()
                .frame(width: 10, height: 10)
                .foregroundColor(.white)
                .shadow(color: .white.opacity(0.1), radius: 3)
            
            VStack(alignment: .leading, spacing: 8) {
                HStack(spacing: 8) {
                    Text(task.title)
                        .foregroundStyle(Color.white)
                        .font(.title)
                    
                    Spacer()
                    
                    Label("11:22 PM", systemImage: "clock")
                        .foregroundStyle(Color.white)
                }
                
                Text(task.description)
                    .foregroundStyle(Color.white)
                    .font(.callout)
            }
//            .frame(maxWidth: .infinity)
            .padding(15)
            .background(task.tint, in: .rect(topLeadingRadius: 15, bottomLeadingRadius: 15))
//            .clipShape(.rect(cornerRadius: 20))
            .strikethrough(task.isCompleted, pattern: .solid, color: .white)
        }
        .padding(.leading)
    }
}
struct ContentView: View {
    @State private var tabSelection: Int = 0
    @State private var tasks: [Task] = sampleTask.sorted(by: {$1.date > $0.date})
    
    var body: some View {
        
        ZStack {
            Color.gBlack.ignoresSafeArea(.all)
            
            VStack() {
                DateHeaderView()
                    .frame(maxWidth: .infinity)
                    .background(Color(Color.gBlack))
                
                TabView(selection: $tabSelection) {
                    DailyTaskView(tasks: tasks)
                        .tag(0)
                    Text("Tab 2")
                        .foregroundStyle(Color.gBlack)
                        .font(.largeTitle)
                        .fontWeight(.black)
                        .tag(1)
                    
                }
                
                Spacer()
                
                TabBarView(tabSelection: $tabSelection)
            }
            .ignoresSafeArea(edges: .bottom)
        }
    }
}

Top of ScrollView Bottom of ScrollView

Attempted converting to List to see if it was ScrollView specific

Played with .frame() with no luck

Verified there wasn't any additional padding that could intervene


Solution

  • Try adding .tabViewStyle(.page(indexDisplayMode: .never)) to your TabView(selection: $tabSelection).

    TabView(selection: $tabSelection) {
        DailyTaskView(tasks: tasks)
            .tag(0)
        Text("Tab 2")
            .foregroundStyle(Color.gray)
            .font(.largeTitle)
            .fontWeight(.black)
            .tag(1)
    }
    .tabViewStyle(.page(indexDisplayMode: .never)) // <--- here
    

    Note, Swift already has a Task defined, change yours to something else (MyTask) otherwise you will confuse yourself and the compiler.