Allowing taps only in vstack deep links within a HStack in widget

Hi, I would like to only allow taps on the deep link VStacks within the HStack.

Here's the code snippet of the View:

struct ThreeContactWidgetView: View {
    var entry: Provider.Entry
    
    var body: some View {
       HStack(spacing: 12) {
           Spacer()
           ForEach(contacts.prefix(3)) { contact in 
              Link(destination: URL(string: "myApp://call?contactId=\(contact.identifier)")!) {
                  VStack {
                       Image(systemName: "person.crop.circle.fill")
                              .resizable()
                              .aspectRatio(contentMode: .fit)
                              .clipShape(Circle())
                        Text("\((contact.givenName))")
                              .font(.headline)
                              .padding(.top, 4)
                   }
                   .frame(width: 100)
               }
            }
            Spacer()
        }
        .padding()
        .containerBackground(for: .widget) {}
    }
}

I tried placing Spacer().allowsHitTesting(false) for example. However, I was still able to tap on the Spacer() and go into the app, and strangely, uses the deep link of the last contact.

Is it even possible to make certain parts of the widget un-tappable in the first place?

In iOS 14 and later, widgets are interactive by default, which means users can tap on any part of the widget to launch the associated app or perform some action. However, if you want to make certain parts of the widget non-tappable, you can use the .background(_:) modifier with a clear color to disable hit testing on those areas.

Here's how you can modify your code to make only the VStacks within the HStack tappable:

struct ThreeContactWidgetView: View {
    var entry: Provider.Entry
    
    var body: some View {
        HStack(spacing: 12) {
            Spacer()
            ForEach(contacts.prefix(3)) { contact in
                Link(destination: URL(string: "myApp://call?contactId=\(contact.identifier)")!) {
                    VStack {
                        Image(systemName: "person.crop.circle.fill")
                            .resizable()
                            .aspectRatio(contentMode: .fit)
                            .clipShape(Circle())
                        Text("\((contact.givenName))")
                            .font(.headline)
                            .padding(.top, 4)
                    }
                    .frame(width: 100)
                }
                .background(Color.clear) // Disable hit testing on this area
            }
            Spacer()
        }
        .padding()
        .containerBackground(for: .widget) {}
    }
}

By adding .background(Color.clear) to each Link's VStack, you should prevent tap gestures from being recognized on the Spacer areas and only allow taps on the VStacks, which will trigger the associated deep links for the respective contacts.

Allowing taps only in vstack deep links within a HStack in widget
 
 
Q