UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

SOLVED: ScrollView category title

Forums > SwiftUI

@00jim  

Similar in behaviour to the navigationTitle, I woul like the category names e.g. "Data #1" to remain at the top of the screen, untul the next category in the ScrollView meets to replace it (similar to the date label grouping chat messages in WhatsApp will change as the next group scrolls up).

import SwiftUI

let dataSet: [Data] = [

    // DATA #1
    Data(info: "Info #1A", category: .data1),
    Data(info: "Info #1B", category: .data1),
    Data(info: "Info #1C", category: .data1),
    Data(info: "Info #1D", category: .data1),
    Data(info: "Info #1E", category: .data1),
    Data(info: "Info #1F", category: .data1),

    // DATA #2
    Data(info: "Info #2A", category: .data2),
    Data(info: "Info #2B", category: .data2),
    Data(info: "Info #2C", category: .data2),
    Data(info: "Info #2D", category: .data2),
    Data(info: "Info #2E", category: .data2),
    Data(info: "Info #2F", category: .data2),

    // DATA #3
    Data(info: "Info #3A", category: .data3),
    Data(info: "Info #3B", category: .data3),
    Data(info: "Info #3C", category: .data3),
    Data(info: "Info #3D", category: .data3),
    Data(info: "Info #3E", category: .data3),
    Data(info: "Info #3F", category: .data3),

    // DATA #4
    Data(info: "Info #4A", category: .data4),
    Data(info: "Info #4B", category: .data4),
    Data(info: "Info #4C", category: .data4),
    Data(info: "Info #4D", category: .data4),
    Data(info: "Info #4E", category: .data4),
    Data(info: "Info #4F", category: .data4),

    // DATA #5
    Data(info: "Info #5A", category: .data5),
    Data(info: "Info #5B", category: .data5),
    Data(info: "Info #5C", category: .data5),
    Data(info: "Info #5D", category: .data5),
    Data(info: "Info #5E", category: .data5),
    Data(info: "Info #5F", category: .data5),
]

enum DataCategory: String, CaseIterable {
    case data1 = "Data #1"
    case data2 = "Data #2"
    case data3 = "Data #3"
    case data4 = "Data #4"
    case data5 = "Data #5"
}

struct Data: Identifiable {
    let id = UUID()
    let info: String
    let category: DataCategory
}

struct TileTitleTestView: View {

    var body: some View {
        VStack {
            Text("default")
                .padding()
                .cornerRadius(8)
        }
        .frame(maxWidth: .infinity)
        .background(Color.blue)
        .foregroundColor(.white)
        .cornerRadius(15)
        .padding(5)
    }
}

struct TileArrayView: View {
    let data: [Data]

    var body: some View {
        ScrollView {
            LazyVGrid(columns: Array(repeating: GridItem(.flexible(), spacing: 10), count: 3), spacing: 10) {
                ForEach(DataCategory.allCases, id: \.self) { category in
                    Section(header:
                                Text(category.rawValue)
                                    .font(.system(size: 30).bold())
                                    .multilineTextAlignment(.leading)
                                    .foregroundColor(.black)
                    ) {
                        ForEach(data.filter { $0.category == category }) { data in
                            DataTile(data: data)
                                .aspectRatio(1, contentMode: .fit)
                        }
                    }
                }
            }
            .padding()
        }
    }
}

struct DataTile: View {
    let data: Data

    var body: some View {
        VStack {
            Text(data.info)
                .padding()
                .cornerRadius(8)
        }
        .frame(maxWidth: .infinity)
        .background(Color.pink)
        .foregroundColor(.black)
        .cornerRadius(15)
        .padding(5)
    }
}

As close as possible to the default behaviour of the navigationTitle, that will appear in the top centre title bar would be my goal.

1      

Use this init for LazyVGrid instead with pinnedViews:

LazyVGrid(columns: Array(repeating: GridItem(.flexible(), spacing: 10), count: 3), spacing: 10, pinnedViews: .sectionHeaders)

is this what you are trying to achieve?

2      

@00jim  

Yes !

However, I would preffer the text to be backed by a white margin at the top, so the cells do not touch the title.

How do I achieve this please ?

1      

As possible solution change your section header to this.

Section(header:
            Color.white
    .frame(height: 60)
    .overlay {
        Text(category.rawValue)
            .font(.system(size: 30).bold())
            .multilineTextAlignment(.leading)
            .foregroundColor(.black)
    }
)

2      

@00jim  

Thank you very much once again !

This helps a lot with the effect: .statusBar(hidden: true)

1      

Hacking with Swift is sponsored by Essential Developer

SPONSORED Join a FREE crash course for mid/senior iOS devs who want to achieve an expert level of technical and practical skills – it’s the fast track to being a complete senior developer! Hurry up because it'll be available only until April 28th.

Click to save your free spot now

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.