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.
Assigning action to UIBarButtonItem with objc_util
-
So I’m working on a ui with the ui module and the objc_util module. I needed to use the objc_util to do some user QOL improvements with the TextViews. This got me on wanting to continue improvements, and I’ve added a UIToolbar to the keyboard to allow the user to end editing the TextView with a UIBarButtonItem. But the problem is I also want to add another UIBarButtonItem that will clear all the text in the TextView, but I’m having trouble making this happen. There is no method in the TextView to just clear the text, and when init-ing the button to target the TextView and assigning the action to setText of the TextView I can’t figure out how to pass a empty string parameter. Here's an example of the gist of my problem:
import ui from objc_util import * view=ui.View() textview=ui.TextView() textview.text="hello" #make text to see if the button works tvobj=ObjCInstance(textview) #tried passing below as argument in button action text=ObjCClass("NSMutableString").alloc().initWithString_('') #below creates the button and assigns the target and action #can't figure out how to pass argument as well. #tried saying "setText:", 'setText:@""','setText=text' btn=ObjCClass('UIBarButtonItem').alloc().initWithBarButtonSystemItem_target_action_(13,textview,'???') #the 13 is just the refresh button #below finishes setting up the view and adding the button to the #keyboard toolbar bar=ObjCClass('UIToolbar').alloc().init() bar.sizeToFit() keyboard=ObjCClass('UIKeyboard').alloc().init() flex=ObjCClass('UIBarButtonItem').alloc().initWithBarButtonSystemItem_target_action_(5,None,None) bar.items=[flex,btn] textview.inputAccessoryView=bar view.add_subview(textview) view.present()
-
@mcriley821, see below for a function that creates a button that has the given label and calls the given function when clicked.
It uses an UI button as an intermediary. You have to retain a reference to this button to avoid crashes. Consider this a quick fix to move on with your coding - others may point to a way of making the call without extra ui.Button.
def create_button(label, func): button_width = 25 black = ObjCClass('UIColor').alloc().initWithWhite_alpha_(0.0, 1.0) action_button = ui.Button() action_button.action = func accessory_button = ObjCClass('UIBarButtonItem').alloc().initWithTitle_style_target_action_(label, 0, action_button, sel('invokeAction:')) accessory_button.width = button_width accessory_button.tintColor = black return (action_button, accessory_button)
-
@mcriley821, see here for the version without ui.Button. Not much different as you need to create an object with a method anyway.
-
@mikael Thanks for the help, I’ll try the intermediary ui button, but I’ve already tried the code in the other post. The problem with the other code (I think) is that I have a target, it just doesn’t have the method I want (clear text) so creating a new class doesn’t work for me. And even so in creating a new class, I would still need to find a way to target the TextView with my own method.
-
@mcriley821 could you try (see clear button at right)
from objc_util import * import ui UIBarButtonItem = ObjCClass('UIBarButtonItem') UIBarButtonItemGroup = ObjCClass('UIBarButtonItemGroup') def btnAction(_self, _cmd): tv = ObjCClass('UIApplication').sharedApplication().keyWindow().firstResponder() tv.setText_('') ActionTarget = create_objc_class('ActionTarget', methods=[btnAction]) target = ActionTarget.new().autorelease() @on_main_thread def main(): tv = ui.TextView(frame=(0, 0, 320, 320)) b1 = UIBarButtonItem.alloc().initWithTitle_style_target_action_('clear', 0, target, 'btnAction').autorelease() group = UIBarButtonItemGroup.alloc().initWithBarButtonItems_representativeItem_([b1], None).autorelease() ObjCInstance(tv).inputAssistantItem().trailingBarButtonGroups = [group] tv.present('sheet') if __name__ == '__main__': main()
-
@cvp I tried your code, but there’s no button that appears. Was it meant to be a fully-standalone test?
-
@mcriley821 you have to put the cursor in the TextView
-
@cvp I’m on iPhone, but I modified your code a little and it works! Thank you much for your help!
-
@mcriley821 Ok, sorry, I Always forget that I work iPad and most of other people work on iPhone