每次我更改文本时,如何强制UITextView滚动到顶部?

时间:2022-08-25 07:44:03

OK, I'm having some problem with the UITextView. Here's the issue:

好的,我对UITextView有一些问题。这是问题:

I add some text to a UITextView. The user then double clicks to select something. I then change the text in the UITextView (programatically as above) and the UITextView scrolls to the bottom of the page where there is a cursor.

我在UITextView中添加一些文本。然后用户双击以选择某样东西。然后,我在UITextView中更改文本(如上面所示),并且UITextView滚动到页面的底部,那里有一个游标。

However, that is NOT where the user clicked. It ALWAYS scrolls to the bottom of the UITextView regardless of where the user clicked.

但是,这不是用户单击的地方。无论用户点击的位置,它总是会滚动到UITextView的底部。

So here's my question: How do I force the UITextView to scroll to the top every time I change the text? I've tried contentOffset and scrollRangeToVisible. Neither work.

我的问题是:我如何强制UITextView在每次修改文本时滚动到顶部?我试过了contentOffset和scrollRangeToVisible。既不工作。

Any suggestions would be appreciated.

如有任何建议,我们将不胜感激。

32 个解决方案

#1


119  

UITextView*note;
[note setContentOffset:CGPointZero animated:YES];

This does it for me.

这是为我做的。

#2


59  

If anyone has this problem in iOS 8, I found that just setting the UITextView's text property, then calling scrollRangeToVisible with an NSRange with location:0, length:0, worked. My text view was not editable, and I tested both selectable and not selectable (neither setting affected the result). Here's a Swift example:

如果有人在ios8中有这个问题,我发现只是设置UITextView的文本属性,然后调用scrollRangeToVisible与一个NSRange(位置:0,长度:0)工作。我的文本视图不是可编辑的,我测试了两个可选择的和不可选择的(没有设置影响结果)。这是一个快速的例子:

myTextView.text = "Text that is long enough to scroll"
myTextView.scrollRangeToVisible(NSRange(location:0, length:0))

#3


35  

And here is my solution...

这是我的解决方案…

    override func viewDidLoad() {
        textView.scrollEnabled = false
        textView.text = "your text"
    }

    override func viewDidAppear(animated: Bool) {
        textView.scrollEnabled = true
    }

#4


31  

Calling

调用

scrollRangeToVisible(NSMakeRange(0, 0))

works but call it in

工作,但叫它进来。

override func viewDidAppear(animated: Bool)

#5


25  

I was using attributedString in HTML with text view not editable. Setting the content offset did not work for me either. This worked for me: disable scroll enabled, set the text and then enable the scrolling again

我使用的是HTML中的attributedString,文本视图无法编辑。设置内容偏移量对我也不起作用。这对我有效:禁用滚动,设置文本,然后再次启用滚动。

[yourTextView setScrollEnabled:NO];
yourTextView.text = yourtext;
[yourTextView setScrollEnabled:YES];

#6


16  

I'm not sure if I understand your question, but are you trying to simply scroll the view to the top? If so you should do

我不确定我是否理解你的问题,但你是想简单地把视图滚动到顶部吗?如果是这样,你应该这样做。

[textview scrollRectToVisible:CGRectMake(0,0,1,1) animated:YES];

[textview scrollRectToVisible:CGRectMake(0,0,1,1)动画:是的);

#7


15  

Since none of these solutions worked for me and I wasted way too much time piecing together solutions, this finally solved it for me.

因为这些解决方案对我都不起作用,而且我浪费了太多的时间来拼凑解决方案,这最终为我解决了问题。

override func viewWillAppear(animated: Bool) {
    dispatch_async(dispatch_get_main_queue(), {
        let desiredOffset = CGPoint(x: 0, y: -self.textView.contentInset.top)
        self.textView.setContentOffset(desiredOffset, animated: false)
    })
}

This is really silly that this is not default behavior for this control.

这是非常愚蠢的,这不是这个控件的默认行为。

I hope this helps someone else out.

我希望这能帮助别人。

#8


8  

This is how it worked on iOS 9 Release so as the textView is scrolled on top before appearing on screen

这是它在ios9版本上的工作方式,所以当textView在屏幕上出现时,它会在顶部滚动。

- (void)viewDidLoad
{
    [super viewDidLoad];
    textView.scrollEnabled = NO;
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    textView.scrollEnabled = YES;
}

#9


8  

For iOS 10 and Swift 3 I did:

对于iOS 10和Swift 3,我做到了:

override func viewDidLoad() {
    super.viewDidLoad()
    textview.isScrollEnabled = false
}

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    textView.isScrollEnabled = true
}

Worked for me, not sure if you're having the problem with the latest version of Swift and iOS.

为我工作,不确定你是否有最新版本的Swift和iOS的问题。

#10


7  

I have an updated answer which will have the textview appear properly, and without the user experiencing a scroll animation.

我有一个更新的答案,它将使textview显示正确,并且没有用户体验滚动动画。

override func viewWillAppear(animated: Bool) {
    dispatch_async(dispatch_get_main_queue(), {
        self.introductionText.scrollRangeToVisible(NSMakeRange(0, 0))
    })

#11


5  

Try this to move the cursor to the top of the text.

尝试将光标移到文本的顶部。

NSRange r  = {0,0};
[yourTextView setSelectedRange:r];

See how that goes. Make sure you call this after all your events have fired or what ever you are doing is done.

拭目以待。在你所有的事情都被炒掉或者你做了什么之后,一定要把它记下来。

#12


5  

[txtView setContentOffset:CGPointMake(0.0, 0.0) animated:YES];

This line of code works for me.

这行代码对我有效。

#13


4  

My issue is to set textView to scroll to top when view appeared. For iOS 10.3.2, and Swift 3.

我的问题是,当视图出现时,将textView设置为滚动到顶部。对于iOS 10.3.2和Swift 3。

Solution 1:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    // It doesn't work. Very strange.
    self.textView.setContentOffset(CGPoint.zero, animated: false)
}
override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    // It works, but with an animation effection.
    self.textView.setContentOffset(CGPoint.zero, animated: false)
}

Solution 2:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    // It works.       
    self.textView.contentOffset = CGPoint.zero
}

#14


3  

Combined the previous answers, now it should work:

结合前面的答案,现在它应该工作:

talePageText.scrollEnabled = false
talePageText.textColor = UIColor.blackColor()
talePageText.font = UIFont(name: "Bradley Hand", size: 24.0)
talePageText.contentOffset = CGPointZero
talePageText.scrollRangeToVisible(NSRange(location:0, length:0))
talePageText.scrollEnabled = true

#15


3  

This worked for me. It is based on RyanTCBs answer but it is the Objective-C variant of the same solution:

这为我工作。它基于RyanTCBs的答案,但它是同一解决方案的Objective-C变体:

- (void) viewWillAppear:(BOOL)animated {
    // For some reason the text view, which is a scroll view, did scroll to the end of the text which seems to hide the imprint etc at the beginning of the text.
    // On some devices it is not obvious that there is more text when the user scrolls up.
    // Therefore we need to scroll textView to the top.
    [self.textView scrollRangeToVisible:NSMakeRange(0, 0)];
}

#16


3  

Swift 2 Answer:

斯威夫特2回答:

textView.scrollEnabled = false

/* Set the content of your textView here */

textView.scrollEnabled = true

This prevents the textView from scrolling to the end of the text after setting it.

这样可以防止textView设置后滚动到文本的末尾。

#17


3  

-(void) viewDidAppear:(BOOL)animated{
[mytextView scrollRangeToVisible:NSMakeRange(0,0)];}

- (void)viewWillAppear:(BOOL)animated{
[mytextView scrollRangeToVisible:NSMakeRange(0,0)];}
  • ViewWillappear will do it instantly before user can notice, but ViewDidDisappear section will animate it lazily.
  • ViewWillappear会在用户通知之前立即进行,但是ViewDidDisappear部分会让它被延迟。
  • [mytextView setContentOffset:CGPointZero animated:YES]; does NOT work sometimes(I don't know why), so use scrollrangetovisible rather.
  • [mytextView setContentOffset:CGPointZero动画:是的);有时不工作(我不知道为什么),所以使用scrollrangetovisible。

#18


3  

Problem solved: iOS = 10.2 Swift 3 UITextView

问题解决:iOS = 10.2 Swift 3 UITextView。

I just used the following line:

我只是用了下面一行:

displayText.contentOffset.y = 0

#19


3  

In Swift 3:

在斯威夫特3:

  • viewWillLayoutSubviews is the place to make changes. viewWillAppear should work as well, but logically, layout should be perform in viewWillLayoutSubviews.

    viewWillLayoutSubviews是进行更改的地方。viewWillAppear也应该工作,但是逻辑上,布局应该在viewWillLayoutSubviews中执行。

  • Regarding methods, both scrollRangeToVisible and setContentOffset will work. However, setContentOffset allows animation to be off or on.

    对于方法,scrollRangeToVisible和setContentOffset都可以工作。然而,setContentOffset允许动画关闭或打开。

Assume the UITextView is named as yourUITextView. Here's the code:

假设UITextView被命名为yourUITextView。这是代码:

// Connects to the TextView in the interface builder.
@IBOutlet weak var yourUITextView: UITextView!

/// Overrides the viewWillLayoutSubviews of the super class.
override func viewWillLayoutSubviews() {

    // Ensures the super class is happy.
    super.viewWillLayoutSubviews()

    // Option 1:
    // Scrolls to a range of text, (0,0) in this very case, animated.
    yourUITextView.scrollRangeToVisible(NSRange(location: 0, length: 0))

    // Option 2:
    // Sets the offset directly, optional animation.
    yourUITextView.setContentOffset(CGPoint(x: 0, y: 0), animated: false)
}

#20


2  

[self.textView scrollRectToVisible:CGRectMake(0, 0, 320, self.textView.frame.size.height) animated:NO];

#21


2  

-(void)viewWillLayoutSubviews{
    [super viewWillLayoutSubviews];

    [textview setContentOffset:CGPointZero animated:NO];
}

#22


2  

just you can use this code

您可以使用此代码。

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    textView.scrollRangeToVisible(NSMakeRange(0, 0))
}

#23


1  

For me fine works this code:

对我来说,这段代码很好:

    textView.attributedText = newText //or textView.text = ...

    //this part of code scrolls to top
    textView.contentOffset.y = -64
    textView.scrollEnabled = false
    textView.layoutIfNeeded() //if don't work, try to delete this line
    textView.scrollEnabled = true

For scroll to exact position and show it on top of screen I use this code:

滚动到准确的位置并显示在屏幕上方我使用这段代码:

    var scrollToLocation = 50 //<needed position>
    textView.contentOffset.y = textView.contentSize.height
    textView.scrollRangeToVisible(NSRange.init(location: scrollToLocation, length: 1))

Setting contentOffset.y scrolls to the end of text, and then scrollRangeToVisible scrolls up to value of scrollToLocation. Thereby, needed position appears in first line of scrollView.

设置内容偏移。将y轴滚动到文本的末尾,然后滚动到可见的滚动到scrollToLocation的值。因此,需要的位置出现在scrollView的第一行。

#24


1  

For me in iOS 9 it stopped to work for me with attributed string with method scrollRangeToVisible (the 1 row was with bold font, other rows were with regular font)

在ios9中,我使用带属性字符串的方法来为我工作,方法是scrollRangeToVisible(第一行是粗体,其他行是常规字体)

So I had to use:

所以我不得不使用:

textViewMain.attributedText = attributedString
textViewMain.scrollRangeToVisible(NSRange(location:0, length:0))
delay(0.0, closure: { 
                self.textViewMain.scrollRectToVisible(CGRectMake(0, 0, 10, 10), animated: false)
            })

where delay is:

延迟在哪里:

func delay(delay:Double, closure:()->Void) {
    dispatch_after(
        dispatch_time(
            DISPATCH_TIME_NOW,
            Int64(delay * Double(NSEC_PER_SEC))
        ),
        dispatch_get_main_queue(), closure)
}

#25


1  

Try to use this 2 lines solution:

尝试使用这两行解决方案:

view.layoutIfNeeded()
textView.contentOffset = CGPointMake(textView.contentInset.left, textView.contentInset.top)

#26


1  

I had the problem, but in my case textview is the subview of some custom view and added it to ViewController. None of the solution worked for me. To solve the problem added 0.1 sec delay and then enabled scroll. It worked for me.

我有这个问题,但在我的案例中,textview是一些自定义视图的子视图,并将它添加到ViewController中。没有一个解决方案对我有效。为了解决这个问题,增加了0.1秒的延迟,然后启用了滚动。它为我工作。

textView.isScrollEnabled = false
..
textView.text = // set your text here

let dispatchTime = DispatchTime.now() + 0.1
DispatchQueue.main.asyncAfter(deadline: dispatchTime) {
   self.textView.isScrollEnabled = true
}

#27


1  

Here are my codes. It works fine.

下面是我的代码。它将正常工作。

class MyViewController: ... 
{
  private offsetY: CGFloat = 0
  @IBOutlet weak var textView: UITextView!
  ...

  override viewWillAppear(...) 
  {
      ...
      offsetY = self.textView.contentOffset.y
      ...
  }
  ...
  func refreshView() {
      let offSetY = textView.contentOffset.y
      self.textView.setContentOffset(CGPoint(x:0, y:0), animated: true)
      DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
        [unowned self] in
        self.textView.setContentOffset(CGPoint(x:0, y:self.offSetY), 
           animated: true)
        self.textView.setNeedsDisplay()
      }
  }

#28


1  

I think the reason why some people are having problems with this issue is because they are trying to set the TextView scroll position, before this TextView has appeared.

我认为一些人在这个问题上有问题的原因是他们试图在TextView出现之前设置TextView滚动位置。

There is nothing to scroll, when the TextView hasn't yet appeared.

当TextView还没有出现时,没有什么可滚动的。

You need to wait for the TextView to appear first, and only then set its scroll position inside the viewDidAppear method as shown below:

您需要等待TextView首先出现,然后才在viewDidAppear方法中设置它的滚动位置,如下所示:

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    textView.setContentOffset(CGPoint.zero, animated: false)
}

#29


1  

That's how I did it

我就是这么做的。

Swift 4:

斯威夫特4:

extension UITextView {

    override open func draw(_ rect: CGRect)
    {
        super.draw(rect)
        setContentOffset(CGPoint.zero, animated: false)
    }

 }

#30


0  

Swift 3 version of drew_s answer earlier, which is the only thing that worked for me after trying most of the other answers.

快速的3版drew_s的回答,这是我在尝试了大多数其他的答案后唯一有效的方法。

    override func viewWillAppear(_ animated: Bool) {
    DispatchQueue.main.async{
        let desiredOffset = CGPoint(x: 0, y: -self.person_description.contentInset.top)
        self.person_description.setContentOffset(desiredOffset, animated: false)
    }
}

This was a cut and paste of working code. Replace person_description with your textview variable.

这是一个剪切和粘贴的工作代码。用textview变量替换person_description。

#1


119  

UITextView*note;
[note setContentOffset:CGPointZero animated:YES];

This does it for me.

这是为我做的。

#2


59  

If anyone has this problem in iOS 8, I found that just setting the UITextView's text property, then calling scrollRangeToVisible with an NSRange with location:0, length:0, worked. My text view was not editable, and I tested both selectable and not selectable (neither setting affected the result). Here's a Swift example:

如果有人在ios8中有这个问题,我发现只是设置UITextView的文本属性,然后调用scrollRangeToVisible与一个NSRange(位置:0,长度:0)工作。我的文本视图不是可编辑的,我测试了两个可选择的和不可选择的(没有设置影响结果)。这是一个快速的例子:

myTextView.text = "Text that is long enough to scroll"
myTextView.scrollRangeToVisible(NSRange(location:0, length:0))

#3


35  

And here is my solution...

这是我的解决方案…

    override func viewDidLoad() {
        textView.scrollEnabled = false
        textView.text = "your text"
    }

    override func viewDidAppear(animated: Bool) {
        textView.scrollEnabled = true
    }

#4


31  

Calling

调用

scrollRangeToVisible(NSMakeRange(0, 0))

works but call it in

工作,但叫它进来。

override func viewDidAppear(animated: Bool)

#5


25  

I was using attributedString in HTML with text view not editable. Setting the content offset did not work for me either. This worked for me: disable scroll enabled, set the text and then enable the scrolling again

我使用的是HTML中的attributedString,文本视图无法编辑。设置内容偏移量对我也不起作用。这对我有效:禁用滚动,设置文本,然后再次启用滚动。

[yourTextView setScrollEnabled:NO];
yourTextView.text = yourtext;
[yourTextView setScrollEnabled:YES];

#6


16  

I'm not sure if I understand your question, but are you trying to simply scroll the view to the top? If so you should do

我不确定我是否理解你的问题,但你是想简单地把视图滚动到顶部吗?如果是这样,你应该这样做。

[textview scrollRectToVisible:CGRectMake(0,0,1,1) animated:YES];

[textview scrollRectToVisible:CGRectMake(0,0,1,1)动画:是的);

#7


15  

Since none of these solutions worked for me and I wasted way too much time piecing together solutions, this finally solved it for me.

因为这些解决方案对我都不起作用,而且我浪费了太多的时间来拼凑解决方案,这最终为我解决了问题。

override func viewWillAppear(animated: Bool) {
    dispatch_async(dispatch_get_main_queue(), {
        let desiredOffset = CGPoint(x: 0, y: -self.textView.contentInset.top)
        self.textView.setContentOffset(desiredOffset, animated: false)
    })
}

This is really silly that this is not default behavior for this control.

这是非常愚蠢的,这不是这个控件的默认行为。

I hope this helps someone else out.

我希望这能帮助别人。

#8


8  

This is how it worked on iOS 9 Release so as the textView is scrolled on top before appearing on screen

这是它在ios9版本上的工作方式,所以当textView在屏幕上出现时,它会在顶部滚动。

- (void)viewDidLoad
{
    [super viewDidLoad];
    textView.scrollEnabled = NO;
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    textView.scrollEnabled = YES;
}

#9


8  

For iOS 10 and Swift 3 I did:

对于iOS 10和Swift 3,我做到了:

override func viewDidLoad() {
    super.viewDidLoad()
    textview.isScrollEnabled = false
}

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    textView.isScrollEnabled = true
}

Worked for me, not sure if you're having the problem with the latest version of Swift and iOS.

为我工作,不确定你是否有最新版本的Swift和iOS的问题。

#10


7  

I have an updated answer which will have the textview appear properly, and without the user experiencing a scroll animation.

我有一个更新的答案,它将使textview显示正确,并且没有用户体验滚动动画。

override func viewWillAppear(animated: Bool) {
    dispatch_async(dispatch_get_main_queue(), {
        self.introductionText.scrollRangeToVisible(NSMakeRange(0, 0))
    })

#11


5  

Try this to move the cursor to the top of the text.

尝试将光标移到文本的顶部。

NSRange r  = {0,0};
[yourTextView setSelectedRange:r];

See how that goes. Make sure you call this after all your events have fired or what ever you are doing is done.

拭目以待。在你所有的事情都被炒掉或者你做了什么之后,一定要把它记下来。

#12


5  

[txtView setContentOffset:CGPointMake(0.0, 0.0) animated:YES];

This line of code works for me.

这行代码对我有效。

#13


4  

My issue is to set textView to scroll to top when view appeared. For iOS 10.3.2, and Swift 3.

我的问题是,当视图出现时,将textView设置为滚动到顶部。对于iOS 10.3.2和Swift 3。

Solution 1:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    // It doesn't work. Very strange.
    self.textView.setContentOffset(CGPoint.zero, animated: false)
}
override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    // It works, but with an animation effection.
    self.textView.setContentOffset(CGPoint.zero, animated: false)
}

Solution 2:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    // It works.       
    self.textView.contentOffset = CGPoint.zero
}

#14


3  

Combined the previous answers, now it should work:

结合前面的答案,现在它应该工作:

talePageText.scrollEnabled = false
talePageText.textColor = UIColor.blackColor()
talePageText.font = UIFont(name: "Bradley Hand", size: 24.0)
talePageText.contentOffset = CGPointZero
talePageText.scrollRangeToVisible(NSRange(location:0, length:0))
talePageText.scrollEnabled = true

#15


3  

This worked for me. It is based on RyanTCBs answer but it is the Objective-C variant of the same solution:

这为我工作。它基于RyanTCBs的答案,但它是同一解决方案的Objective-C变体:

- (void) viewWillAppear:(BOOL)animated {
    // For some reason the text view, which is a scroll view, did scroll to the end of the text which seems to hide the imprint etc at the beginning of the text.
    // On some devices it is not obvious that there is more text when the user scrolls up.
    // Therefore we need to scroll textView to the top.
    [self.textView scrollRangeToVisible:NSMakeRange(0, 0)];
}

#16


3  

Swift 2 Answer:

斯威夫特2回答:

textView.scrollEnabled = false

/* Set the content of your textView here */

textView.scrollEnabled = true

This prevents the textView from scrolling to the end of the text after setting it.

这样可以防止textView设置后滚动到文本的末尾。

#17


3  

-(void) viewDidAppear:(BOOL)animated{
[mytextView scrollRangeToVisible:NSMakeRange(0,0)];}

- (void)viewWillAppear:(BOOL)animated{
[mytextView scrollRangeToVisible:NSMakeRange(0,0)];}
  • ViewWillappear will do it instantly before user can notice, but ViewDidDisappear section will animate it lazily.
  • ViewWillappear会在用户通知之前立即进行,但是ViewDidDisappear部分会让它被延迟。
  • [mytextView setContentOffset:CGPointZero animated:YES]; does NOT work sometimes(I don't know why), so use scrollrangetovisible rather.
  • [mytextView setContentOffset:CGPointZero动画:是的);有时不工作(我不知道为什么),所以使用scrollrangetovisible。

#18


3  

Problem solved: iOS = 10.2 Swift 3 UITextView

问题解决:iOS = 10.2 Swift 3 UITextView。

I just used the following line:

我只是用了下面一行:

displayText.contentOffset.y = 0

#19


3  

In Swift 3:

在斯威夫特3:

  • viewWillLayoutSubviews is the place to make changes. viewWillAppear should work as well, but logically, layout should be perform in viewWillLayoutSubviews.

    viewWillLayoutSubviews是进行更改的地方。viewWillAppear也应该工作,但是逻辑上,布局应该在viewWillLayoutSubviews中执行。

  • Regarding methods, both scrollRangeToVisible and setContentOffset will work. However, setContentOffset allows animation to be off or on.

    对于方法,scrollRangeToVisible和setContentOffset都可以工作。然而,setContentOffset允许动画关闭或打开。

Assume the UITextView is named as yourUITextView. Here's the code:

假设UITextView被命名为yourUITextView。这是代码:

// Connects to the TextView in the interface builder.
@IBOutlet weak var yourUITextView: UITextView!

/// Overrides the viewWillLayoutSubviews of the super class.
override func viewWillLayoutSubviews() {

    // Ensures the super class is happy.
    super.viewWillLayoutSubviews()

    // Option 1:
    // Scrolls to a range of text, (0,0) in this very case, animated.
    yourUITextView.scrollRangeToVisible(NSRange(location: 0, length: 0))

    // Option 2:
    // Sets the offset directly, optional animation.
    yourUITextView.setContentOffset(CGPoint(x: 0, y: 0), animated: false)
}

#20


2  

[self.textView scrollRectToVisible:CGRectMake(0, 0, 320, self.textView.frame.size.height) animated:NO];

#21


2  

-(void)viewWillLayoutSubviews{
    [super viewWillLayoutSubviews];

    [textview setContentOffset:CGPointZero animated:NO];
}

#22


2  

just you can use this code

您可以使用此代码。

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    textView.scrollRangeToVisible(NSMakeRange(0, 0))
}

#23


1  

For me fine works this code:

对我来说,这段代码很好:

    textView.attributedText = newText //or textView.text = ...

    //this part of code scrolls to top
    textView.contentOffset.y = -64
    textView.scrollEnabled = false
    textView.layoutIfNeeded() //if don't work, try to delete this line
    textView.scrollEnabled = true

For scroll to exact position and show it on top of screen I use this code:

滚动到准确的位置并显示在屏幕上方我使用这段代码:

    var scrollToLocation = 50 //<needed position>
    textView.contentOffset.y = textView.contentSize.height
    textView.scrollRangeToVisible(NSRange.init(location: scrollToLocation, length: 1))

Setting contentOffset.y scrolls to the end of text, and then scrollRangeToVisible scrolls up to value of scrollToLocation. Thereby, needed position appears in first line of scrollView.

设置内容偏移。将y轴滚动到文本的末尾,然后滚动到可见的滚动到scrollToLocation的值。因此,需要的位置出现在scrollView的第一行。

#24


1  

For me in iOS 9 it stopped to work for me with attributed string with method scrollRangeToVisible (the 1 row was with bold font, other rows were with regular font)

在ios9中,我使用带属性字符串的方法来为我工作,方法是scrollRangeToVisible(第一行是粗体,其他行是常规字体)

So I had to use:

所以我不得不使用:

textViewMain.attributedText = attributedString
textViewMain.scrollRangeToVisible(NSRange(location:0, length:0))
delay(0.0, closure: { 
                self.textViewMain.scrollRectToVisible(CGRectMake(0, 0, 10, 10), animated: false)
            })

where delay is:

延迟在哪里:

func delay(delay:Double, closure:()->Void) {
    dispatch_after(
        dispatch_time(
            DISPATCH_TIME_NOW,
            Int64(delay * Double(NSEC_PER_SEC))
        ),
        dispatch_get_main_queue(), closure)
}

#25


1  

Try to use this 2 lines solution:

尝试使用这两行解决方案:

view.layoutIfNeeded()
textView.contentOffset = CGPointMake(textView.contentInset.left, textView.contentInset.top)

#26


1  

I had the problem, but in my case textview is the subview of some custom view and added it to ViewController. None of the solution worked for me. To solve the problem added 0.1 sec delay and then enabled scroll. It worked for me.

我有这个问题,但在我的案例中,textview是一些自定义视图的子视图,并将它添加到ViewController中。没有一个解决方案对我有效。为了解决这个问题,增加了0.1秒的延迟,然后启用了滚动。它为我工作。

textView.isScrollEnabled = false
..
textView.text = // set your text here

let dispatchTime = DispatchTime.now() + 0.1
DispatchQueue.main.asyncAfter(deadline: dispatchTime) {
   self.textView.isScrollEnabled = true
}

#27


1  

Here are my codes. It works fine.

下面是我的代码。它将正常工作。

class MyViewController: ... 
{
  private offsetY: CGFloat = 0
  @IBOutlet weak var textView: UITextView!
  ...

  override viewWillAppear(...) 
  {
      ...
      offsetY = self.textView.contentOffset.y
      ...
  }
  ...
  func refreshView() {
      let offSetY = textView.contentOffset.y
      self.textView.setContentOffset(CGPoint(x:0, y:0), animated: true)
      DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
        [unowned self] in
        self.textView.setContentOffset(CGPoint(x:0, y:self.offSetY), 
           animated: true)
        self.textView.setNeedsDisplay()
      }
  }

#28


1  

I think the reason why some people are having problems with this issue is because they are trying to set the TextView scroll position, before this TextView has appeared.

我认为一些人在这个问题上有问题的原因是他们试图在TextView出现之前设置TextView滚动位置。

There is nothing to scroll, when the TextView hasn't yet appeared.

当TextView还没有出现时,没有什么可滚动的。

You need to wait for the TextView to appear first, and only then set its scroll position inside the viewDidAppear method as shown below:

您需要等待TextView首先出现,然后才在viewDidAppear方法中设置它的滚动位置,如下所示:

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    textView.setContentOffset(CGPoint.zero, animated: false)
}

#29


1  

That's how I did it

我就是这么做的。

Swift 4:

斯威夫特4:

extension UITextView {

    override open func draw(_ rect: CGRect)
    {
        super.draw(rect)
        setContentOffset(CGPoint.zero, animated: false)
    }

 }

#30


0  

Swift 3 version of drew_s answer earlier, which is the only thing that worked for me after trying most of the other answers.

快速的3版drew_s的回答,这是我在尝试了大多数其他的答案后唯一有效的方法。

    override func viewWillAppear(_ animated: Bool) {
    DispatchQueue.main.async{
        let desiredOffset = CGPoint(x: 0, y: -self.person_description.contentInset.top)
        self.person_description.setContentOffset(desiredOffset, animated: false)
    }
}

This was a cut and paste of working code. Replace person_description with your textview variable.

这是一个剪切和粘贴的工作代码。用textview变量替换person_description。