Search code examples
swiftuipopoveropenurl

Merely declaring the environment variable openURL cause popover behavior to go wonky


As demonstrated in the sample code below. The popover appears correctly when run without declaring the openURL variable. Uncomment the lines and it appears in the incorrect spot and refuses to be dismissed. I could really use a fix/work-around...

struct Popover: View {
    @State var isShowingPopover = false
//    @Environment(\.openURL) var openURL

    var body: some View {
        Text("Content")
        .toolbar {
            ToolbarItemGroup(placement: .primaryAction) {
                Button("Popover") {
                    isShowingPopover.toggle()
                }
                .popover(isPresented: $isShowingPopover) {
                    Button(action:{
//                        openURL(URL(string: "https://cnn.com")!)
                    }){
                        Label("Open CNN", systemImage: "hand.thumbsup")
                    }
                        .padding()
                }
            }
        }
    }
}


struct Popover_Previews: PreviewProvider {
    static var previews: some View {
        NavigationView{
            Text("Sidebar")
            Popover()
        }
    }
}

Solution

  • It appears toolbar defect... using navigationBarItems works fine.

    Tested with Xcode 12.1 / iOS 14.1

    struct PopoverView: View {
        @State var isShowingPopover = false
        @Environment(\.openURL) var openURL
    
        var body: some View {
            Text("Content")
                .navigationBarItems(trailing:
                     Button("Popover") {
                          isShowingPopover.toggle()
                     }
                     .popover(isPresented: $isShowingPopover) {
                          Button(action:{
                                openURL(URL(string: "https://cnn.com")!)
                          }){
                                Label("Open CNN", systemImage: "hand.thumbsup")
                          }
                                .padding()
                     })
        }
    }