SwiftUI on MacOS Click-behavior

Viewed 170

In a SwiftUI App on MacOS I display a few Items in a Line View inside a List.

The expected behavior is:

  • Click, double-click, log press on a special Element in Line (in the example Text("X") triggers the action
  • Click anywhere else in Line selects the element in the List.
  • Double-click anywhere else in Line triggers the action.

The actual behavior is:

  • All clicks on Text("X") work fine.
  • Clicking on Text("some Text") does not select the element
  • Clicking in the right edge of Line (Spacer())selects the element
  • Double-clicking on Text("some Text") triggers the action
  • Double-clicking in the right edge of Line (Spacer()) does not triggers the action

I have a quite ugly solution (commented out): Giving the HStack in Line a Background, and setting the selection manually the click-behaviour is fine.
The problem now is, stetting the Colors to the system colors.
Is there a better solution?

This is my code:

struct ContentView: View {
  @State var sel :Int? = nil
  var body: some View {
    List(selection: $sel) {
      Line(lineNr:0, selection: $sel).tag(0)
      Line(lineNr:1, selection: $sel).tag(1)
      Line(lineNr:2, selection: $sel).tag(2)
      Line(lineNr:3, selection: $sel).tag(3)
      Line(lineNr:4, selection: $sel).tag(4)
      Line(lineNr:5, selection: $sel).tag(5)
    }
  }
}

struct Line: View {
  @Environment(\.colorScheme) var colorScheme: ColorScheme
  var lineNr : Int
  @Binding var selection : Int?
  
  var body: some View {
    HStack {
      Text("X: ")
        .onTapGesture(count: 2, perform: { print("X double tapped") })
        .onTapGesture(count: 1, perform: { print("X tapped") })
        .onLongPressGesture { print ("X long-presses") }
      Text("some Text")
      Spacer()
    } 
    // ugly solution
    //.background( standardBackgoundColors()  )
    .onTapGesture(count: 2, perform: {
      print("Line double-clicked")
    // ugly solution
    // selection = lineNr
    })
    // ugly solution
    //.onTapGesture(count: 1, perform: {
    //  print("Line clicked")
    //  selection = lineNr
    //})
  }
  
  //Todo: find out the correct system colors
  func standardBackgoundColors()->Color{
    if (selection == lineNr) {
      return colorScheme == .light  ? Color(#colorLiteral(red: 0.8039215803, green: 0.8039215803, blue: 0.8039215803, alpha: 1)) : Color.black
    } else {
      return colorScheme == .light  ? Color.white : Color.black
    }
  }
}

Any ideas?

0 Answers
Related