UITextViewを満たさないテキストがある場合、意図したとおりに動作して上部にスクロールします。画面に収まらないほど多くのテキストがある場合、UITextViewは上部ではなくテキストの中央にスクロールされます。
関連する可能性のある詳細を次に示します。
ViewDidLoadで、UITextViewの上部と下部にパディングを追加します。
self.mainTextView.textContainerInset = UIEdgeInsetsMake(90, 0, 70, 0);
UITextViewは自動レイアウトを使用して、画面の上下左右(IBで行われます)から20pxを固定し、さまざまな画面サイズと向きを可能にします。
ロードしたら、指でスクロールできます。
編集私は、自動レイアウト制約を削除してから幅を修正するだけで問題が解決するように見えましたが、その画面幅のみです。
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
のContentOffsetを設定する必要がある場合があります。
(もう1つの方法は、textViewとそのsuperViewの間に「-40」の定数を使用して「等しい」幅と「等しい」高さのレイアウト制約を作成することです。定数がゼロの場合のみ「等しい」 、そうでない場合は定数によって調整されます。ただし、この制約は両方のビューを制約するビューにしか追加できないため、IBでこれを行うことはできません。
私がこれをしなければならない場合、AutoLayoutのポイントは何ですか?私はAutoLayoutを詳細に研究しましたが、それは素晴らしい質問です。
view Controllerクラスに次の関数を追加します...
Swift
override func viewDidLayoutSubviews() {
self.mainTextView.setContentOffset(.zero, animated: false)
}
Swift 2.1
override func viewDidLayoutSubviews() {
self.mainTextView.setContentOffset(CGPointZero, animated: false)
}
目的C
- (void)viewDidLayoutSubviews {
[self.mainTextView setContentOffset:CGPointZero animated:NO];
}
スイフト
self.textView.scrollRangeToVisible(NSMakeRange(0, 0))
Objective-C
[self.textView scrollRangeToVisible:(NSMakeRange(0, 0))];
私は同じ問題を抱えていました!推奨される制約にリセットして、配置するだけ(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)
}
IOS9以降では、viewWillAppear:のtextviewもCGRect(0,0,1000,1000)に付属しています。これが機能するには、viewWillAppearで呼び出す必要があります。
[self.view setNeedsLayout];
[self.view layoutIfNeeded];
// * Your code here
その後、textviewには正しいCGRectデータが含まれ、必要なスクロール操作を実行できます。
ViewDidLayoutSubviewsおよびviewWillLayoutSubviewsにコードを配置する際の問題は、これらのメソッドが頻繁に呼び出されることです(デバイスの回転中、ビューのサイズ変更中など)。テキストビューから何かを読んでいて、デバイスを回転させると、表示しているコンテンツの一部が画面に表示されたままになることが期待されます。トップに戻るとは思わないでしょう。コンテンツを一番上にスクロールする代わりに、テキストビューのscrollEnabledプロパティをNO(false)に設定したままにして、viewDidAppearで再び有効にしてください。
制約を台無しにしたくない場合:
override func updateViewConstraints() {
super.updateViewConstraints()
}
override func viewDidLayoutSubviews() {
self.textLabel.setContentOffset(CGPointZero, animated: false)
}
私にとってこれは別の方法で動作します。上記のすべてを試しましたが、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)
}
これは興味深いバグです。私たちのプロジェクトでは、これはiPhone 5
-サイズの画面。 textview contentOffset
は、View Controllerのライフサイクルのある時点で変化するようです。 viewDidLoad
およびviewWillAppear
では、textviewのcontentOffset
は0,0
、およびviewDidAppear
によって変更されます。 viewWillLayoutSubviews
で発生していることがわかります。制約が正しく設定されているようです。
これにより、必要でない限り、スクロールメソッドを呼び出さないようになります。
if textView.contentOffset.y > 0 {
textView.contentOffset = CGPoint(x: 0, y: 0)
// Or use scrollRectToVisible, scrollRangeToVisible, etc.
}
スイフト
override func viewDidLoad() {
super.viewDidLoad()
textView.isScrollEnabled = false
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
textView.isScrollEnabled = true
}
A.View Controllerがミスを犯していないか、何か間違ったことをしていないため、B、誤ってスクロールされたテキストを持つView Controllerが複数ある場合、View Controllerのコードでこの問題を処理するのはひどいアイデアのようです表示すると、冗長なコードになります。解決策は、テキストビュークラスに存在するコードを記述することです。私のソリューションは、UITextViewのカスタムクラスを選択してこのクラスを使用するInterface Builderで動作します。
import Foundation
import UIKit
class TopTextView: UITextView {
var scrolled = false
override func layoutSubviews() {
super.layoutSubviews()
if scrolled { return }
setContentOffset(.zero, animated: false)
scrolled = true
}
}
これは私のために働いた。 ViewControllerの子としてUITextViewではなく、UITextViewをそのビューの子として持つ子ビューを持つView Controllerがあります。テキストビューが上部または下部のバーの下にある場合、これがどのように機能するかはわかりませんが、エッジインセットに触れないため、これは機能するはずです。