Skip to content

Instantly share code, notes, and snippets.

@steipete
Last active October 15, 2022 02:52
Show Gist options
  • Save steipete/b9f43b455f396a8db764d13eec971e9b to your computer and use it in GitHub Desktop.
Save steipete/b9f43b455f396a8db764d13eec971e9b to your computer and use it in GitHub Desktop.
SwiftUI Button that wraps a hidden view to anchor popovers on it; can be used as a button in the navigation bar. https://pspdfkit.com/blog/2020/popovers-from-swiftui-uibarbutton/
struct AnchorButton<Content: View>: View {
typealias Action = (_ sender: AnyObject?) -> Void
let callback: Action
var content: Content
@StateObject private var viewWrapper = ViewWrapper(view: UIView(frame: .zero))
init(action: @escaping Action, @ViewBuilder label: () -> Content) {
self.callback = action
self.content = label()
}
var body: some View {
return
ZStack {
InternalAnchorView(view: viewWrapper.view)
Button {
self.callback(BarButtonWatcher.lastBarButtonItem ?? viewWrapper.view)
} label: {
content
}
}.onAppear {
// Lazy global needs access to init
_ = BarButtonWatcher.shared
}
}
private struct InternalAnchorView: UIViewRepresentable {
var view: UIView
func makeUIView(context: Self.Context) -> UIView { view }
func updateUIView(_ uiView: UIView, context: Self.Context) {}
}
// View can't be directly stored as StateObject (not an observable object)
private class ViewWrapper: ObservableObject {
@Published var view: UIView
init(view: UIView) {
self.view = view
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment