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.
Scrolling to the end of a textview
-
Hi,
i am trying to append some text to my textview field.
The text is really long but then i try to scroll to bottom in the textview. This i not working.I used this code:
def appendtextview(text): v['viewtop']['textview1'].text = v['viewtop']['textview1'].text + str(text) v['viewtop']['textview1'].content_offset = (0, v['viewtop']['textview1'].content_size[1] - v['viewtop']['textview1'].height)
Can someon help me with this?
Thanks a lot.
Cu kami
-
Try:
- wrapping that method in an on_main_thread. That might ensure that when you set the text, the content size is also updated. I believe the content_size is probably old.
- one thing we did in stash, was to add a slight ui.delay after setting text, to scroll to the desired location. I think we determined that content_size might not be immediately updated by the OS, so you have to wait.
-
@kami one other thing to try would be objc_util. This may be related to a long-standing iOS bug. The workaround suggested on SO is
-(void) scrollToBottom { [textView scrollRangeToVisible:NSMakeRange([textView.text length], 0)]; [textView setScrollEnabled:NO]; [textView setScrollEnabled:YES]; }
I haven't tried to convert this to python equivalent.
-
Hi,
this was a good idea. The short delay with 0.5 sec is enough to get down to the last row.
Thanks a lot for the help.
Cu kami
-
@kami, good to hear. If that makes app feel sluggish in use, 0.1 sec works just as well.
-
After testing a little bit, it is no running smoothly. When i scroll in the textview it is not going down to the end?
Can anyone maybe post a better version or an objc_util example?
Thanks a lot.
Cu kami
-
@kami try this
import ui from objc_util import * tv = ui.TextView() tv.frame = (0,0,500,500) tv.text = 'a'*12000 b = ui.ButtonItem() b.title = 'bottom' def b_action(sender): tvo = ObjCInstance(tv) tvo.scrollRangeToVisible_(NSRange(len(tv.text),0)) tvo.setScrollingEnabled_(False) tvo.setScrollingEnabled_(True) pass b.action = b_action tv.right_button_items = (b,) tv.present('sheet')
-
Works much better, but only every second time. First time it scrolls to the end. The second time it scrolls to much down, so the textview is empty????
Cu kami
-
@kami With exactly this little script? For me, it is ok
-
Hi,
after some testing it only works for me at everytime with a short delay of 0.4 sec.
Otherwise it comes to some errors. Is it possible to check first if the textview is reloaded and then scroll down?
Thanks a lot.
Cu kami
-
@kami, here’s an alternative approach. You can add a guard variable in
update
if you do not want to have it constantly ”running”.import ui class ScrollToBottomTextView(ui.View): def __init__(self, **kwargs): super().__init__(**kwargs) self.tv = ui.TextView( frame=self.bounds, flex='WH' ) self.add_subview(self.tv) self.update_interval = 1/60 def update(self): self.tv.content_offset = ( 0, self.tv.content_size[1]-self.height) if __name__ == '__main__': v = ScrollToBottomTextView() v.present() import requests text = requests.get('https://forum.omz-software.com/topic/5744/scrolling-to-the-end-of-a-textview').text lines = text.splitlines() i = 0 def add_line(): global lines, i v.tv.text += lines[i] + '\n' i += 1 ui.delay(add_line, 0.5) ui.delay(add_line, 0.5)
-
Hi,
i am trying this function under ios 16.3 and it is not working anymore.
def scroll() : tvo = ObjCInstance(main['textview1']) tvo.scrollRangeToVisible_(NSRange(len(main['textview1'].text),0)) tvo.setScrollingEnabled_(False) tvo.setScrollingEnabled_(True)
Can someone help me with this?
BR kami
-
@kami For me, my little script here-under still works under iOS 16.3 and Pythonista beta
import ui from objc_util import * tv = ui.TextView() tv.frame = (0,0,500,500) tv.text = 'a'*12000 b = ui.ButtonItem() b.title = 'bottom' def b_action(sender): tvo = ObjCInstance(tv) tvo.scrollRangeToVisible_(NSRange(len(tv.text),0)) tvo.setScrollingEnabled_(False) tvo.setScrollingEnabled_(True) pass b.action = b_action tv.right_button_items = (b,) tv.present('sheet')
-
-
@kami
Yeah, this is a good idea. you can follow this.