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.
pythonista UI
-
@shinya.ta Then, I don't understand your request.
Do you need new buttons like led, right,... or keys in the keyboard?
And what exactly are the wanted functions?
Del exists as back on the keyboard
Next is right, isn'it?
Clear is delete all? -
@shinya.ta already del with position on iPad
b_del = ui.Button() b_del.frame = (10,250,100,32) b_del.title = 'del' b_del.background_color = 'white' b_del.border_width = 1 def b_del_action(sender): tv = sender.superview['TextView'] i = tv.selected_range[0] if i < len(tv.text): tv.text = tv.text[:i] + tv.text[i+1:] #tv.selected_range = (i,i) # refused if i = len(tv.text) tvo = ObjCInstance(tv) p1 = tvo.positionFromPosition_offset_(tvo.beginningOfDocument(), i) p2 = p1 tvo.selectedTextRange = tvo.textRangeFromPosition_toPosition_(p1,p2) b_del.action = b_del_action v.add_subview(b_del)
-
@shinya.ta clear
b_clear = ui.Button() b_clear.frame = (10,290,100,32) 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)
-
Dear.@cvp
It is correct to add the button.
The biggest problem is to switch it to an existing keyboard on the iPhone.
I would like to add a keyboard for the globe of the iPhone.
-
🌐 Key button.
-
Dear.@cvp
I tried delete, and there is no response of the button.
Is it written by mistake?
b_del = ui.Button()
b_del.frame = (10,250,100,32)
b_del.title = 'del'
b_del.background_color = 'white'
b_del.border_width = 1
def b_del_action(sender):
tv = sender.superview['TextView']
i = tv.selected_range[0]
if i < len(tv.text):
tv.text = tv.text[:i] + tv.text[i+1:]
#tv.selected_range = (i,i) # refused if i = len(tv.text)
tvo = ObjCInstance(tv)
p1 = tvo.positionFromPosition_offset_(tvo.beginningOfDocument(), i)
p2 = p1
tvo.selectedTextRange = tvo.textRangeFromPosition_toPosition_(p1,p2)
b_del.action = b_del_action
v.add_subview(b_del) -
@shinya.ta It should be ok but action deletes the character of the TextView where the cursor is. If the cursor is after the last character, there is obviously no effect.
Edit: you have also to change the frame else it could fall in your TExtView.
-
@shinya.ta I dont understand why you want a globe key because it is already in the keyboard.
-
You need a button to switch from an existing keyboard to an existing keyboard on the iPhone.
It is necessary to change it during the editing of the mail.
-
I haven't tried to delete the letter yet, but I think it is probably OK.
When using Voiceover, using Textfield instead of Textview, it was successful.
-
@shinya.ta I understand why you need the globe key but why don't you use the globe key of the keyboard?
-
The iPhone is using an internal keyboard.
My wife doesn't use an external keyboard, so I need a button to switch it
I use an existing flick input for text input.
-
@shinya.ta sorry, perhaps due to my poor English but I still don't understand because the internal keyboard of the iPhone shows the globe key, isn't It?
-
I don't know the cooperation between the existing keyboard of the iPhone and the application I made this time.
-
I was able to delete it, but I want to delete it from the end position.
-
I changed it to textfield, but I can't do it well. Why is that?
import ui
from objc_util import *v = ui.View()
v.frame = (0,0,333,555)
v.name = 'Move cursor in TextFild'tf = ui.TextField()
tf.name = 'TextField'
tf.frame = (0,0,333,296)
tf.font = ('Arial Rounded MT Bold',24)
tf.text = 'this is the sentence'
v.add_subview(tf)b_del = ui.Button()
b_del.frame = (250,310,78,78)
b_del.title = '削除'
b_del.background_color = 'white'
b_del.border_width = 1
def b_del_action(sender):
tf = sender.superview['TextField']
i = tf.selected_range[0]
if i < len(tf.text):
tf.text = tf.text[:i] + tf.text[i+1:]
#tf.selected_range = (i,i) # refused if i = len(tf.text)
tfo = ObjCInstance(tf)
p1 = tfo.positionFromPosition_offset_(tfo.beginningOfDocument(), i)
p2 = p1
tfo.selectedTextRange = tfo.textRangeFromPosition_toPosition_(p1,p2)
b_del.action = b_del_action
v.add_subview(b_del)b_clear = ui.Button()
b_clear.frame = (250,475,78,78)
b_clear.title = '全削除'
b_clear.background_color = 'white'
b_clear.border_width = 1
def b_clear_action(sender):
tf = sender.superview['TextFild']
tf.text = ''
b_clear.action = b_clear_action
v.add_subview(b_clear)b_top = ui.Button()
b_top.frame = (5,310,78,78)
b_top.title = '文頭'
b_top.background_color = 'white'
b_top.border_width = 1
def b_top_action(sender):
tf = sender.superview['TextFild']
tf.selected_range = (0,0)
b_top.action = b_top_action
v.add_subview(b_top)b_left = ui.Button()
b_left.frame = (47,394,78,78)
b_left.title = '⬅︎'
b_left.background_color = 'white'
b_left.border_width = 1
def b_left_action(sender):
tf = sender.superview['TextField']
i = tf.selected_range[0] - 1
if i < 0:
i = 0
tf.selected_range = (i,i)
b_left.action = b_left_action
v.add_subview(b_left)b_right = ui.Button()
b_right.frame = (212,394,78,78)
b_right.title = '➡︎︎'
b_right.background_color = 'white'
b_right.border_width = 1
def b_right_action(sender):
tf = sender.superview['TextField']
i = tf.selected_range[0] + 1
l = len(tf.text)
if i > l:
i = l
#tf.selected_range = (i,i) # refused if i = len(tf.text)
tfo = ObjCInstance(tf)
p1 = tfo.positionFromPosition_offset_(tfo.beginningOfDocument(), i)
p2 = p1
tfo.selectedTextRange = tfo.textRangeFromPosition_toPosition_(p1,p2)
b_right.action = b_right_action
v.add_subview(b_right)b_bottom = ui.Button()
b_bottom.frame = (130,394,78,78)
b_bottom.title = '文末'
b_bottom.background_color = 'white'
b_bottom.border_width = 1
def b_bottom_action(sender):
tf = sender.superview['TextField']
l = len(tf.text)
#tf.selected_range = (l,l) # refused if l = len(tf.text)
tvo = ObjCInstance(tv)
p1 = tfo.positionFromPosition_offset_(tfo.beginningOfDocument(), l)
p2 = p1
tfo.selectedTextRange = tfo.textRangeFromPosition_toPosition_(p1,p2)
b_bottom.action = b_bottom_action
v.add_subview(b_bottom)def get_xy(tf):
tvo = ObjCInstance(tf)
x_y = []
for i in range(0,len(tf.text)+1): # x,y of each character
p1 = tfo.positionFromPosition_offset_(tfo.beginningOfDocument(), i)
rge = tfo.textRangeFromPosition_toPosition_(p1,p1)
rect = tfo.firstRectForRange_(rge) # CGRect
x,y = rect.origin.x,rect.origin.y
if i == len(tv.text):
if i > 0:
x,y = x_y[i-1]
else:
# text is empty
x,y = 0,0
x_y.append((x,y))
return x_yb_up = ui.Button()
b_up.frame = (130,310,78,78)
b_up.title = '⬆︎'
b_up.background_color = 'white'
b_up.border_width = 1
def b_up_action(sender):
tf = sender.superview['TextField']
x_y = get_xy(tf)
c = tf.selected_range[0]
xc,yc = x_y[c]
i = c - 1
while i >= 0:
x,y = x_y[i]
if y < yc:
# previous row
if x <= xc:
tv.selected_range = (i,i)
return
i = i - 1
b_up.action = b_up_action
v.add_subview(b_up)b_down = ui.Button()
b_down.frame = (130,475,78,78)
b_down.title = '⬇︎'
b_down.background_color = 'white'
b_down.border_width = 1
def b_down_action(sender):
tf = sender.superview['TextFild']
print(tf.selected_range,len(tf.text))
x_y = get_xy(tf)
c = tv.selected_range[0]
#print(x_y,c)
xc,yc = x_y[c]
i = c - 1
while i < len(tf.text):
x,y = x_y[i]
if y > yc:
# next row
if x >= xc:
tv.selected_range = (i,i)
return
else:
if (i+1) < len(tf.text):
if x_y[i+1][1] > y: # i = last character of row under cursor
tv.selected_range = (i,i)
return
else:
pass # try next x
else:
# last character of last row
tf.selected_range = (i,i)
return
i = i + 1
b_down.action = b_down_action
v.add_subview(b_down)v.present('sheet')
tf.selected_range = (0,0)
tf.begin_editing()f = ui.load_view()
f.present('sheet') -
@shinya.ta please, as I said some posts above, put your code between 3 back quotes or use the </> button because, without that, we lose the indentations and other people need to put the indentations them-self.
-
@shinya.ta A TextField has only one line, thus the method selectedTextRange does not exist. A big part of the script needs to be rewritten...
-
@shinya.ta If you want to limit the number of lines of the TextView to 1, use this
tv = ui.TextView() ObjCInstance(tv).textContainer().maximumNumberOfLines = 1
And so, your code main remain unchanged, but you don't need the up and down buttons
-