• shinyformica

    @dgelessus thanks so much for the deep knowledge!

    So now this whole thing is working! As it turns out a lot of this was a red herring.

    In summary:

    • It is perfectly legal to use the python string value "UICollectionElementKindSectionHeader" directly in the registerClass_forSupplementaryViewOfKind_withReuseIdentifier_() objc method, since it is converted to an NSString object implicitly.
    • The value returned by ctypes.c_void_p.in_dll(objc_util.c, "UICollectionElementKindSectionHeader") works as well, I assume since that c_void_p ends up being interpreted as an NSString object.
    • Of course, objc_util.ObjCInstance(ctypes.c_void_p.in_dll(objc_util.c, "UICollectionElementKindSectionHeader")) works, and is probably "safest" since you get the actual value without having to guess, and it is turned into a correct type.
    • You cannot directly use the _FuncPtr value returned by objc_util.c.UICollectionElementKindSectionHeader but there might be some way to convert that _FuncPtr value (just doing a ctypes.cast(funcptr, ctypes.c_void_p) does not work).

    Now, the reason the whole thing was a red herring: collection views won't even bother to call the collectionView_viewForSupplementaryElementOfKind_atIndexPath_() method unless the flow layout object being used to layout the items has had its headerReferenceSize property set to something other than the default CGSize(0,0)...so even when I was successfully registering the class with the method to create section headers, it wasn't being called.

    posted in Pythonista read more
  • shinyformica

    @mikael thank you, checking out that thread now...and yes I was secretly hoping one of the objc gurus on here would know what I was missing. I think what's happening here is that Apple is actually using the address of the NSString* and not any actual string value.

    @cvp are you saying that I can just directly use the value I pull from objc_util.c.UI CollectionElementKindSectionHeader in the objc method call? With no translation?

    posted in Pythonista read more
  • shinyformica

    @mikael indeed, that was the first thing I tried...unfortunately it didn't work. I actually think I am missing something obvious here. I can find where it is defined in objective-c, but the definition contains no actual string value, and I can find no place where a string value is specified:

    NSString *const UI Collection ElementKind SectionHeader;

    (as before, remove the spaces in the spammy name of the constant).

    posted in Pythonista read more
  • shinyformica

    It was! It was the actual name of the constant, which is just nuts.

    posted in Pythonista read more
  • shinyformica

    Little update...in desperation, I started scrounging around in objc_util.c for the name...and it looks like there actually are both:

    UI CollectionElementKind SectionHeader
    and
    UI CollectionElementKind SectionFooter

    symbols defined in there...though they show up as ctypes._FuncPtr objects...attempting to call them without arguments, or with None as the argument, crashes pythonista.

    So...anything I can do with those?

    posted in Pythonista read more
  • shinyformica

    Hey all...trying desperately to get this topic through the aggressive spam filter...crazily it seems like the name of the uikit constant I'm asking about is itself being flagged as spam.

    Anyway...I'm putting spaces in between each word of the name just to fool the filter:

    UI Collection Element Kind Section Header

    Trying to find the actual string value of that constant...my usual methods to find a value via google, in both objective-c and swift docs, etc. have all failed. You can see the definition of the constant by googling the name.

    Anyone have an idea how to pull the value? I need it to finish my pythonista'd wrapper of a collection view.

    posted in Pythonista read more
  • shinyformica

    Anyone else having new topic posts blocked as spam? The last two attempts I've made have been blocked...though the content is my normal rambling.

    posted in Pythonista read more
  • shinyformica

    @mikael in my use case, I'm actually making a Gestures instance per-custom-widget. Since each of my widgets can have 2 or 3 gestures, it is simpler to just let each one have its own Gestures instance and install the various recognizers on each one. Gestures isn't particularly heavyweight, especially without the internal ui.Button instance, and then I don't need any global tracking of who has gestures installed, since when the widget goes away, it takes the gestures instance with it.

    Creating a little handler method in the gesture delegate class, which can be attached to a gesture recognizer is as simple as:

    ...existing gesture delegate definition...
    
    def handleGesture_(_self, _cmd, recognizer):
            import objc_util
            delegate = objc_util.ObjCInstance(_self)
            if not delegate: return
            recognizer = objc_util.ObjCInstance(recognizer)
            if not recognizer: return
            gestures = delegate._gestures()
            if not gestures: return
            gestures._handleGestureRecognizer(recognizer)
    
        methods = [...
                    handleGesture_]
    

    Then, where you make the recognizers, instead of the whole button action thing, with all the associated bookkeeping:

    recognizer = \
                objc_util.ObjCClass(recognizer_type).alloc()
                recognizer.initWithTarget_action_(self._delegate,
                        objc_util.sel("handleGesture:")).autorelease()
    view.objc_instance.addGestureRecognizer_(recognizer)
    

    posted in Pythonista read more

Internal error.

Oops! Looks like something went wrong!