widgetURL is override inside Foreach?

Viewed 368

I am displaying 3 rows in iOS 14 medium size widget like below:

 row 1
-------
 row 2
-------
 row 3
-------

my view structure is here:

VStack {
    ForEach(records, id: \.id) { item in 
        ZStack {
            // some views
        }
        .widgetURL(URL(string: "wig://\(item.id)"))
    }
    Divider()
}

It seems the widget URL for first and second items are override by the the third item, all deep link will open third item's content.

what is the proper way to add deep link for views generated from ForEach?

1 Answers

Here is interface contract (pay attention at marked)

    /// Sets the URL to open in the containing app when the user clicks the widget.
    /// - Parameter url: The URL to open in the containing app.
    /// - Returns: A view that opens the specified URL when the user clicks
    ///   the widget.
    ///
>>    /// Widgets support one `widgetURL` modifier in their view hierarchy.
>>    /// If multiple views have `widgetURL` modifiers, the behavior is
    /// undefined.
    public func widgetURL(_ url: URL?) -> some View

Instead you have to use Link, like

    ForEach(records, id: \.id) { item in 
       Link(destination: URL(string: "wig://\(item.id)")!) {
         ZStack {
            // some views
         }
       }
    }
Related