SwiftUI with escaping closures?

I'm looking for clarity on whether or not it's good practice to use closures for actions within SwiftUI views (I'm not referring to closures for creating subviews, such as @ViewBuilders).

In the below example, the purpose is to extract the button action from the child view. There are two child views, one with the action marked @escaping and one without. Being that these are value types (structs), does this make any difference?

import SwiftUI

class MyViewModel: ObservableObject {
  @Published var count: Int = 0
  func incrementCount() {
    count += 1
  }
}

struct MyView: View {
  @StateObject private var viewModel = MyViewModel()
  var body: some View {
    VStack(spacing: 40) {
      Text("\(viewModel.count)")
      ChildView1 {
        viewModel.incrementCount()
      }
      ChildView2 {
        viewModel.incrementCount()
      }
    }
  }
}

struct ChildView1: View {
  let onTap: () -> Void
  var body: some View {
    Text("BUTTON 1")
      .onTapGesture(perform: onTap)
  }
}
struct ChildView2: View {
  let onTap: () -> Void
  init(onTap: @escaping () -> Void) {
    self.onTap = onTap
  }
  var body: some View {
    Text("BUTTON 2")
      .onTapGesture(perform: onTap)
  }
}

struct MyView_Previews: PreviewProvider {
  static var previews: some View {
    MyView()
  }
}

hi lucid,

i think it a good thing to provide actions to Buttons from outside; you probably do not want to define a Button that already knows exactly what it's supposed to do when tapped, since that makes it not all that reusable.

as for syntax, your ChildView2 uses an explicit initializer, so you are required to use @escaping in the parameter list. your ChildView1 uses a default or synthesized initializer, which i'm guessing is in fact recognizing that the function being passed in is @escaping.

hope that helps,

DMG

SwiftUI with escaping closures?
 
 
Q