SWAttributionView seems to be getting swallowed inside a view with an .onTapGesture modifier

Hey fellow devs,

I have a parent SwiftUI view that includes an SWAttributionView. When I add an .onTapGesture{ } modifier to my parent view, the SWAttributionView no longer appears to 'see' taps. They instead go to the parent's tapGesture modifier. I think I'd be more willing to just accept this, if it wasn't possible for its SwiftUI sibling views to be able to 'see' their taps.

Here is some sample code:

struct ContentView: View {

  @State var tapType: String?
  var body: some View {
    RowView(accessory: {
      Button {
        tapType = "Globe"
      } label: {
        Image(systemName: "globe")
          .foregroundColor(.accentColor)
      }
    })
    .onTapGesture {
      tapType = "Row"
    }
    .alert(item: $tapType) { tt in
      Alert(title: Text("tap type: \(tt)"))
    }
  }
}

struct RowView<Accessory: View>: View {
  private let accessory: () -> Accessory
  init(accessory: @escaping () -> Accessory) {
    self.accessory = accessory
  }

  var body: some View {
    HStack {
      VStack {
        Text("Row Text")
        if let highlight = SharedWithYouMonitor.shared.highlights.first {
          SwiftUIAttributionView(highlight: highlight)
            .frame(maxHeight: 100)
        }
      }
      accessory()
    }
    .padding()
  }
}

The above code is able to set tapType to 'globe' by tapping the globe button. It is also able to set tapType to 'row' by tapping anywhere else in the RowView. But it is not able to demonstrate the sharedWithYou tap behaviour.

When I comment out the tapType = 'row' onTapGesture modifier, the SWAttributeView behaves as expected.

Is this a bug/limitation in SWAttributeView that prevents it from working correctly when its parent has an .onTapGesture modifier?

Thanks in advance for any assistance :-)

here is some other supporting code, that's not specifically germane to my question, but is needed to get things running.

import SharedWithYou

public class SharedWithYouMonitor: NSObject {
  private let highlightCenter: SWHighlightCenter
  public static let shared = SharedWithYouMonitor()
  public var localizedTitle: String {
    return SWHighlightCenter.highlightCollectionTitle
  }
  public var highlights: [SWHighlight] {
    return highlightCenter.highlights
  }
  override init() {
    self.highlightCenter = SWHighlightCenter()
    super.init()
    highlightCenter.delegate = self
  }
}
extension SharedWithYouMonitor: SWHighlightCenterDelegate {
  public func highlightCenterHighlightsDidChange(_ highlightCenter: SWHighlightCenter) {
    highlightCenter.highlights.forEach { highlight in
      print("Received a new highlight with URL: \(highlight.url)")
    }
  }
}
struct SwiftUIAttributionView: UIViewRepresentable {
  private let highlight: SWHighlight
  init(highlight: SWHighlight) {
    self.highlight = highlight
  }
  func makeUIView(context: Context) -> SWAttributionView {
    let result = SWAttributionView()
    result.highlight = highlight
    result.displayContext = .summary
    result.horizontalAlignment = .center
    result.preferredMaxLayoutWidth = 300
    return result
  }
 func updateUIView(_ uiView: SWAttributionView, context: Context) {
  }
}
extension String: Identifiable {
  public typealias ID = Int
  public var id: Int {
    return hash
  }
}

I was able to get around this issue by adding .allowsHitTesting(true) to the UIViewRepresentable view which in your case would be SwiftUIAttributionView.

Update: Never mind this did not work.

SWAttributionView seems to be getting swallowed inside a view with an .onTapGesture modifier
 
 
Q