• Yeah, that's exactly the error I was getting. Got it when trying to reuse a popover view as well.
    The result I have by creating my own title bar is actually better for my purposes, so I'll stick with it.

    Interesting to know about removing the view controller to disconnect the closed view from the animation state of the presenting controller.

  • Python2 vs Python3 :)

  • There was an additional crashing issue: another version of the same problem when an object has gone out of scope in the python context when it is accessed in the objc context.

    I need to re-inforce the understanding that just because a python object like a ui.View is technically placed in a view hierarchy, or otherwise connected to the objc world, the underlying objc instance of a UIView is not in any way holding a strong reference to that python object, and I think vice-versa.

    So creating a local ui.View instance inside a method, and then adding that view to a purely objc view hierarchy, will not preserve the python object after it goes out of scope. So a later attempt to access the python object will segfault.


    import ui import objc_util class X(object): def buttonAction(self, sender): print sender def demoCrash(self, sender): b2 = ui.Button() b2.frame = (0,0,200,50) b2.title = "Crash?" b2.action = self.buttonAction v2 = ui.View() v2.frame = (0,0,200,50) v2.background_color = (1.0,1.0,1.0,1.0) v2.objc_instance.addSubview(b2) v2.present(style="sheet") v = ui.View() v.frame = (0,0,400,400) v.background_color = (1.0,1.0,1.0,1.0) x = X() b = ui.Button() b.title = "Show" b.frame = (0,0,100,30) b.center = (v.width*0.5,v.height*0.5) b.action = x.demoCrash v.add_subview(b) v.present(style="sheet")

    should have been obvious, but my code was more complex and hid what was happening.

  • @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)
  • @JonB looks like you're right...I was doing something incorrectly, though now I'm not sure what.

    If I simply take the widget.bounds() and ui.convert_rect() to the ScrollView, I get a valid rectangle in the ScrollView coordinate space. So all good.

  • @shinyformica try this, it is the way omz wrote dialog: using wait_modal and resetting the view just after.

    import ui from objc_util import * class Popover(ui.View): def __init__(self, *args, **kws): ui.View.__init__(self, *args, **kws) self.width = 200 self.height = 50 self.label = ui.Label() self.label.text = "test" self.add_subview(self.label) self.label.x = 0 self.label.y = 0 self.label.width = self.width self.label.height = self.height def will_close(self): print("popover closing") class MyView(ui.View): def __init__(self, *args, **kws): ui.View.__init__(self, *args, **kws) self.popover = None self.button = ui.ButtonItem() self.button.title = "Show Popover" self.button.action = self.showPopover self.right_button_items = (self.button,) def showPopover(self, sender): print("show popover") if self.popover is None: self.popover = Popover() self.popover.present(style="popover", popover_location=(self.width-100,50), hide_title_bar=True) self.popover.wait_modal() self.popover = None def run(): v = MyView() v.present('full_screen') if __name__ == '__main__': run()```
  • @shinyformica, if I understand your requirement right, it is as simple as:

    button.frame = v.bounds button.flex = 'WH'
  • Those are custom attributes not custom arguments. what happens is the view is created, with no input args:


    then, arguments are set:

    v.width =.... v.bc="oooo"

    and so on.
    if you need to take action based on the custom attributes, you need to have those as @property's, to implement a setter.

  • @Webmaster4o , lol does not surprise me. But let's face it a lot of little treasures in Pythonista.
    I wish they could all be documented, but I understand why they are not. It would take a big chunk out of the development time. I can't remember how long I have had Pythonista now, but I am astounded how much it has evolved in that short time.

  • I think that at each touch_began run, you create a new instance of ui.View, without deleting the previous one! Not vital but not the deal, I suppose.

  • See my other reply: make sure your loaded pyui return PanelMorphic as the CustomClass. init gets called on the class of whatever new returns.

Internal error.

Oops! Looks like something went wrong!