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

问题描述 投票:72回答:18

我会正确的。我有一个UItextView放在我的视图中,当需要滚动查看所有文本时(当textView中存在大量文本时)textView有时会在文本的中间开始,而文本的底部则会在其他时间开始。

enter image description here

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

谢谢你的帮助。

ios objective-c swift xcode cocoa-touch
18个回答
163
投票

这对我有用!

Objective C:

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

Swift:

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

Swift 2 (Alternate Solution)

将此覆盖方法添加到ViewController

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

Swift 3 & 4 (syntax edit)

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

4
投票

将这一行代码放在ViewDidLoad中

viewDidLoad()

3
投票

以下代码应该为您提供所需的效果。

textView

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


2
投票

这对我有用:

self.automaticallyAdjustsScrollViewInsets = false

2
投票

Xcode 8.3.3对我有用:

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

2
投票

override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() textView.scrollRectToVisible(CGRect(origin: CGPointZero, size: CGSizeMake(1.0, 1.0)), animated: false) } 文件中为-(void)viewWillLayoutSubviews { [super viewWillLayoutSubviews]; [self.txtQuestion scrollRangeToVisible:NSMakeRange(0, 0)]; } 创建一个插座。在UITextView部分中提出以下内容:

迅速:

ViewController.swift

我试过了:

ViewDidLoad

1
投票

我将zeeple的答案翻译成了MonoTouch / Xamarin(C#)。

self.textView.contentOffset.y = 0

0
投票

我必须在这里实现两个答案,以便按我的意愿运行我的视图:

来自Juan David Cruz Serrano:

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

来自Murat Yasar:

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

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


0
投票

要强制override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() textView.setContentOffset(CGPoint.zero, animated: false) } 每次都从顶部开始,请使用以下代码:

automaticallyAdjustsScrollViewInsets = false

textView

Swift 4.2

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

-1
投票

在我的情况下,我在自定义tableview单元格中加载textView。下面是我所做的,以确保textview中的文本加载到我的自定义单元格的textview文本的顶部。

1.)在storyboard中,通过取消选中按钮设置textview ScrollEnabled = false。

2.)在视图加载后,在textview上将isScrollEnabled设置为true。我设置了一个小延迟,如下所示:

Objective-C

无论如何,如果您处于我的状态,请尝试将scrollEnabled设置为false,然后在加载视图时,将scrollEnabled设置为true。


51
投票

上面的所有答案对我都不起作用。但是,秘密最终是在viewDidLayoutSubviews的覆盖范围内实现您的解决方案,如:

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

HTH :)


14
投票

在Swift 2中

您可以使用它来使textView从顶部开始:

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    myTextView.setContentOffset(CGPointZero, animated: false)
}

确认使用Swift 2在Xcode 7.2中工作


13
投票

试试以下代码 -

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

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

选择ViewController,然后选择属性检查器,现在取消选中Adjust Scroll View Insets


7
投票

对于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
    }
}

6
投票

将您的导航栏qazxsw poi属性更新为qazxsw poi:

translucent

这将修复视图在导航栏和状态栏下面的框架。

如果您必须显示和隐藏导航栏,请在NO中使用以下代码

self.navigationController.navigationBar.translucent = NO;

希望这可以帮助。


5
投票

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

viewDidLoad

4
投票

if ([self respondsToSelector:@selector(edgesForExtendedLayout)]) self.edgesForExtendedLayout = UIRectEdgeNone; // iOS 7 specific 滚动似乎是很多人的问题。从这里的答案(特别是override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() textViewTerms.scrollRangeToVisible(NSMakeRange(0, 0)) } )和Apple Developer文档中收集,使用我自己的智慧,这里有一个适合我的解决方案。您可以修改代码以满足您的需求。

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

您需要做什么(或者我应该说可以做)是扩展UITextView,如下所示:

this

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

我是iOS编程的新手,我不知道它为什么会如此有效,如果有人掌握了一些相关信息,那就太好了。这种方法也可能不完美,所以我也愿意接受改进的想法。

当然感谢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)) }) } }) } } 在上面的链接背后发布答案。

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


4
投票

Xcode 7.2 7c68; IOS 9.1

我的包含UITextView.contentOffsetNixonsBack很复杂,并且在项目期间发生了很大的变化(IDE版本也改变了2~3次)。

我已经尝试了以上所有解决方案,如果遇到同样的问题,请耐心等待。

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

  1. ViewController
  2. UITextView
  3. textView.scrollEnabled = false //then set text textView.scrollEnabled = true

您可以将这些代码放入以下两个位置:

  1. textView.scrollRangeToVisible(NSMakeRange(0, 0))
  2. textView.setContentOffset(CGPointZero, animated: false)

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

我发现:

当把'密码'放在ViewController中,但textView放在viewDidLayoutSubviews()时,textView.text = someStrings中的内容有时会“震动”。所以,把它们放在同一个地方。

最后一句话:尝试所有组合,这就是我在两个月内解决这个愚蠢错误超过三次的方法。

© www.soinside.com 2019 - 2024. All rights reserved.