mica
mica

Reputation: 4308

SwiftUI action at deselection of a Lists row

I have a SwiftUI List, that changes an attribute on a row, e.g. color on a tap.
Now I want to start an action e.g. reset the color, if another row is tapped.

I´m looking for an event, that the row receives ,if it is deselected.

Here my example code:

struct ContentView: View {
  @State var data : [String] = ["first","second","third","4th","5th"]
  var body: some View {
    List {
      ForEach (data, id: \.self) {
        item in
        ColoredRow(text: item)
      }
    }
  }
}

struct ColoredRow: View {
  var text: String = ""
  @State var col : Color = Color.white

  var body: some View{
    Text("\(text)")
    .background(col)
    .onTapGesture {
      self.col = Color.red
    }
//  .onDeselect {
//    print("disappeare \(self.text)")
//    self.col = Color.white
//  }
  }
}

Upvotes: 2

Views: 840

Answers (1)

Asperi
Asperi

Reputation: 258057

Let' recall that SwiftUI is reactive (ie. state-driven, not event-driven), so if we wan't to change something in UI we need to find a way to change it via state (either UI or model, but state).

So, below is slightly modified your code to show possible approach. Tested with Xcode 11.2 / iOS 13.2.

demo

struct ContentView: View {
    @State var data : [String] = ["first","second","third","4th","5th"]
    @State private var selectedItem: String? = nil
    var body: some View {
        List {
            ForEach (data, id: \.self) {
                item in
                ColoredRow(text: item, selection: self.$selectedItem)
            }
        }
    }
}

struct ColoredRow: View {
    var text: String = ""
    @Binding var selection: String?

    @State var col : Color = Color.white

    var body: some View{
        Text("\(text)")
            .background(selection == text ? Color.red : Color.white)
            .onTapGesture {
                self.selection = (self.selection == self.text ? nil : self.text)
        }
    }
}

Upvotes: 1

Related Questions