UITextView文本内容不是从顶部开始


79

我有一个来自JSON文件的长文本,但是当我单击UITableViewCell中的链接转到我的UIViewController页面时,UITextView文本会加载字符串内容,但不会从头开始显示内容,因此我必须向上滚动所有内容时间。

我需要做什么?


您是否尝试将contentOffset设置为(0,0)?
rdelmar

您可以编辑此问题。在标签下方,您会看到“编辑”。单击该按钮进行编辑。我有一个编辑建议,但觉得用户应该编辑问题。
LanternMike 2014年

请查看此页面,查看其中一种解决方案是否适合您。这里的大多数内容都在这里,还有更多stackoverflow.com/questions/1234242/…如果您对正在发生的事情,工作,而不是尝试的问题有疑问,请提供具体的信息。
LanternMike 2014年

这是我的问题的链接:链接
Ornilo 2014年

只为我工作溶液由这一个从另一个职位
安德烈·巴斯

Answers:


160

我遇到了同样的问题,结果我不得不在viewDidLayoutSubviews中设置内容偏移才能生效。我正在使用此代码显示归因于静态的文本。

- (void)viewDidLayoutSubviews {
    [self.yourTextView setContentOffset:CGPointZero animated:NO];
}

SWIFT 3:

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    self.textView.setContentOffset(CGPoint.zero, animated: false)
}

4
在所有答案中,这一方法效果最好。此外,如果您的UITextView文本从文本视图的垂直中间位置开始,则在viewDidLoad中添加以下内容也可以解决该问题:self.automaticallyAdjustsScrollViewInsets = false
Wizkid

有趣的是,offuttjillian的解决方案确实对我有用,但是您提供的解决方案@Wizkid和Glenn在iOS 9.1上对我来说更糟了。无论如何,它现在正在工作,这让我感到高兴^^
Frozn 2015年

2
尽管不幸的是,这是一个行之有效的解决方案,但是即使您使用的是向上丑陋的可见滚动,也有很大的副作用viewWillLayoutSubviews:/
Hofi

尝试了将近6种方法来解决该问题,此答案仅在iOS9.x中对我有用。
KoreanXcodeWorker's

即使在为UITextView分配文本后进行设置,效果也很好
Hassy

46

这是对我有用的唯一方法。在加载视图之前,我禁用了UITextView的滚动,然后再次启用它:

  override func viewWillAppear(_ animated: Bool) {
        yourTextView.isScrollEnabled = false
    }

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

2
最佳的解决方案,以最大程度地减少向上滚动时出现的可见视觉效果
Hofi

为我工作得很好
蒂博·诺亚

利用该解决方案在iPad上滚动时,我遇到了一些混乱的问题。
外星人


19

通过以编程方式在加载内容之前禁用textview的滚动属性 textview.scrollenabled = NO;

并在加载后启用textview滚动 textview.scrollenabled = YES;

还要检查XIB,始终不选中Textview的滚动启用。


非常感谢,但是,如果我们有这样的UITextView中的CollectionView或tableview中它不会工作
穆萨愤怒的

12

问题的答案iOS 10中UITextView顶部的空白提供了更加干净的最终用户体验。

viewDidLoad包含文本视图的视图控制器中:

 self.automaticallyAdjustsScrollViewInsets = false

设置textView.setContentOffset(CGPointMake(0,0), animated: false)和其中的一些其他建议在被调用时都起作用,viewDidLayoutSubviews()但是在较旧的设备(如iPad 2和更旧的设备)上,显示屏幕时实际上会看到文本滚动。那不是您希望最终用户看到的东西。


4

使用这些解决方案后,我仍然遇到问题。这个问题似乎与透明的导航栏和选择自动调整视图控制器上的内容插图有关。如果您不关心文本在导航栏下方的滚动,则最好保留这些设置,并将文本视图的顶部限制在导航栏的底部,而不是视图控制器的顶部。

如果像我一样,您希望它在向下滚动时显示在导航栏的下面;那么对我有用的解决方案是添加它。

- (void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];

    CGFloat offset = self.navigationController.navigationBar.frame.size.height+[UIApplication sharedApplication].statusBarFrame.size.height;

    [self.textView setContentOffset:CGPointMake(0, -offset) animated:NO];
}

这只是寻找导航栏和状态栏的高度,并相应地调整内容偏移量。

请注意,这种方法的缺点是,当设备旋转时,您最终将滚动回到顶部。


谢谢-这最终使我想到了正确的主意:)
HannahCarney 2015年

4

对我来说,这段代码不错:

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

    //this part of code scrolls to top
    textView.contentOffset.y = -64 //or = 0 if no Navigation Bar
    textView.scrollEnabled = false
    textView.layoutIfNeeded()
    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的第一行中。


4

与其他一些答案类似,但是具有更多的好处,您不会在随后的设备旋转时导致滚动到顶部。在Swift 2.2中运作良好

/// Whether view has laid out subviews at least once before.
var viewDidLayoutSubviewsAtLeastOnce = false

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    if !viewDidLayoutSubviewsAtLeastOnce {
        textView.setContentOffset(CGPoint(x: 0, y: -textView.contentInset.top), animated: false)
    }

    viewDidLayoutSubviewsAtLeastOnce = true
}

在尝试了几种不同的答案后,这个对我来说效果最好。根据Swindler的回答,您可以将CGPointZero用于CGPoint。
米奇·唐尼

在此方法中执行此操作很重要-viewDidLayoutSubviews。许多答案会让您在viewWillAppear中执行此操作,但这是错误的。viewDidLayoutSubviews是执行此操作的地方。谢谢。
geekyaleks

3

迅捷版

需要结合以下各项:

1.)设置出口

  @IBOutlet var textView: UITextView!

2.)在View Controller的情节提要中,关闭“调整滚动视图插图”

3.)通过在视图控制器中添加以下内容,将内容设置为零顶部

override func viewWillLayoutSubviews() {
   super.viewWillLayoutSubviews()
     myUITextView.setContentOffset(CGPointZero, animated: false)
}

“CGPointZero”不可用斯威夫特
阿里

3

而不是设置内容偏离的viewDidLayoutSubviews你可以写layoutIfNeededviewDidLoad中设置下面的TextView的正确位置:

    self.textView.layoutIfNeeded()
    self.textView.setContentOffset(CGPoint.zero, animated: false)

干杯!


2

在Swift 2,Xcode 7解决方案中,要使滚动保持启用状态并使文本从顶部开始,这就是您所需要的:

@IBOutlet weak var myUITextView: UITextView!

override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()
    //start scroll at top of text
    myUITextView.scrollRangeToVisible(NSMakeRange(0, 0))
}

1
谢谢!对于Swift 2.2来说,这对我来说是完美的。这里没有其他解决方案像平滑和简单的那样工作。
Natalia

2

斯威夫特3.0

override func viewWillAppear(_ animated: Bool) {
    privacyText.isScrollEnabled = false
}

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

禁用在Storyboard中滚动!并在代码中启用。重写FUNC viewDidAppear(_动画:BOOL){privacyText.isScrollEnabled =真}
维塔利甲

2

这对我来说效果最好!我把它放在viewDidLoad()中。

//TextView Scroll starts from the top
myTextView.contentOffset.y = 0

1
表达式不可分配。
Bhumesh Purohit

1

这是另一种对我始终有效的方法。目标C:

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    [self.textView setContentOffset:CGPointZero animated:NO];
}

在Swift中:

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

1

迅捷版:

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

1

将以下函数添加到您的视图控制器类中...

Swift 3

override func viewDidLayoutSubviews() {
    self.mainTextView.setContentOffset(.zero, animated: false)
}
Swift 2.1

override func viewDidLayoutSubviews() {
    self.mainTextView.setContentOffset(CGPointZero, animated: false)
}
Objective C

- (void)viewDidLayoutSubviews {
    [self.mainTextView setContentOffset:CGPointZero animated:NO];
}

或者你在ViewDidAppear里面加上滚动,这样用户会看到他往上滚动到第一行


你能把最后一句话翻译成英文吗?
Gilles Gouaillardet

1

在带有属性文本的swift 4中,任何答案都无济于事,我在主题中组合了一些答案。

override func viewWillAppear(_ animated: Bool) {
     super.viewWillAppear(animated)
     uiTextview.isScrollEnabled = false
}

override func viewDidAppear(_ animated: Bool) {
     uiTextview.isScrollEnabled = true
     uiTextview.setContentOffset(CGPoint.zero, animated: false)
}

uittextview是在集合视图还是表视图中怎么办
Amr Angry

@AmrAngry我不知道,我只是将其用于文本视图
hall.keskin

谢谢我使用tetxview.scrollRangeToVisible(NSMakeRange(0,0))
Amr生气

1

Swift 3、4、5解决方案:

解决问题的步骤:

  • 禁用UITextView滚动
  • 设置scrollRectToVisible
  • 启用UITextView滚动

码:

yourTextView.isScrollEnabled = false
let rect:CGRect = CGRect(x: 0, y: 0, width: 1, height: 1)
yourTextView.scrollRectToVisible(rect, animated: false)
yourTextView.isScrollEnabled = true

这为我工作。希望对您有所帮助!


感谢Mohit方便的解释。
Praveen Kumar Verma

0

这就是我做到的。我将textview分为子类,并且:

override func willMoveToSuperview(newSuperview: UIView?) {
    self.scrollEnabled = false
}

override func layoutSubviews() {
    super.layoutSubviews()
    self.scrollEnabled = true
}

0

在情节提要中,选择要放置文本视图的视图控制器。在属性检查器中,取消选中“调整滚动视图插图”。而已。


0

将此代码放在您的课​​程上

override func viewDidLayoutSubviews() {
        self.About_TV.setContentOffset(.zero, animated: false) // About_TV : your text view name)
    }

-2

将代码添加到viewdidload

self.automaticallyAdjustsScrollViewInsets = NO;
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.