好的,我在使用UITextView
时遇到了一些问题。这是问题所在:
我向UITextView
添加了一些文字。然后用户双击以选择某些内容。
然后我将UITextView
中的文本(以编程方式如上所述)和UITextView
滚动更改为有光标的页面底部。
但是,这不是用户点击的地方。无论用户点击何处,它始终滚动到UITextView
的底部。
所以这是我的问题:每次更改文本时,如何强制UITextView
滚动到顶部?我试过了contentOffset
和scrollRangeToVisible
。都没有工作。
任何建议都将不胜感激。
答案 0 :(得分:142)
UITextView*note;
[note setContentOffset:CGPointZero animated:YES];
这对我有用。
Swift版本(Xcode 9.3上带有iOS 11的Swift 4.1):
note.setContentOffset(.zero, animated: true)
答案 1 :(得分:66)
如果有任何人在iOS 8中遇到此问题,我发现只需设置UITextView's
文字属性,然后使用scrollRangeToVisible
NSRange
调用location:0
,{{1工作。我的文本视图不可编辑,我测试了可选择的和不可选择的(两个设置都没有影响结果)。这是一个Swift示例:
length:0
答案 2 :(得分:41)
这是我的解决方案......
override func viewDidLoad() {
textView.scrollEnabled = false
textView.text = "your text"
}
override func viewDidAppear(animated: Bool) {
textView.scrollEnabled = true
}
答案 3 :(得分:36)
致电
scrollRangeToVisible(NSMakeRange(0, 0))
可以使用,但可以在
中调用它override func viewDidAppear(animated: Bool)
答案 4 :(得分:29)
我在HTML中使用了attributionString,文本视图不可编辑。设置内容偏移对我来说也不起作用。这对我有用:禁用启用滚动,设置文本然后再次启用滚动
[yourTextView setScrollEnabled:NO];
yourTextView.text = yourtext;
[yourTextView setScrollEnabled:YES];
答案 5 :(得分:17)
我不确定我是否理解您的问题,但您是否只想将视图滚动到顶部?如果是这样你应该做
[textview scrollRectToVisible:CGRectMake(0,0,1,1) animated:YES];
答案 6 :(得分:17)
由于这些解决方案都不适合我,而且浪费了太多时间拼凑解决方案,这最终为我解决了这个问题。
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)
})
}
这真的很愚蠢,这不是此控件的默认行为。
我希望这可以帮助其他人。
答案 7 :(得分:11)
对于iOS 10和Swift 3,我做了:
override func viewDidLoad() {
super.viewDidLoad()
textview.isScrollEnabled = false
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
textView.isScrollEnabled = true
}
为我工作,不确定你是否遇到了最新版Swift和iOS的问题。
答案 8 :(得分:10)
我有一个更新的答案,它会使textview正确显示,并且没有用户体验滚动动画。
override func viewWillAppear(animated: Bool) {
dispatch_async(dispatch_get_main_queue(), {
self.introductionText.scrollRangeToVisible(NSMakeRange(0, 0))
})
答案 9 :(得分:8)
这就是iOS 9 Release的工作原理 因此,在出现在屏幕上之前,textView会滚动到顶部
- (void)viewDidLoad
{
[super viewDidLoad];
textView.scrollEnabled = NO;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
textView.scrollEnabled = YES;
}
答案 10 :(得分:7)
我是怎么做到的
斯威夫特4:extension UITextView {
override open func draw(_ rect: CGRect)
{
super.draw(rect)
setContentOffset(CGPoint.zero, animated: false)
}
}
答案 11 :(得分:5)
[txtView setContentOffset:CGPointMake(0.0, 0.0) animated:YES];
这行代码适合我。
答案 12 :(得分:5)
我的问题是在视图出现时将textView设置为滚动到顶部。适用于iOS 10.3.2和Swift 3。
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)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// It works.
self.textView.contentOffset = CGPoint.zero
}
答案 13 :(得分:5)
尝试此操作将光标移动到文本的顶部。
NSRange r = {0,0};
[yourTextView setSelectedRange:r];
看看情况如何。确保在所有事件都被触发后或者你正在做的事情完成之后调用它。
答案 14 :(得分:4)
结合以前的答案,现在它应该有效:
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 :(得分:4)
Swift 2答案:
textView.scrollEnabled = false
/* Set the content of your textView here */
textView.scrollEnabled = true
这可以防止textView在设置后滚动到文本末尾。
答案 16 :(得分:4)
在Swift 3中:
viewWillLayoutSubviews 是进行更改的地方。 viewWillAppear 也可以正常运行,但从逻辑上讲,布局应该在 viewWillLayoutSubviews 中执行。
关于方法, scrollRangeToVisible 和 setContentOffset 都可以使用。但是, setContentOffset 允许关闭或打开动画。
假设 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)
}
答案 17 :(得分:3)
这对我有用。它基于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)];
}
答案 18 :(得分:3)
这对我有用
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
DispatchQueue.main.async {
self.textView.scrollRangeToVisible(NSRange(location: 0, length: 0))
}
}
答案 19 :(得分:3)
-(void) viewDidAppear:(BOOL)animated{
[mytextView scrollRangeToVisible:NSMakeRange(0,0)];}
- (void)viewWillAppear:(BOOL)animated{
[mytextView scrollRangeToVisible:NSMakeRange(0,0)];}
ViewWillappear
会在用户注意到之前立即执行此操作,但ViewDidDisappear
部分会懒惰地为其设置动画。 [mytextView setContentOffset:CGPointZero animated:YES];
有时不起作用(我不知道为什么),所以请使用scrollrangetovisible。答案 20 :(得分:3)
问题解决了: iOS = 10.2 斯威夫特3 的UITextView
我刚使用了以下一行:
displayText.contentOffset.y = 0
答案 21 :(得分:2)
只是你可以使用这段代码
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
textView.scrollRangeToVisible(NSMakeRange(0, 0))
}
答案 22 :(得分:2)
我遇到了问题,但在我看来,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
}
答案 23 :(得分:2)
-(void)viewWillLayoutSubviews{
[super viewWillLayoutSubviews];
[textview setContentOffset:CGPointZero animated:NO];
}
答案 24 :(得分:2)
[self.textView scrollRectToVisible:CGRectMake(0, 0, 320, self.textView.frame.size.height) animated:NO];
答案 25 :(得分:1)
此代码解决了这个问题,也有助于避免不必要的自动滚动到textView的末尾。只需使用方法setTextPreservingContentOffset:
,而不是直接将文本设置为textView。
@interface ViewController () {
__weak IBOutlet UITextView *textView;
CGPoint lastContentOffset;
NSTimer *autoscrollTimer;
BOOL revertAnyContentOffsetChanges;
}
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[textView addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew context:nil];
}
- (void)dealloc
{
[textView removeObserver:self forKeyPath:@"contentOffset"];
}
- (void)setTextPreservingContentOffset:(NSString *)text
{
lastContentOffset = textView.contentOffset;
[autoscrollTimer invalidate];
revertAnyContentOffsetChanges = YES;
textView.text = text;
autoscrollTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(enableScrolling:) userInfo:nil repeats:NO];
autoscrollTimer.tolerance = 1;
}
- (void)enableScrolling:(NSTimer *)timer
{
revertAnyContentOffsetChanges = NO;
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if (revertAnyContentOffsetChanges && [keyPath isEqualToString:@"contentOffset"] && [[change valueForKey:@"new"] CGPointValue].y != lastContentOffset.y) {
[textView setContentOffset:lastContentOffset animated:NO];
}
}
@end
答案 26 :(得分:1)
尝试使用这两行解决方案:
view.layoutIfNeeded()
textView.contentOffset = CGPointMake(textView.contentInset.left, textView.contentInset.top)
答案 27 :(得分:1)
我必须在 viewDidLayoutSubviews 内部调用以下内容(在viewDidLoad内部调用还为时过早):
myTextView.setContentOffset(.zero, animated: true)
答案 28 :(得分:1)
我认为有些人遇到此问题的原因是因为他们试图在此TextView
出现之前设置TextView
滚动位置。
当TextView
尚未出现时,无法滚动。
您需要等待TextView
首先出现,然后才在viewDidAppear
方法中设置其滚动位置,如下所示:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
textView.setContentOffset(CGPoint.zero, animated: false)
}
答案 29 :(得分:1)
之前的Swift 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)
}
}
这是工作代码的剪切和粘贴。将person_description替换为textview变量。
答案 30 :(得分:1)
这是我的代码。它工作正常。
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()
}
}
答案 31 :(得分:1)
对于我来说,在iOS 9中它停止为我工作的方法字符串与方法scrollRangeToVisible(1行是粗体字,其他行是普通字体)
所以我不得不使用:
textViewMain.attributedText = attributedString
textViewMain.scrollRangeToVisible(NSRange(location:0, length:0))
delay(0.0, closure: {
self.textViewMain.scrollRectToVisible(CGRectMake(0, 0, 10, 10), animated: false)
})
延迟是:
func delay(delay:Double, closure:()->Void) {
dispatch_after(
dispatch_time(
DISPATCH_TIME_NOW,
Int64(delay * Double(NSEC_PER_SEC))
),
dispatch_get_main_queue(), closure)
}
答案 32 :(得分:1)
对我而言,这段代码很好用:
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
要滚动到确切位置并将其显示在屏幕顶部,请使用以下代码:
var scrollToLocation = 50 //<needed position>
textView.contentOffset.y = textView.contentSize.height
textView.scrollRangeToVisible(NSRange.init(location: scrollToLocation, length: 1))
设置contentOffset.y滚动到文本末尾,然后scrollRangeToVisible向上滚动到scrollToLocation的值。因此,所需位置出现在scrollView的第一行。
答案 33 :(得分:0)
一旦我在重新启用滚动之前添加了一个短暂的延迟,ChallengerGuy的答案就完全解决了我的问题。在添加延迟之前,我的PageController页面都是固定的,除了第一页,它也可以在任何用户与页面交互后自行修复。添加延迟也修复了第一页的UITextView滚动位置。
override open func viewDidLoad() {
super.viewDidLoad()
textView.isScrollEnabled = false
textView.text = textToScroll
... other stuff
}
override open func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
Central().delay(0.5) {
self.textView.isScrollEnabled = true
}
}
(我的Central()文件中的延迟功能。)
func delay(_ delay: Double, closure:@escaping ()->()) {
DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
closure()
}
}
答案 34 :(得分:0)
对于Swift,我认为最干净的方法是继承UITextView并使用此小技巧
import UIKit
class MyTextView: UITextView {
override var text: String! {
willSet {
isScrollEnabled = false
} didSet {
isScrollEnabled = true
}
}
}
答案 35 :(得分:0)
textview的默认行为是滚动到底部,因为它使用户能够继续编辑。
将textview偏移设置为其插图的最高值将为我解决该问题。
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
self.myTextView.contentOffset.y = -self.myTextView.contentInset.top
}
注意:我的textView嵌入在导航控制器中。
答案 36 :(得分:-1)
Xcode 8.0的解决方案。斯威夫特2.3。 适用于界面构建,可以轻松修改以便以编程方式工作。
class MBTextView: UITextView
{
required init?(coder aDecoder: NSCoder)
{
super.init(coder: aDecoder)
setupView()
}
func setupView() {}
}
class MBStartFromTopTV: MBTextView
{
override func setupView()
{
// some custom code
}
override func drawRect(rect: CGRect)
{
super.drawRect(rect)
setContentOffset(CGPoint.zero, animated: false)
}
}