SwiftUI List OutlineGroup

Hello,

I'm having some difficulties trying to customise a SwiftUI list-detail splitview using List and OutlineGroup:

The model used is provided in Apple documentation OutlineGroup.

The contentView is

struct ContentView: View {
    @State var itemString = String()
    var body: some View {
        HSplitView {
            MyOutLine(title: "MyOutLine", itemString: $itemString)
                .frame(width: 200, height: 300
, alignment: Alignment(horizontal: .leading, vertical: .top))
                .padding()
            MyView(itemString: itemString)
        }
    }
}

The left view is

struct MyOutLine: View {
    let title:String
    @Binding var itemString:String
    @State private var selection: FileItem?
    var body: some View {
        List(selection: $selection) {
            OutlineGroup(data, children: \.children) { item in
                Text ("\(item.description)")
                    .onTapGesture  {
                        selection = item
                        itemString = item.description
                    }
                    .listRowBackground(
                        selection == item ?
                        Color.gray
                        :nil
                    )
            }
        }
        .listStyle(.sidebar)
        .onAppear { itemString = "No selection"}
    }
}

The right view is:

struct MyView: View {
    let itemString:String
    var body: some View {
        VStack{
            Spacer()
            HStack {
                Spacer()
                Text(itemString)
                Spacer()
            }
            Spacer()
        }
    }
}

The result works but I have 2 problems:

  1. The selection works but the detail view is updated only when I click the text but not when I click the rest of the row. This results in the detail view not being sync with the list selection.

  2. I would like to customise the colour of the selected row but listRowBackground does not seem to work.

Is there a way to fix this

Thank you in advance

Jean Marie

Answered by DTS Engineer in 793721022

@JMDelh Have you considered using a two-column navigation split view instead?

The selection works but the detail view is updated only when I click the text but not when I click the rest of the row. This results in the detail view not being sync with the list selection.

Apply the contentShape(_:eoFill:) and set the maxWidth of to infinity

 Text("\(item.description)")
     .frame(maxWidth: .infinity)
     .contentShape(Rectangle())

@JMDelh Have you considered using a two-column navigation split view instead?

The selection works but the detail view is updated only when I click the text but not when I click the rest of the row. This results in the detail view not being sync with the list selection.

Apply the contentShape(_:eoFill:) and set the maxWidth of to infinity

 Text("\(item.description)")
     .frame(maxWidth: .infinity)
     .contentShape(Rectangle())

I did dig into your suggestion and the first issue is now solved by encapsulating the Text() and a Spacer() in a HStack(), using .contentShape(Rectangle()) and the onTabGesture {} on the HStack(). The frame() modifier is not needed.

The detail view is updated and sync when clicking on any part of the selection

struct MyOutLine: View {
    let title:String
    @Binding var itemString:String
    @State private var selection: FileItem?
    var body: some View {
        List(selection: $selection) {
            OutlineGroup(data, children: \.children) { item in
                HStack  {
                    Text ("\(item.description)")
                    Spacer()
                }
                .contentShape(Rectangle())
                .onTapGesture  {
                    selection = item
                    itemString = item.description
                }
                .listRowBackground(
                    selection == item ?
                    Color.gray
                    :nil
                )
            }
        }
        .listStyle(.sidebar)
        .onAppear { itemString = "No selection"}
    }
}

This does not help for listRowBackground()

SwiftUI List OutlineGroup
 
 
Q