UITextView starts at Bottom or Middle of the text

后端 未结 19 1556
谎友^
谎友^ 2020-12-04 13:09

I\'ll get right to it. I have a UItextView placed in my view that when needs to scroll to see all the text (when a lot of text is present in the textView) the t

相关标签:
19条回答
  • 2020-12-04 13:19

    This worked for me with Xcode 8.3.3:

    -(void)viewWillLayoutSubviews
    {
        [super viewWillLayoutSubviews];
        [self.txtQuestion scrollRangeToVisible:NSMakeRange(0, 0)];
    }
    
    0 讨论(0)
  • 2020-12-04 13:22

    That did the trick for me!

    Objective C:

    [self.textView scrollRangeToVisible:NSMakeRange(0, 0)];
    

    Swift:

    self.textView.scrollRangeToVisible(NSMakeRange(0, 0))
    

    Swift 2 (Alternate Solution)

    Add this override method to your ViewController

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        textView.setContentOffset(CGPointZero, animated: false)
    }
    

    Swift 3 & 4 (syntax edit)

    override func viewDidLayoutSubviews() {
      super.viewDidLayoutSubviews()
    
      textView.contentOffset = .zero
    }
    
    0 讨论(0)
  • 2020-12-04 13:22

    UITextView scrolling seems to be a problem to a lot of people. Gathering from the answers here around (especially this) and the Apple Developer documentation, using some of my own wit, here is a solution that works for me. You can modify the code to suit your needs.

    My use case is as follows: the same UITextView is used for different purposes, displaying varying content in different circumstances. What I want is that when the content changes, the old scroll position is restored, or at times, scrolled to the end. I don't want too much animation when this is done. Especially I don't want the view to animate like all the text was new. This solution first restores the old scroll position without animation, then scrolls to the end animated, if so desired.

    What you need to do (or should I say can do) is extend UITextView as follows:

    extension UITextView {
      func setText(text: String, storedOffset: CGPoint, scrollToEnd: Bool) {
        self.text = text
        let delayInSeconds = 0.001
        let popTime: dispatch_time_t = dispatch_time(DISPATCH_TIME_NOW, Int64(delayInSeconds * Double(NSEC_PER_SEC)))
        dispatch_after(popTime, dispatch_get_main_queue(), {
          self.setContentOffset(storedOffset, animated: false)
          if scrollToEnd && !text.isEmpty {
            let popTime: dispatch_time_t = dispatch_time(DISPATCH_TIME_NOW, Int64(delayInSeconds * Double(NSEC_PER_SEC)))
            dispatch_after(popTime, dispatch_get_main_queue(), {
              self.scrollRangeToVisible(NSMakeRange(text.lengthOfBytesUsingEncoding(NSUTF8StringEncoding) - 1, 0))
            })
          }
        })
      }
    }
    

    What this does is it updates the text, then uses a stored value of the UITextView.contentOffset property (or anything you pass as a parameter), and sets the offset of the view accordingly. If desired, after this, it scrolls to the end of the new, potentially changed content.

    I'm new to iOS programming and I don't know why it works so well it does, if someone has some information on this it would be nice to know. Also the approach may not be perfect so I'm open to improvement ideas as well.

    And of course thanks to NixonsBack for posting the answer behind the link above.

    My first post :), cheers!

    0 讨论(0)
  • 2020-12-04 13:23

    Xcode 7.2 7c68; IOS 9.1

    My ViewController which contains UITextView is complicated, and changed a lot during the project (IDE version changed maybe 2~3 times too).

    I've tried all above solutions, if you encounter the same issue, be PATIENT.

    There are three possible 'secret codes' to solve:

    1. textView.scrollEnabled = false //then set text textView.scrollEnabled = true
    2. textView.scrollRangeToVisible(NSMakeRange(0, 0))
    3. textView.setContentOffset(CGPointZero, animated: false)

    And there are two places you can put those codes in:

    1. viewDidLoad()
    2. viewDidLayoutSubviews()

    Combine them, you'll get 3*2=6 solutions, the correct combination depends on how complicated you ViewController is (Believe me, after delete just a view above textView, I need to find a new combination).

    And I found that:

    When put 'secret codes' in viewDidLayoutSubviews(), but textView.text = someStrings in viewDidLoad(), the content in textView will 'shake' sometimes. So, put them in the same place.

    Last word: try ALL combinations, this is how I solve this stupid bug more than three times during two months.

    0 讨论(0)
  • 2020-12-04 13:24

    Try this below code -

    if ( [self respondsToSelector:@selector(setAutomaticallyAdjustsScrollViewInsets:)]){
         self.automaticallyAdjustsScrollViewInsets = NO;         
    }
    

    Or you can also set this property by StoryBoard -

    Select ViewController then select attributes inspector now unchecked Adjust Scroll View Insets.

    0 讨论(0)
  • 2020-12-04 13:26

    Update your UINavigationBar's translucent property to NO:

    self.navigationController.navigationBar.translucent = NO;
    

    This will fix the view from being framed underneath the navigation bar and status bar.

    If you have to show and hide the navigation bar, then use below code in your viewDidLoad

     if ([self respondsToSelector:@selector(edgesForExtendedLayout)])
        self.edgesForExtendedLayout = UIRectEdgeNone;   // iOS 7 specific
    

    Hope this helps.

    0 讨论(0)
提交回复
热议问题