If you use this script to switch the keyboard, the existing keyboard will be hidden.
How can I change the beta version to use with the existing keyboard?
import ui from objc_util import * import clipboard import speech v = ui.View() v.frame = (0,0,500,320) v.name = 'Move cursor in TextView' tv = ui.TextView() tv.name = 'TextView' tv.frame = (0,10,380,250) tv.font = ('Arial Rounded MT Bold',20) tv.text = 'aé😢🇯🇵👨👨👧👧' v.add_subview(tv) def say_char(tv): # test speech character at cursor idxtopos = IndexToPos('') # list index to position i = tv.selected_range #print(i,idxtopos) i = idxtopos[i] # used to check if same base character if i < len(tv.text): c = tv.text[i] if c == ' ': c ='space' speech.say(c,'jp-JP') def selected_range(i): tvo = ObjCInstance(tv) p1 = tvo.positionFromPosition_offset_(tvo.beginningOfDocument(), i) p2 = p1 tvo.selectedTextRange = tvo.textRangeFromPosition_toPosition_(p1, p2) say_char(tv) return # some emoji like flags count as 2 for len but as 4 for selected_range def IndexToPos(type): tvo = ObjCInstance(tv) # build array index -> position in range idxtopos =  pre_x = -1 #print(tv.text) for c in tv.text: # nbr characters used e=1 é=1 😂=1 🇯🇵=2 👨👨👧👧=7 # some emoji generate more than one character, # sometimes counted for more than one in range # 1,2,3->1 4->2 nb = 1 + int(len(c.encode('utf-8'))/4) for j in range(0,nb): p1 = tvo.positionFromPosition_offset_(tvo.beginningOfDocument(), len(idxtopos)) p2 = p1 rge = tvo.textRangeFromPosition_toPosition_(p1, p2) rect = tvo.firstRectForRange_(rge) # CGRect x = rect.origin.x if x == float('inf') or x == pre_x: # same x as previous one, composed character pass else: pre_x = x i = len(idxtopos) idxtopos.append(i) # start position of c #print(c,nb,len(idxtopos)-1,i,x) idxtopos.append(i+1) # end position of last c #print(idxtopos) # get index of actual cursor i = tv.selected_range # actual position of cursor # often p is one of sub_chars, not always the first one p = idxtopos[i] # used to check if same base character #print(p,i,idxtopos) if type == 'left': if i == 0: return # already before character while True: i = i - 1 if idxtopos[i] != p: q = idxtopos[i] # seach first sub-character while i > 0: if idxtopos[i-1] != q: break i = i - 1 break elif type == 'right': if i == (len(idxtopos)-1): return # already after last character while True: i = i + 1 if idxtopos[i] != p: break elif type == 'end': i = len(idxtopos)-1 else: return idxtopos r = idxtopos[i] selected_range(i) return idxtopos b_top = ui.Button() b_top.frame = (285,302,94,41) b_top.title = '文頭' b_top.background_color = 'white' b_top.border_width = 1 def b_top_action(sender): tv = sender.superview['TextView'] tv.selected_range = (0,0) b_top.action = b_top_action v.add_subview(b_top) b_left = ui.Button() b_left.frame = (190,262,94,41) b_left.title = '⬅︎' b_left.background_color = 'white' b_left.border_width = 1 def b_left_action(sender): idxtopos = IndexToPos('left') # list index to position b_left.action = b_left_action v.add_subview(b_left) b_right = ui.Button() b_right.frame = (285,262,94,41) b_right.title = '➡︎' b_right.background_color = 'white' b_right.border_width = 1 def b_right_action(sender): idxtopos = IndexToPos('right') # list index to position b_right.action = b_right_action v.add_subview(b_right) b_bottom = ui.Button() b_bottom.frame = (190,302,94,41) b_bottom.title = '文末' b_bottom.background_color = 'white' b_bottom.border_width = 1 def b_bottom_action(sender): idxtopos = IndexToPos('end') # list index to position b_bottom.action = b_bottom_action v.add_subview(b_bottom) def get_xy(tv): idxtopos = IndexToPos('') # list index to position tvo = ObjCInstance(tv) x_y =  for i in range(0,len(idxtopos)+1): # x,y of each character p1 = tvo.positionFromPosition_offset_(tvo.beginningOfDocument(), i) rge = tvo.textRangeFromPosition_toPosition_(p1,p1) rect = tvo.firstRectForRange_(rge) # CGRect x,y = rect.origin.x,rect.origin.y if i == len(idxtopos): if i > 0: x,y = x_y[i-1] else: # text is empty x,y = 0,0 if x == float('inf'): x,y = x_prec+15,y_prec x_prec,y_prec = x,y x_y.append((x,y)) return x_y b_up = ui.Button() b_up.frame = (0,262,94,41) b_up.title = '⬆︎' b_up.background_color = 'white' b_up.border_width = 1 def b_up_action(sender): tv = sender.superview['TextView'] x_y = get_xy(tv) c = tv.selected_range xc,yc = x_y[c] i = c - 1 while i >= 0: x,y = x_y[i] if y < yc: # previous row if x <= xc: selected_range(i) return i = i - 1 b_up.action = b_up_action v.add_subview(b_up) b_down = ui.Button() b_down.frame = (95,262,94,41) b_down.title = '⬇︎' b_down.background_color = 'white' b_down.border_width = 1 def b_down_action(sender): tv = sender.superview['TextView'] idxtopos = IndexToPos('') # list index to position x_y = get_xy(tv) c = tv.selected_range #print(x_y,c) xc,yc = x_y[c] i = c# - 1 # I don't remember why this "- 1" while i < len(idxtopos): x,y = x_y[i] if y > yc: # next row if x >= xc: selected_range(i) return else: if (i+1) < len(idxtopos): if x_y[i+1] > y: # i = last character of row under cursor selected_range(i) return else: pass # try next x else: # last character of last row selected_range(i) return i = i + 1 b_down.action = b_down_action v.add_subview(b_down) b_copy = ui.Button() b_copy.frame = (95,302,94,41) b_copy.title = 'copy' b_copy.background_color = 'white' b_copy.border_width = 1 def b_copy_action(sender): tv = sender.superview['TextView'] clipboard.set(tv.text) b_copy.action = b_copy_action v.add_subview(b_copy) b_clear = ui.Button() b_clear.frame = (0,302,94,41) b_clear.title = 'clear' b_clear.background_color = 'white' b_clear.border_width = 1 def b_clear_action(sender): tv = sender.superview['TextView'] tv.text = '' b_clear.action = b_clear_action v.add_subview(b_clear) #絵文字タスクバー def typeChar(sender): '''finds active textinput, and types the button's title''' tf=sender.objc_instance.firstResponder() tf.insertText_(sender.title) def nextSet(sender): i_set = sender.i_set + 1 if i_set == sender.n_sets: i_set = 0 #attach our accessory to the textfield, and textview ww = vv_array[i_set] tvo = tv.objc_instance #print(dir(tvo)) tvo.setInputAccessoryView_(ObjCInstance(ww)) tvo.reloadInputViews() #create normal keys d = 32 dd = 4 emojis = '😊😜😱💦☔️(笑)☀️☁️☃️❄️🍙🍔🚗🌈⭐️😀😃😄😁😆😅😂🤣☺️😊😇🙂🙃😉😌😍🥰😘😗😙😚😋😛😝😜🤪🤨🧐🤓😎🤩🥳😏😒😞😔😟😕🙁☹️😣😖😫😩🥺😢😭😤😠😡🤬🤯😳🥵🥶😨😰😥😓🤗🤔🤭🤫🤥😶😐😑😬😦😧😮😲😴' n_emojis_in_set = 10 n_sets = 1 + int((len(emojis)-1)/n_emojis_in_set) vv_array =  for i_set in range(0,n_sets): l = int(len(emojis)/n_sets) i = i_set * l set_emojis = emojis[i:i+l] + '⏩' w, h = ui.get_screen_size() vv = ui.View(name='set'+str(i_set)) vv.background_color = 'lightgray' h = 0 x = dd y = dd for button_title in set_emojis: b = ui.Button(title=button_title) if button_title == '⏩': b_action = nextSet b.i_set = i_set b.n_sets = n_sets b.name = 'nextSet' else: b_action = typeChar b.action=b_action b.frame = (x,y,d,d) b.font = ('.SFUIText', d) if (y+d+dd) > h: h = y + d + dd vv.add_subview(b) x = x + d + dd if (x+d+dd) > w: x = dd y = y + d + dd vv.frame = (0,0,w,h) vv_array.append(vv) i_set = 0 nextSet(vv_array[n_sets-1]['nextSet']) # display 1st setet) v.present('sheet') tv.selected_range = (0,0) tv.begin_editing()
@shinya.ta I've never seen that
@shinya.ta I think I understand your problem, wait a minute.
Are you still with the beta version of Pythonista?
When it has expired, did you reinstall the standard version?
What shows settings/Général/keyboards?
I've been using the beta version since I was taught the beta version.
We haven't reinstalled the standard version.
The current condition is like this.
@shinya.ta Ok. First, I'm happy (and you too, I hope) that you can now post images in the forum.
If you are in Beta, I don't understand.
As I can see, only the globe is visible, what happens if you tap it.
A beta version of the update was released just now, so if you install it, there will be something wrong.
It becomes like this for a moment.
After that, it becomes like this screen.
@shinya.ta I didn't know there was a new update of the beta.
As this update modifies something about keyboard, perhaps the problem comes from there
@shinya.ta you could reinstall previous version:
I reinstalled it.
Did you reinstall the same build or did you choose the previous build?
@shinya.ta I understand your problem.
You have added "Move cursor in TextView" as a Pythonista keyboard but this script can't be run as a keyboard, it does not import the keyboard module.
You have made a mix between this script written in the past and the "Japanese Braille keyboard" that I wrote for you.
Remove this script from your keyboard scripts.
I delete the topic "problem with build 330015"
I've returned it to the previous version.
What should I do to execute this as a keyboard?
@shinya.ta Not so easy, I'll try....
But, don't forget, this script is written for a TextView in Pythonista and you want to use it anywhere in other apps, like your mail...
It is not at all the same process.
That will not be solved in a few time 😢
@shinya.ta I've an important question.
This script runs in Pythonista and presents an UI View with a TextView and some buttons,
AND the keyboard has an additional row with emoji"s.
If you want to use something like that in other apps, like Mail, is it only to have this additional row of emoji's?
What is easy is a little script that you can add to Pythonista keyboards and this new keyboard will offer the English keyboard and a row where you can display and tap your emojis like the actual script.
You can find an initial version here, tell me if it is ok
Of course, you have to add it to Pythonista keyboards via
tools/shortcuts/Pythonista keyboard/+ where you have to choose the script and the title
See here, used in the mail program. But you don't have any TextView because the input field belongs to the Mail app. And, if you want an English keyboard, there is no room for other buttons.
There is no particular need for Emoji.
The most important one is the cursor move button.
Ok, I'll do it.
- Pythonista Keyboard usable in all apps
- standard English keyboard
- left or right cursor
You would not have all cursor move possibilities, I think, because the text field of any app is not a Pythonista TextView or TextField
Do you still need emojis or do I put these left/right cursors in the same row?
If ok, it will be for tomorrow, I hope
If there is a space to put, I would like to have Emoji, but I don't mind if it isn't.
You need English and Japanese for the standard language keyboard.
@shinya.ta The Pythonista keyboard only offers English keyboard.
Of course, you can always tap the globe key to shift to another international keyboard