UITextView 从文本的底部或中间开始

我就直说了。我在视图中放置了一个 UItextView,当需要滚动查看所有文本时(当 textView 中存在大量文本时) ,textView 有时开始于文本的中间,有时开始于文本的底部。

enter image description here

在 textView 上未启用编辑。我需要一种方法来强制 textView 从顶部开始,每次。我看到一些类似这样的问题,其他人使用了内容偏移,但我不知道这是如何工作的,或者它是否适用于这里。

谢谢你的帮助。

37078 次浏览

下面的代码应该会给您想要的效果。

[self.scrollView setContentOffset:CGPointMake(0, -self.scrollView.contentInset.top) animated:YES];

您需要将“ self. scrollView”替换为滚动视图的名称。您应该在设置了滚动视图的文本之后放入这段代码。

将 UINavigationBar 的 translucent属性更新为 NO:

self.navigationController.navigationBar.translucent = NO;

这将修复位于导航栏和状态栏下面的视图。

如果必须显示和隐藏导航栏,那么在 viewDidLoad中使用以下代码

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

希望这个能帮上忙。

这招真管用!

目标丙:

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

斯威夫特:

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

Swift 2(替代解决方案)

将此覆盖方法添加到 ViewController

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

Swift 3 & 4(语法编辑)

override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()


textView.contentOffset = .zero
}

试试下面的代码-

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

或者您也可以通过 StoryBoard-设置此属性

选择 ViewController,然后选择现在未选中 Adjust Scroll View Insets的属性检查器。

对很多人来说,UITextView滚动似乎是个问题。从这里收集的答案(特别是 这个)和 Apple Developer 文档,用我自己的一些智慧,这里有一个适合我的解决方案。您可以根据需要修改代码。

我的用例如下: 相同的 UITextView用于不同的目的,在不同的情况下显示不同的内容。我想要的是,当内容发生变化时,旧的滚动位置被恢复,或者有时,滚动到最后。我不想要太多的动画,当这完成。尤其是我不希望视图像动画一样,所有的文字是新的。这个解决方案首先恢复旧的滚动位置没有动画,然后滚动到结束动画,如果需要的话。

你需要做的(或者我应该说 可以做的)是扩展 UITextView 如下:

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))
})
}
})
}
}

这样做的目的是更新文本,然后使用 UITextView.contentOffset属性的存储值(或作为参数传递的任何内容) ,并相应地设置视图的偏移量。如果需要,在此之后,它将滚动到新的、可能已更改的内容的末尾。

我是 iOS 编程的新手,我不知道为什么它能这么好用,如果有人有这方面的信息,我会很高兴知道。而且这种方法可能并不完美,所以我也愿意接受改进的想法。

当然,还要感谢 尼克松回来了在上面的链接后面提供了答案。

我的第一个帖子:) ,干杯!

经过大量的测试,我发现必须在 viewWillLayoutSubviews ()函数中添加以下内容,以确保 UITextView 从一开始就显示出来:

override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
textViewTerms.scrollRangeToVisible(NSMakeRange(0, 0))
}

ViewController.swift文件中为您的 UITextView创建一个出口:

斯威夫特:

self.textView.contentOffset.y = 0

我试过了:

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

以上所有的答案对我来说都不起作用。然而,秘诀是在 viewDidLayoutSubviews 的覆盖内实现解决方案,如下所示:

override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()


welcomeText.contentOffset = .zero
}

)

这对我很有效:

 override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
textView.scrollRectToVisible(CGRect(origin: CGPointZero, size: CGSizeMake(1.0, 1.0)), animated: false)


}

Xcode 7.27c68; IOS 9.1

我的 ViewController包含 UITextView是复杂的,并且在项目中改变了很多(IDE 版本也可能改变了2 ~ 3次)。

我已经尝试了以上所有的解决方案,如果你遇到同样的问题,是 病人

有三种可能的“密码”需要解决:

  1. ScrollEnable = false //然后设置文本 ScrollEnable = true
  2. textView.scrollRangeToVisible(NSMakeRange(0, 0))
  3. textView.setContentOffset(CGPointZero, animated: false)

有两个地方可以输入密码:

  1. viewDidLoad()
  2. viewDidLayoutSubviews()

结合它们,你会得到3 * 2 = 6个解决方案,正确的组合取决于你的 ViewController是多么复杂(相信我,删除以上的 textView视图后,我需要找到一个新的组合)。

我发现:

当在 viewDidLayoutSubviews()中放入“密码”,而在 viewDidLoad()中放入 textView.text = someStrings时,textView中的内容有时会“震动”。那就把它们放在同一个地方。

最后一句话: 尝试 全部组合,这是我如何解决这个愚蠢的错误超过三次,在两个月内。

在 Swift 2里

你可以使用这个来使 textView 从顶部开始:

override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()


myTextView.setContentOffset(CGPointZero, animated: false)
}

确认使用 Xcode 7.2和 Swift 2

对于 Swift > 2.2,我在使用上述方法时遇到了 iOS 8和 iOS 9的问题,因为没有单一的解决方案,所以这里我做了什么来使它们都能工作。

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


if #available(iOS 9.0, *) {
textView.scrollEnabled = false
}


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


override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)


if #available(iOS 9.0, *) {
textView.scrollEnabled = true
}
}

把这一行代码放入 ViewDidLoad

self.automaticallyAdjustsScrollViewInsets = false

我翻译了 Zeeple 对 MonoTouch/Xamarin (C #)的回答。

public override void ViewDidLayoutSubviews()
{
base.ViewDidLayoutSubviews();
myForm.SetContentOffset(new CoreGraphics.CGPoint(0,0), animated: false);
}

在我的例子中,我在自定义表格视图单元格中加载 textView。下面是我所做的,以确保文本视图中的文本加载在我的文本视图中的文本在我的自定义单元格的顶部。

在故事板中,通过取消选中按钮来设置 textview ScrollEnable = false。

2)在视图加载之后,在 textview 上将 isScrollEnable 设置为 true。我设置了一个小小的延迟,如下:

override func awakeFromNib() {
super.awakeFromNib()


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


}

无论如何,如果您处于我的情况,请尝试将 scrollEnable 设置为 false,然后当视图加载时,将 scrollEnable 设置为 true。

我必须在这里实现两个答案,才能让我的观点按照我的意愿运行:

来自 Juan David Cruz Serrano:

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

来自 Murat Yasar:

automaticallyAdjustsScrollViewInsets = false

这样就产生了一个 UITextView,它在最顶部加载滚动条,一旦开始滚动条就不会改变插入。很奇怪,这不是默认行为。

这个方法在 Xcode 8.3中对我很有用。3:

-(void)viewWillLayoutSubviews
{
[super viewWillLayoutSubviews];
[self.txtQuestion scrollRangeToVisible:NSMakeRange(0, 0)];
}

要强制 textView每次都从顶部开始,请使用以下代码:

Swift 4.2 :

override func viewDidLayoutSubviews() {
textView.setContentOffset(CGPoint(x: 0, y: 0), animated: false)
}

Objective-C :

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

Swift 4.2 & Swift 5

设置文本之前和之后的内容偏移量。(在主线程上)

let animation = false //or whatever you want
self.mainTextView.setContentOffset(.zero, animated: animation)
self.mainTextView.attributedText = YOUR_ATTRIBUTED_TEXT
self.mainTextView.setContentOffset(.zero, animated: animation)