Skip to content

Instantly share code, notes, and snippets.

@OhItsShaun
Last active May 16, 2023 04:00
Show Gist options
  • Save OhItsShaun/ad4a8f674e8dc75139f725d32a05e5f8 to your computer and use it in GitHub Desktop.
Save OhItsShaun/ad4a8f674e8dc75139f725d32a05e5f8 to your computer and use it in GitHub Desktop.
Position UIPopover from NSToolbarItem
// You may want to present a UIKit popover from an NSToolbarItem, e.g. Maps.app uses
// a popover to select between viewing modes of default, Transit and Satlite.
//
// In UIKit land, set the popover controller's source view as the containing UIWindow,
// and use the following to grab the source rect from the NSToolbarItem in an AppKit
// bundle.
//
// Uses private APIs so mileage varies.
func position(for toolbarItem: NSToolbarItem) -> CGRect? {
guard let view = toolbarItem.value(forKey: "_view") as? NSView,
let window = view.value(forKey: "_window") as? NSWindow else {
assertionFailure("Looks like your toolbar item isn't in the view hierarchy, or the private API changed.")
return nil
}
var rect = view.convert(view.bounds, to: nil)
// AppKit coordinate system is bottom upwards, whereas UIKit coordinate system is
// top downwards, so we need to flip the y-axis w.r.t. the item's height.
let windowHeight = window.frame.height
rect.origin.y = windowHeight - rect.maxY
return rect
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment