Forum Archive

How to select all text in text box on tap

Jonstieg

I'd like to select all the text in a text box whenever I tap on it and I just can't find any information on how to do it.

Is there a method to select/highlight all the text? Is there a way that I could simulate sending the Command + A keys?

Thanks

JonB

Typically in iOS you can tap once in the textbox to give focus, then long tap for a few seconds then release, and you will get a Select/Select All/Paste dialog.

This is one of my pet peeves in ios, because this often does not work, or does not work as expected, or the whole screen goes banannas while you are long tapping because the keyboard goes away, etc)

omz

Here's an example of a TextView that automatically selects all text when you tap into it to start editing:

import ui
from functools import partial

class MyTextViewDelegate (object):
    def textview_did_begin_editing(self, textview):
        r = (0, len(textview.text))
        ui.delay(partial(setattr, textview, 'selected_range', r), 0)

tv = ui.TextView(frame=(0, 0, 500, 500))
tv.text = 'Lorem Ipsum Dolor Sit'
tv.font = ('Helvetica', 18)
tv.delegate = MyTextViewDelegate()

tv.present('sheet')

It works by implementing the delegate method textview_did_begin_editing. Unfortunately, setting the selection directly in this method doesn't work (I guess because the system modifies the selection afterwards), so I used ui.delay to set it just a little bit later.

If you want to use a (single-line) TextField, the approach would be similar, but with a different delegate method.

Jonstieg

Thanks. This code works really well but I am having a tough time applying it to my code, which has TextFields. Here is a bit of my code, which uses a .pyui:

import ui
from functools import partial

class golfApp(ui.View):
   ...
   def textfield_did_begin_editing(self, textfield):
       r = (0, len(textfield.text))
       ui.delay(partial(setattr, textfield, 'selected_range', r), 0)
   ...

v=ui.load_view('golf')
v.delegate = MyTextFieldDelegate()
v.present(style='full_screen', orientations='portrait')     

Any idea what I'm doing wrong? Thanks so much.

Jonstieg

I did some more research and the problem seems to be that there is no selected_range method on the TextField. Is there an equivalent method that I'm missing? Thanks.

omz

Ah sorry, you're right, I forgot about that.

You can work around this limitation with some Objective-C trickery though:

import ui
from objc_util import *
from functools import partial

def select_all(textfield):
    tf = ObjCInstance(textfield).subviews()[0]
    start_pos = tf.beginningOfDocument()
    end_pos = tf.endOfDocument()
    range = tf.textRangeFromPosition_toPosition_(start_pos, end_pos)
    tf.setSelectedTextRange_(range)

class MyTextFieldDelegate (object):
    def textfield_did_begin_editing(self, textfield):
        ui.delay(partial(select_all, textfield), 0)

tf = ui.TextField(frame=(0, 0, 500, 500))
tf.text = 'Lorem Ipsum Dolor Sit'
tf.font = ('Helvetica', 18)
tf.delegate = MyTextFieldDelegate()
tf.present('sheet')