How can I set UITextView selectedTextRange with an

2019-07-19 11:07发布

I've been trying to figure out a way to set the cursor to the bottom of a long UITextView with animation. Setting it wasn't too difficult, in fact this answer covers it very well. https://stackoverflow.com/a/34922332/563381

However, animating it isn't so easy. There isn't a setSelectedTextRange(animated:) that I can find. Setting it inside a UIView.animate... block doesn't seem to do anything. The best I've been able to come up with is to animate the scroll manually then in the completion set the selectedTextRange. However this is fragile, often looks choppy, and seems on occasion to not work at all.

When you set selectedTextRange it does jump to that location. If there was a way to avoid that jump the animation might be smoother and at least would be less fragile since it wouldn't require a delay and you could use setContentOffset(animated) without needing to wait to set the selectedTextRange.

The other option is to find a way to cause the selectedTextRange jump to be animated itself. On this front I tried the trick of disabling scrolling before and reenabling after but that didn't seem to work for me. Guessing that has changed in later versions of iOS.

1条回答
倾城 Initia
2楼-- · 2019-07-19 11:49

You can use setContentOffset(_, animated:) and detect the end of the animation with scrollViewDidEndScrollingAnimation and set the cursor like so:

// The action to scroll down
@IBAction func test(_ sender: Any) {

    let offset = self.textView.contentSize.height - self.textView.frame.height
    self.textView.setContentOffset(CGPoint(x: 0, y: offset), animated: true)
}

// Setting the cursor down
func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {

    let offset = self.textView.contentSize.height - self.textView.frame.height

    if scrollView.contentOffset == CGPoint(x: 0, y: offset) {
        let newPosition = textView.endOfDocument
        self.textView.selectedTextRange = self.textView.textRange(from: newPosition, to: newPosition)
    }
}

You will need to add UITextViewDelegate to your view controller and set the textView delegate:

textView.delegate = self
查看更多
登录 后发表回答