Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.
Problems when using objc_util()
-
Can you help me solve the problem about object_c? I'm using objc_util() to create a UIDragInteraction, but it didn't work. The error message is like this.
This is my code and error message.What I ultimately want to accomplish is to implement UIDragInteraction and UIDropInteraction operations in pythonista ui view.The error message is:
Traceback (most recent call last): File "_ctypes/callbacks.c", line 259, in 'converting callback result' TypeError: cannot be converted to pointer
# coding: utf-8 from objc_util import * import ui def dragInteraction_itemsForBeginningSession_(_m,_c,interaction,session): provider=ObjCClass('NSItemProvider').alloc().initWithObject('i am string') item=ObjCClass('UIDragItem').alloc().initWithItemProvider(provider) nsarry=ObjCClass("NSArray").arrayWithObject(item) return nsarry methods=[dragInteraction_itemsForBeginningSession_] protocols=['UIDragInteractionDelegate'] draginter=create_objc_class('itemsForBeginningSession',methods=methods,protocols=protocols) @on_main_thread def create_drag(f_v): ob_fv=ObjCInstance(f_v) f=CGRect(CGPoint(100,100 ), CGSize(300, 300)) ob_cv=ObjCClass("UIView").alloc().initWithFrame(f) color=ObjCClass('UIColor').colorWith(red=1.0, green=0.0, blue=0.0, alpha=1.0) ob_cv.setBackgroundColor(color) delegate=draginter.alloc().init() obj_draginter=ObjCClass('UIDragInteraction').alloc().initWithDelegate(delegate) obj_draginter.setEnabled(True) ob_cv.addInteraction(obj_draginter) ob_fv.addSubview(ob_cv) cui=ui.View(bg_color='#ffffff',farme=(0,0,500,500)) create_drag(cui) cui.present()
-
Is that a full on crash or a normal traceback? If a normal traceback, print the full traceback so we can get the offending line.
If it is a crash, install @dgelessus 's faulthandler.
https://github.com/dgelessus/pythonista_startup -
@rozaimech try this, it works
return nsarry.ptr
-
@JonB there is no crash, only an error
Exception ignored in: <function dragInteraction_itemsForBeginningSession_ at 0x117dcf7b8> Traceback (most recent call last): File "_ctypes/callbacks.c", line 259, in 'converting callback result' TypeError: cannot be converted to pointer
-
@rozaimech, this looks interesting - unfortunately there is not way to dnd on an iPhone, I think.
-
@cvp thanks! it's work!
-
@mikael This code should work on iphones. This feature is turned off by default on iphones, but as obj_draginter.setEnabled (True) is turned on, it can be used.
-
@JonB Thank you for your help! I should continue to sleep now.
-
@rozaimech, ok, thanks, now I got it. Long press to start, also added a text field to be on the receiving end of the interaction (the string).
As a detail, there is no need to create the red view ”in ObjC” to make it drag-and-droppable. This works just as well, and has the benefit of being more readable:
@on_main_thread def create_drag(f_v): drag_source = ui.View( background_color='red', frame=(100, 100, 300, 300), ) delegate = draginter.alloc().init() obj_draginter = ObjCClass('UIDragInteraction').alloc().initWithDelegate( delegate) obj_draginter.setEnabled(True) drag_source.objc_instance.addInteraction(obj_draginter) f_v.add_subview(drag_source)
-
@mikael thanks ,but how to find these hidden interfaces....I want to learn
-
@rozaimech, you are quite right, I had not realized that the
objc_instance
attribute was not really documented anywhere.But the main thing I tried to convey was that you can get the ObjC version of views and other UI class instances with
ObjCInstance(regular_ui_view)
... and that is documented in the
objc_util
docs. Usingregular_ui_view.objc_instance
is just a convenience feature, as you do not always need to importobjc_util
to e.g. set some ObjC-level attributes. -
@mikael ok
-
@rozaimech said:
cui=ui.View(bg_color='#ffffff',farme=(0,0,500,500))
Small typing error: farme ipo frame 🙄
-
@cvp hello..do you know how to create a block in the dropInteraction_performDrop_?
# coding: utf-8 from objc_util import * import ui def dropInteraction_canHandleSession_(_m,_c,interaction,session): return True def dropInteraction_sessionDidUpdate_(_m,_c,interaction,session): #UIDropOperationCancel = 0, #UIDropOperationForbidden = 1, #UIDropOperationCopy = 2, #UIDropOperationMove = 3, return ObjCClass('UIDropProposal').alloc().initWithDropOperation(2).ptr def dropInteraction_performDrop_(_m,_c,interaction,session): session=ObjCInstance(session) '''object c: [session loadObjectsOfClass:[NSString class] completion:^(NSArray<__kindof id<NSItemProviderReading>> * _Nonnull objects) { self.dropLabel.text = objects.firstObject;}]; ''' session.loadObjectsOfClass_completion_(NSString,) methods=[dropInteraction_canHandleSession_,dropInteraction_sessionDidUpdate_,dropInteraction_performDrop_] protocols=['UIDropInteractionDelegate'] dropDelegate=create_objc_class('MydropDelegate',methods=methods,protocols=protocols) Delegate=dropDelegate.alloc().init() dropInteraction=ObjCClass('UIDropInteraction').alloc().initWithDelegate(Delegate) drop_view = ui.View(bg_color='blue',frame=(0,0,500,500)) drop_view.objc_instance.setUserInteractionEnabled(True) drop_view.objc_instance.addInteraction(dropInteraction) drop_view.present()
-
@rozaimech first of all, did you read objc_util doc in Pythonista?
Then, there are a lot of examples in the forum.
Last, I'll try to do it, I just read your request. -
@cvp
I'm sorry to make you feel like I'm a lazy kid to sit idle and enjoy the fruits of other's work .I have read Pythonista documents and source code many times, but there are not many similar examples about objc_util. I can't master English very well, but thank you very much for your help! I'm also trying to find relevant solutions. -
@rozaimech ok and Sorry, I'm still busy with your problem.
A block is ok but loadObjectsOfClass_completion_ is not a method for session... -
@rozaimech I'be done a step more but not yet ok
def dropInteraction_performDrop_(_m,_c,interaction,session): session=ObjCInstance(session) print('dropInteraction_performDrop_ called') '''object c: [session loadObjectsOfClass:[NSString class] completion:^(NSArray<__kindof id<NSItemProviderReading>> * _Nonnull objects) { self.dropLabel.text = objects.firstObject;}]; ''' def handler(_cmd):#,obj1_ptr,_error): print('block called') handler_block = ObjCBlock(handler, restype=None, argtypes=[c_void_p])#, c_void_p, c_void_p]) for item in session.items(): print(item) itemProvider = item.itemProvider() print(itemProvider) ret = itemProvider.loadObjectsOfClass_completion_(NSString, handler_block)
-
@rozaimech we will win, I hope.
You did a small error in loadObjectOfClass_completionHandler_def dropInteraction_performDrop_(_m,_c,interaction,session): session=ObjCInstance(session) print('dropInteraction_performDrop_ called') '''object c: [session loadObjectsOfClass:[NSString class] completion:^(NSArray<__kindof id<NSItemProviderReading>> * _Nonnull objects) { self.dropLabel.text = objects.firstObject;}]; ''' def handler(_cmd,obj1_ptr,_error): print('block called') obj1 = ObjCInstance(obj1_ptr) print(obj1) handler_block = ObjCBlock(handler, restype=None, argtypes=[c_void_p, c_void_p, c_void_p]) for item in session.items(): print(item) itemProvider = item.itemProvider() print(itemProvider) #print(dir(itemProvider)) itemProvider.loadObjectOfClass_completionHandler_(NSString, handler_block)
-
@rozaimech I don't know what you want to drop.
I try with a photo (with the Photos app in split view with Pythonista) and, if you comment the print(obj1) line,- we see that the dropped item is a public.jpeg
- the block is called
Up to here, it is ok but there is still work (for you?) th analyze the droped item. I've tried but not yet solved...