How to set the background color of a popover view
Figured I'd post this for others, since I just got it to work.
If you've ever wanted to show a view as a popover, but colorized so it matches the theme, including the enclosing view's edges and the little arrow, here's how to do it...
import objc_util # this code came from elsewhere on the forum: given a view, it finds the objc UIViewController which is presenting it: def getUIViewController(view): UIViewController = objc_util.ObjCClass('UIViewController') UIView = objc_util.ObjCClass('UIView') viewobj = view.objc_instance viewResponder = viewobj.nextResponder() try: while not viewResponder.isKindOfClass_(UIViewController): viewResponder = viewResponder.nextResponder() except AttributeError: return None return viewResponder popup = ui.View() popup.frame = (0,0,300,50) # "bg" is the color you want to set the popover view to popup.background_color = bg popup.present(style="popover", popover_location=pos, hide_title_bar=True) # this is the bit that colors the enclosing view parentvc = getUIViewController(popup) popovervc = parentvc.popoverPresentationController() if popovervc is not None: popovervc.backgroundColor = objc_util.UIColor.colorWithRed_green_blue_alpha_(*popup.background_color)
be warned that on iPhones, popover presentation is ignored and the view is presented full screen, so popovervc above will be None.
@shinyformica this line may be commented, isn'it?
#UIView = objc_util.ObjCClass('UIView')
@cvp yes, that line isn't needed, I just copy-pasta'd this from a chunk of larger code...looks like I forgot to define "pos" too, which is a little complicated: it isn't simply a point in the parent coordinate system. It's a point in reference to the top-left corner of the top view in the view hierarchy which is presenting it.
I asked about getting that location a while ago, and got some good replies, so the little utility function to get that point is:
def popoverPoint(pos, sourceView): import objc_util srcobjc = sourceView.objc_instance topobjc = None parent = srcobjc.superview() while parent is not None: topobjc = parent parent = parent.superview() p = srcobjc.convertPoint_toView_(objc_util.CGPoint(*pos), topobjc) return (p.x,p.y)