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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27622437/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 04:06:21  来源:igfitidea点击:

UITextView starts at Bottom or Middle of the text

iosobjective-cswiftxcodecocoa-touch

提问by Alex Wulff

I'll get right to it. I have a UItextViewplaced in my view that when needs to scroll to see all the text (when a lot of text is present in the textView) the textView starts in the middle of the text sometimes and the bottom of the text other times.

我会马上解决的。我有一个UItextView放置在我的视图中,当需要滚动以查看所有文本时(当 textView 中存在大量文本时),textView 有时从文本中间开始,有时从文本底部开始。

enter image description here

在此处输入图片说明

Editing is not enabled on the textView. I need a way to force the textView to start at the top, every time. I saw some questions somewhat like this where other people used a content offset, but I do not really know how that works or if it would even be applicable here.

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

Thanks for your help.

谢谢你的帮助。

回答by David Cruz

That did the trick for me!

这对我有用!

Objective C:

目标 C:

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

Swift:

迅速:

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

Swift 2 (Alternate Solution)

Swift 2(替代解决方案)

Add this override method to your ViewController

将此覆盖方法添加到您的 ViewController

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

Swift 3 & 4 (syntax edit)

Swift 3 & 4(语法编辑)

override func viewDidLayoutSubviews() {
  super.viewDidLayoutSubviews()

  textView.contentOffset = .zero
}

回答by zeeple

All of the answers above did not work for me. However, the secret turns out to be to implement your solution within an override of viewDidLayoutSubviews, as in:

以上所有答案都不适用于我。然而,秘诀是在 viewDidLayoutSubviews 的覆盖范围内实现您的解决方案,如下所示:

override func viewDidLayoutSubviews() {
  super.viewDidLayoutSubviews()

  welcomeText.contentOffset = .zero
}

HTH :)

哈 :)

回答by Nick89

In Swift 2

在斯威夫特 2

You can use this to make the textView start from the top:

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

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    myTextView.setContentOffset(CGPointZero, animated: false)
}

Confirmed working in Xcode 7.2 with Swift 2

确认在 Xcode 7.2 和 Swift 2 中工作

回答by keshav vishwkarma

Try this below code -

试试下面的代码 -

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

Or you can also set this property by StoryBoard -

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

Select ViewController then select attributes inspector now unchecked Adjust Scroll View Insets.

选择 ViewController 然后选择 attributes inspector now unchecked Adjust Scroll View Insets

回答by CodeOverRide

For Swift >2.2, I had issues with iOS 8 and iOS 9 using above methods as there are no single answer that works so here is what I did to make it work for both.

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

回答by Mrunal

Update your UINavigationBar's translucentproperty to NO:

将 UINavigationBar 的translucent属性更新为NO

self.navigationController.navigationBar.translucent = NO;

This will fix the view from being framed underneath the navigation bar and status bar.

这将修复视图被框在导航栏和状态栏下方。

If you have to show and hide the navigation bar, then use below code in your viewDidLoad

如果您必须显示和隐藏导航栏,请在您的 viewDidLoad

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

Hope this helps.

希望这可以帮助。

回答by outcast

Xcode 7.2 7c68; IOS 9.1

Xcode 7.2 7c68;IOS 9.1

My ViewControllerwhich contains UITextViewis complicated, and changed a lot during the project (IDE version changed maybe 2~3 times too).

ViewController里面的内容UITextView比较复杂,在项目中改动很大(IDE版本也改动了2~3次)。

I've tried all above solutions, if you encounter the same issue, be PATIENT.

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

There are three possible 'secret codes' to solve:

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

  1. textView.scrollEnabled = false //then set text textView.scrollEnabled = true
  2. textView.scrollRangeToVisible(NSMakeRange(0, 0))
  3. textView.setContentOffset(CGPointZero, animated: false)
  1. textView.scrollEnabled = false //then set text textView.scrollEnabled = true
  2. textView.scrollRangeToVisible(NSMakeRange(0, 0))
  3. textView.setContentOffset(CGPointZero, animated: false)

And there are two places you can put those codes in:

您可以在两个地方放置这些代码:

  1. viewDidLoad()
  2. viewDidLayoutSubviews()
  1. viewDidLoad()
  2. viewDidLayoutSubviews()

Combine them, you'll get 3*2=6 solutions, the correct combination depends on how complicated you ViewControlleris (Believe me, after delete just a view above textView, I need to find a new combination).

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

And I found that:

我发现:

When put 'secret codes' in viewDidLayoutSubviews(), but textView.text = someStringsin viewDidLoad(), the content in textViewwill 'shake' sometimes. So, put them in the same place.

将“密码”放入viewDidLayoutSubviews(),但textView.text = someStrings放入 时viewDidLoad(),内容textView有时会“抖动”。所以,把它们放在同一个地方。

Last word: try ALLcombinations, this is how I solve this stupid bug more than three times during two months.

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

回答by Kevin

With a lot of testing, i found must add below in viewWillLayoutSubviews() function to make sure the UITextView show up from the very beginning:

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

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

回答by ipe

UITextViewscrolling seems to be a problem to a lot of people. Gathering from the answers here around (especially this) and the Apple Developer documentation, using some of my own wit, here is a solution that works for me. You can modify the code to suit your needs.

UITextView滚动似乎是很多人的问题。使用我自己的一些智慧,从这里的答案(尤其是这个)和 Apple Developer 文档中收集到的,这是一个对我有用的解决方案。您可以修改代码以满足您的需要。

My use case is as follows: the same UITextViewis used for different purposes, displaying varying content in different circumstances. What I want is that when the content changes, the old scroll position is restored, or at times, scrolled to the end. I don't want too much animation when this is done. Especially I don't want the view to animate like all the text was new. This solution first restores the old scroll position without animation, then scrolls to the end animated, if so desired.

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

What you need to do (or should I say cando) is extend UITextView as follows:

你需要做的(或者我应该说可以做)是扩展 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))
        })
      }
    })
  }
}

What this does is it updates the text, then uses a stored value of the UITextView.contentOffsetproperty (or anything you pass as a parameter), and sets the offset of the view accordingly. If desired, after this, it scrolls to the end of the new, potentially changed content.

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

I'm new to iOS programming and I don't know why it works so well it does, if someone has some information on this it would be nice to know. Also the approach may not be perfect so I'm open to improvement ideas as well.

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

And of course thanks to NixonsBackfor posting the answer behind the link above.

当然,感谢NixonsBack在上面的链接后面发布了答案。

My first post :), cheers!

我的第一篇文章:),干杯!

回答by Murat Yasar

Put this one line of code in ViewDidLoad

将这一行代码放在ViewDidLoad 中

self.automaticallyAdjustsScrollViewInsets = false