web-dev-qa-db-ja.com

UITextViewはテキストの下部または中央から始まります

私はすぐにそれを取得します。 UItextViewをビューに配置し、スクロールしてすべてのテキストを表示する必要がある場合(textViewに多くのテキストが存在する場合)、textViewはテキストの途中から開始し、テキストを他の時間。

enter image description here

TextViewでは編集は有効になっていません。毎回、textViewを強制的に先頭から開始する方法が必要です。他の人がコンテンツオフセットを使用している場合、このような質問を見ましたが、それがどのように機能するのか、またはここで適用できるのかさえわかりません。

ご協力いただきありがとうございます。

73
Alex Wulff

それは私のためにトリックをしました!

目標C:

[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
}
166
David Cruz

上記のすべての答えは私にとってうまくいきませんでした。ただし、秘密は、次のようにviewDidLayoutSubviewsのオーバーライド内でソリューションを実装することです。

override func viewDidLayoutSubviews() {
  super.viewDidLayoutSubviews()

  welcomeText.contentOffset = .zero
}

HTH :)

52
zeeple

In Swift 2

これを使用して、textViewを先頭から開始できます。

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    myTextView.setContentOffset(CGPointZero, animated: false)
}

Swift 2でXcode 7.2での動作を確認

14
Nick89

以下のコードを試してください-

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

または、StoryBoardでこのプロパティを設定することもできます-

ViewControllerを選択してから、属性インスペクターを選択します(チェックを外しますAdjust Scroll View Insets

13

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

UINavigationBarのtranslucentプロパティをNOに更新します。

self.navigationController.navigationBar.translucent = NO;

これにより、ビューがナビゲーションバーとステータスバーの下に表示されなくなります。

ナビゲーションバーを表示および非表示にする必要がある場合は、viewDidLoadで以下のコードを使用します

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

お役に立てれば。

6
Mrunal

多くのテストで、最初からUITextViewが表示されることを確認するために、viewWillLayoutSubviews()関数に以下を追加する必要があります。

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

Xcode 7.2 7c68; IOS 9.1

ViewControllerを含むUITextViewは複雑で、プロジェクト中に大きく変更されました(IDEバージョンも2〜3回変更されました)。

上記のすべての解決策を試しましたが、同じ問題が発生した場合は、[〜#〜] patient [〜#〜]にしてください。

解決すべき3つの「秘密コード」があります。

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

また、これらのコードを配置できる場所は2つあります。

  1. viewDidLoad()
  2. viewDidLayoutSubviews()

それらを組み合わせると、3 * 2 = 6のソリューションが得られます。正しい組み合わせは、ViewControllerがどれだけ複雑かによって異なります(信じてください。textViewの上のビューだけを削除した後、新しい組み合わせ)。

そして、私はそれを見つけました:

viewDidLayoutSubviews()に「シークレットコード」を配置し、viewDidLoad()に_textView.text = someStrings_を配置すると、textViewのコンテンツが時々「揺れ」ます。したがって、それらを同じ場所に置きます。

最後の言葉:[〜#〜] all [〜#〜]の組み合わせを試してください。これが、この愚かなバグを2か月間に3回以上解決する方法です。

4
outcast

この1行のコードをViewDidLoadに配置します

self.automaticallyAdjustsScrollViewInsets = false
4
Murat Yasar

UITextViewスクロールは多くの人にとって問題のようです。ここの答え(特に this )とApple開発者ドキュメント、私自身のウィットのいくつかを使用して、ここに私のために働く解決策があります。ニーズに合わせてコードを変更します。

私の使用例は次のとおりです。同じUITextViewがさまざまな目的に使用され、さまざまな状況でさまざまなコンテンツを表示します。私が欲しいのは、コンテンツが変更されると、古いスクロール位置が復元されるか、最後までスクロールされることです。これが完了したら、あまりアニメーションを望んでいません。特に、すべてのテキストが新しいようにビューをアニメートしたくありません。このソリューションでは、最初にアニメーションなしで古いスクロール位置を復元し、必要に応じてアニメーションの最後までスクロールします。

あなたがする必要がある(またはcanと言う必要があります)は、次のように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プログラミングに慣れていないので、なぜそれがうまく機能するのかわかりません。誰かがこれについて何らかの情報を持っているなら、知っておくといいでしょう。また、このアプローチは完璧ではないかもしれないので、改善のアイデアも受け入れています。

そしてもちろん、上記のリンクの後ろに答えを投稿してくれた NixonsBack に感謝します。

私の最初の投稿:)、乾杯!

4
ipe

次のコードは、あなたが望む効果を与えるはずです。

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

「self.scrollView」をスクロールビューの名前に置き換える必要があります。スクロールビューのテキストを設定した後、このコードを配置する必要があります。

3
Gary Riches

これは私のために働いた:

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

}
2
bpolat

これはXcode 8.3.3でうまくいきました。

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

ViewController.SwiftファイルにUITextViewのアウトレットを作成します。 ViewDidLoadセクションに次を入力します。

迅速:

self.textView.contentOffset.y = 0

私が試してみました:

self.textView.scrollRangeToVisible(NSMakeRange(0, 0))
2
J.Bury

Zeepleの回答をMonoTouch/Xamarin(C#)に翻訳しました。

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

ビューを希望どおりに機能させるには、ここに2つの答えを実装する必要がありました。

Juan David Cruz Serranoから:

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

Murat Yasarから:

automaticallyAdjustsScrollViewInsets = false

これにより、一番上にスクロールがロードされ、スクロールが開始されるとインセットが変更されないUITextViewが提供されました。これがデフォルトの動作ではないことは非常に奇妙です。

0
Leon

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)
0
Amirca

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];
}
0
ARGeo