omz:forum

    • Register
    • Login
    • Search
    • Recent
    • Popular

    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

    Pythonista
    5
    13
    5308
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • kami
      kami last edited by

      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

      JonB 1 Reply Last reply Reply Quote 0
      • JonB
        JonB last edited by

        Try:

        1. 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.
        2. 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.
        1 Reply Last reply Reply Quote 0
        • JonB
          JonB @kami last edited by JonB

          @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.

          1 Reply Last reply Reply Quote 0
          • kami
            kami last edited by

            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

            mikael 1 Reply Last reply Reply Quote 0
            • mikael
              mikael @kami last edited by

              @kami, good to hear. If that makes app feel sluggish in use, 0.1 sec works just as well.

              1 Reply Last reply Reply Quote 0
              • kami
                kami last edited by

                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

                cvp 1 Reply Last reply Reply Quote 0
                • cvp
                  cvp @kami last edited by

                  @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')
                  
                  1 Reply Last reply Reply Quote 0
                  • kami
                    kami last edited by

                    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

                    cvp 1 Reply Last reply Reply Quote 0
                    • cvp
                      cvp @kami last edited by cvp

                      @kami With exactly this little script? For me, it is ok

                      1 Reply Last reply Reply Quote 0
                      • kami
                        kami last edited by

                        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

                        mikael 1 Reply Last reply Reply Quote 0
                        • mikael
                          mikael @kami last edited by

                          @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)
                          
                          1 Reply Last reply Reply Quote 0
                          • kami
                            kami last edited by

                            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

                            cvp 1 Reply Last reply Reply Quote 0
                            • cvp
                              cvp @kami last edited by cvp

                              @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')
                              
                              1 Reply Last reply Reply Quote 0
                              • First post
                                Last post
                              Powered by NodeBB Forums | Contributors