ios-加載時,UITextView不會滾動到頂部

當我的文本沒有填充UITextView時,它會按預期滾動到頂部。 當文本超出屏幕顯示的大小時,UITextView將滾動到文本的中間而不是頂部。

以下是一些可能相關的詳細信息:

在viewDidLoad中,在UITextView的頂部和底部提供一些填充:

self.mainTextView.textContainerInset = UIEdgeInsetsMake(90, 0, 70, 0);

UITextView使用自動布局將其從屏幕的頂部,底部和每一側(在IB中完成)錨定20px,以允許使用不同的屏幕尺寸和方向。

加載后,我仍然可以用手指滾動它。

編輯我發現刪除自動布局約束然后固定寬度似乎只能解決此問題,但僅適用于該屏幕寬度。

asked 2020-02-29T10:13:19Z
11個解決方案
116 votes

將以下函數添加到您的視圖控制器類中...

迅捷3

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

斯威夫特2.1

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

目標C

- (void)viewDidLayoutSubviews {
    [self.mainTextView setContentOffset:CGPointZero animated:NO];
}
answered 2020-02-29T10:14:26Z
18 votes

UITextView是UIScrollView的子類,因此可以使用其方法。 如果您只想確保將其滾動到頂部,那么無論在何處添加文本,請嘗試:

[self.mainTextView setContentOffset:CGPointZero animated:NO];

編輯:具有任何滾動視圖的自動版式很快就會變得怪異。 設置固定寬度即可解決,這并不奇怪。 如果在-viewDidLayoutSubviews中不起作用,那很奇怪。 手動設置布局約束可能會起作用。 首先在IB中創建約束:

@property (weak, nonatomic) IBOutlet NSLayoutConstraint *textViewWidthConstraint;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *textViewHeightConstraint;

然后在ViewController中

    -(void)updateViewConstraints {
            self.textViewWidthConstraint.constant = self.view.frame.size.width - 40.0f;
            self.textViewHeightConstraint.constant = self.view.frame.size.height - 40.0f;
            [super updateViewConstraints];
        }

-viewDidLayoutSubviews中可能仍然需要setContentOffset。

(另一種方法是為textView及其superView之間的“等于”寬度和“等于”高度創建布局約束,常數為“ -40”。如果常數為零,則僅等于“相等”。 ,否則它會根據常數進行調整。但是由于您只能將此約束添加到同時約束兩個視圖的視圖中,因此您無法在IB中執行此操作。)

您可能會問自己可以领救济金的游戏,如果我必須這樣做,AutoLayout有什么意義? 我已經深入研究了AutoLayout,這是一個很好的問題。

answered 2020-02-29T10:13:52Z
11 votes

迅速

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

目標C

[self.textView scrollRangeToVisible:(NSMakeRange(0, 0))];
answered 2020-02-29T10:14:50Z
9 votes

我有同樣的問題! 重置為建議的約束,然后放置(y偏移)

@IBOutlet weak var textContent: UITextView!
    override func viewDidLoad() {
        textContent.scrollsToTop = true
        var contentHeight = textContent.contentSize.height
        var offSet = textContent.contentOffset.x
        var contentOffset = contentHeight - offSet
        textContent.contentOffset = CGPointMake(0, -contentOffset)
    }
answered 2020-02-29T10:15:10Z
7 votes

對于iOS9及更高版本,即使在viewWillAppear:上,textview也隨CGRect(0,0,1000,1000)一起提供。 為了使其正常工作,您必須調用viewWillAppear:

[self.view setNeedsLayout];
[self.view layoutIfNeeded];
// * Your code here

之后,textview將具有正確的CGRect數據,您可以執行可能需要的任何滾動操作。

answered 2020-02-29T10:15:36Z
2 votes

將代碼放入viewDidLayoutSubviews和viewWillLayoutSubviews中的問題在于,這些方法被稱為很多(在設備旋轉,調整視圖大小等過程中)。 如果您正在從文本視圖中閱讀內容,并且旋轉設備,那么您希望正在查看的內容部分保留在屏幕上。 您不希望它滾動回到頂部。不要將內容滾動到頂部,而是嘗試將文本視圖的scrollEnabled屬性設置為NO(false),然后在viewDidAppear中將其重新打開。

answered 2020-02-29T10:16:00Z
1 votes

如果您不想惹麻煩:

override func updateViewConstraints() {
    super.updateViewConstraints()
}
override func viewDidLayoutSubviews() {
    self.textLabel.setContentOffset(CGPointZero, animated: false)
}
answered 2020-02-29T10:16:19Z
1 votes

這是一個有趣的錯誤。 在我們的項目中,這僅在屏幕尺寸為27688059450891970197056的設備上發生。 看來textview 27688059450891970197057在視圖控制器生命周期的某個時候發生了變化。 在viewDidLoad和276880594508919701970中,textview的contentOffset0,0,而到27688059450891970197062已更改。 您可以看到它發生在276880594508919701970。約束似乎設置正確。

這將確保除非需要,否則不會調用滾動方法:

if textView.contentOffset.y > 0 {
    textView.contentOffset = CGPoint(x: 0, y: 0)
   
answered 2020-02-29T10:16:45Z
1 votes

對我來說,這是以不同的方式起作用的,我嘗試了上面提到的所有方法,但func viewWillAppear(_ animated: Bool)中沒有任何操作。最終使textView向上滾動,并在func viewDidAppear(_ animated: Bool)中,它在屏幕出現后滾動。

下面為我工作,但在鍵盤上下時遇到了一些與約束有關的問題。

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

下面按預期工作:

override func viewDidLoad() {
    super.viewDidLoad()
    self.textView.scrollsToTop = true
}
override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    self.view.layoutIfNeeded()
    self.textView.setContentOffset(.zero, animated: false)
}
answered 2020-02-29T10:17:14Z
0 votes

迅速

override func viewDidLoad() {
    super.viewDidLoad()  
    textView.isScrollEnabled = false  
}
override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    textView.isScrollEnabled = true
}
answered 2020-02-29T10:17:33Z
0 votes

在視圖控制器中的代碼中處理此問題似乎是一個糟糕的主意,因為:A.視圖控制器沒有犯任何錯誤或做任何錯誤,以及B,如果您有多個視圖控制器并帶有錯誤滾動的文本 視圖,您最終得到了冗余代碼。 解決方案應該是編寫存在于文本視圖類中的代碼。 我的解決方案與Interface Builder配合使用,在其中我只需為UITextView選擇一個自定義類并使用該類:

import Foundation
import UIKit
class TopTextView: UITextView {
    var scrolled = false
    override func layoutSubviews() {
        super.layoutSubviews()
        if scrolled { return }
        setContentOffset(.zero, animated: false)
        scrolled = true
    }
}

這對我有用。 我碰巧有一個視圖控制器,其子視圖帶有UITextView作為該視圖的子視圖,而不是UITextView作為該視圖控制器的子視圖。 我不知道如果文本視圖位于頂部或底部條形之下,效果如何,但是由于沒有邊緣邊緣被觸摸,因此這應該可行。

answered 2020-02-29T10:17:59Z
translate from