Is there a better way to create a multi-column (Data table) List view in SwiftUI

Viewed 2393

EDIT Below

I'm trying to present a JSON file as a data table, similar to what one would see in a database application. So far my best results have come from an HStack of Lists, however in doing so, each list is scrollable on its own (nor can I imagine any easy way to sort the list(s). Is there a way to create this database view effect using a single List view as opposed to multiple ones?

As an aside, the pod "SwiftDataTables" is exactly what I'm trying to achieve, although that pod seems out of date and not enough documentation for me to get working with my data.

This is a screenshot of what I am currently working with:

Current Siutation

And here is the code I'm using:

//
//  ContentView.swift
//  Shared
//
//  Created by Kyle Carroll on 7/19/21.
//

import SwiftUI
import SwiftDataTables

struct ContentView: View {

    @StateObject var bookStore : BookStore = BookStore(books:bookData)

    var body: some View {
            HStack(spacing: 0) {
                List {
                    ForEach (bookStore.books) { book in
                        ListCell3(book: book)
                    }
                }
                .listStyle(PlainListStyle())
                .frame(width: 75, height: nil, alignment: .center)
                List {
                    ForEach (bookStore.books) { book in
                        ListCell(book: book)
                    }
                }
                .listStyle(PlainListStyle())
                List {
                    ForEach (bookStore.books) { book in
                        ListCell2(book: book)
                    }
                }
                .listStyle(PlainListStyle())
        }
    }
}

struct ListCell: View {

    var book : Book

    var body: some View {
            HStack {
                Text(book.title)
        }
    }
}

struct ListCell2: View {

    var book : Book

    var body: some View {
            HStack {
                Text(book.author)
        }
    }
}

struct ListCell3: View {

    var book : Book

    var body: some View {
            HStack {
                Text(book.id)
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        if #available(iOS 15.0, *) {
            ContentView()
                .previewInterfaceOrientation(.landscapeLeft)
        } else {
            // Fallback on earlier versions
        }
    }
}

Edit:

I've chanced my ListCell struct to list all elements in a single row with dividers between them, however, I can't figure out how to get defined spacing between the elements. A global "spacing" in the HStack causes the elements to be misaligned as the text in each cell is a different length. I'd like certain "columns" to have different fixed widths.


    var book : Book

    var body: some View {
        HStack(alignment: .center, spacing: nil) {
                Text(book.id)
                Divider()
                Text(book.title)
                Divider()
                Text(book.author)
        }
    }
}
1 Answers

By changing the contents of the list view cell struct, I was able to put each attribute in a single row and then use modifiers to evenly space them as follows:

struct ListCell: View {

    var book : Book

    var body: some View {
        HStack(alignment: .center, spacing: nil) {
                Text(book.id)
                .frame(maxWidth: 50, alignment: .leading)
                Divider()
                Text(book.title)
                .frame(maxWidth: 200, alignment: .leading)
                Divider()
                Text(book.author)
                .frame(maxWidth: 200, alignment: .leading)
        }
    }
}
Related