wake-up-neo.net

UITextView beginnt am unteren oder mittleren Rand des Textes

Ich werde gleich dazu kommen. Ich habe eine UItextView in meiner Ansicht, die besagt, dass wenn Text gescrollt werden muss, um den gesamten Text anzuzeigen (wenn viel Text in der Textansicht vorhanden ist), die Textansicht manchmal in der Mitte des Textes und zu anderen Zeiten am unteren Rand des Textes beginnt. 

 enter image description here

Die Bearbeitung ist in der Textansicht nicht aktiviert. Ich brauche eine Möglichkeit, die Textansicht jedes Mal an der Spitze zu starten. Ich habe einige Fragen wie diese gesehen, bei denen andere Leute einen Content-Offset verwendet haben, aber ich weiß nicht wirklich, wie das funktioniert oder ob es hier überhaupt anwendbar wäre. 

Danke für Ihre Hilfe.

70
Alex Wulff

Das hat mir geholfen! 

Ziel c:

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

Schnell:

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

Swift 2 (alternative Lösung)

Fügen Sie diese Überschreibungsmethode Ihrem ViewController hinzu

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

Swift 3 & 4 (Syntax bearbeiten)

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

Alle obigen Antworten funktionierten nicht für mich. Es hat sich jedoch als Geheimnis herausgestellt, Ihre Lösung innerhalb einer Überschreibung von viewDidLayoutSubviews zu implementieren, wie in:

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

HTH :)

51
zeeple

In Swift 2

Sie können dies verwenden, um das textView von oben zu starten:

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    myTextView.setContentOffset(CGPointZero, animated: false)
}

Bestätigt das Arbeiten in Xcode 7.2 mit Swift 2

14
Nick89

Versuchen Sie diesen Code unten -

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

Oder Sie können diese Eigenschaft auch über StoryBoard festlegen.

Wählen Sie ViewController und dann den Attribut-Inspector aus, der jetzt Adjust Scroll View Insets nicht markiert ist.

12

Bei Swift> 2.2 hatte ich Probleme mit iOS 8 und iOS 9, bei denen die oben genannten Methoden verwendet wurden, da es keine einzige Antwort gibt, die funktioniert. Daher habe ich Folgendes getan, damit es für beide funktioniert.

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

Bei vielen Tests habe ich festgestellt, dass ich unten in der viewWillLayoutSubviews () - Funktion hinzufügen muss, um sicherzustellen, dass die UITextView von Anfang an angezeigt wird:

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

Aktualisieren Sie die translucent -Eigenschaft Ihrer UINavigationBar auf NO:

self.navigationController.navigationBar.translucent = NO;

Dadurch wird verhindert, dass die Ansicht unter der Navigationsleiste und der Statusleiste gerahmt wird.

Wenn Sie die Navigationsleiste ein- und ausblenden müssen, verwenden Sie den folgenden Code in Ihrer viewDidLoad

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

Hoffe das hilft.

5
Mrunal

Xcode 7.2 7c68; IOS 9.1

Mein ViewController, das UITextView enthält, ist kompliziert und hat sich während des Projekts stark verändert (die IDE-Version hat sich möglicherweise auch zwei- bis dreimal geändert).

Ich habe alle oben genannten Lösungen ausprobiert. Wenn Sie auf dasselbe Problem stoßen, seien Sie GEDULDIG .

Es gibt drei mögliche 'Geheimcodes', die gelöst werden müssen:

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

Und es gibt zwei Stellen, an denen Sie diese Codes eingeben können:

  1. viewDidLoad()
  2. viewDidLayoutSubviews()

Kombinieren Sie sie, Sie erhalten 3 * 2 = 6 Lösungen. Die richtige Kombination hängt davon ab, wie kompliziert Sie sind. ViewController (Glauben Sie mir, nachdem Sie nur eine Ansicht über textView gelöscht haben, muss ich eine neue finden Kombination).

Und ich fand das:

Wenn in viewDidLayoutSubviews() 'secret codes' eingegeben werden, aber in viewDidLoad()textView.text = someStrings, Wird der Inhalt in textView manchmal 'wackeln'. Also legen Sie sie an den gleichen Ort.

Letztes Wort: versuche ALLE Kombinationen, so löse ich diesen dummen Fehler mehr als dreimal innerhalb von zwei Monaten.

4
outcast

UITextView Scrollen scheint für viele Leute ein Problem zu sein. Aus den Antworten hier (vor allem this ) und der Apple Developer-Dokumentation, die etwas von meinem eigenen Witz verwendet, wird hier eine Lösung gefunden, die für mich funktioniert. Sie können den Code an Ihre Bedürfnisse anpassen.

Mein Anwendungsfall ist wie folgt: Die gleiche UITextView wird für verschiedene Zwecke verwendet, wobei in verschiedenen Situationen unterschiedliche Inhalte angezeigt werden. Ich möchte, dass bei Änderungen des Inhalts die alte Bildlaufposition wiederhergestellt wird oder bis zum Ende gescrollt wird. Ich möchte nicht zu viel Animation, wenn dies erledigt ist. Insbesondere möchte ich nicht, dass die Ansicht so animiert wird, wie der gesamte Text neu war. Bei dieser Lösung wird zunächst die alte Bildlaufposition ohne Animation wiederhergestellt, und dann bis zum animierten Ende, wenn dies gewünscht wird.

Was Sie tun müssen (oder sollte ich can tun), ist, UITextView wie folgt zu erweitern:

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

Dabei wird der Text aktualisiert, dann wird ein gespeicherter Wert der UITextView.contentOffset-Eigenschaft (oder alles, was Sie als Parameter übergeben) verwendet, und der Versatz der Ansicht wird entsprechend festgelegt. Falls gewünscht, scrollt es bis zum Ende des neuen, möglicherweise geänderten Inhalts.

Ich bin neu in der iOS-Programmierung und weiß nicht, warum es so gut funktioniert. Wenn jemand Informationen darüber hat, wäre es schön zu wissen. Auch der Ansatz ist möglicherweise nicht perfekt, daher bin ich auch offen für Verbesserungsideen.

Und natürlich danke NixonsBack für die Veröffentlichung der Antwort hinter dem obigen Link.

Mein erster Beitrag :), Prost!

4
ipe

Der folgende Code sollte Ihnen die gewünschte Wirkung verleihen.

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

Sie müssen "self.scrollView" durch den Namen Ihrer Bildlaufansicht ersetzen. Sie sollten diesen Code einfügen, nachdem Sie den Text der Bildlaufansicht festgelegt haben.

3
Gary Riches

Fügen Sie diese eine Codezeile in ViewDidLoad ein.

self.automaticallyAdjustsScrollViewInsets = false
3
Murat Yasar

Das hat für mich funktioniert: 

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

}
2
bpolat

Das funktionierte für mich mit Xcode 8.3.3:

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

Erstellen Sie einen Ausgang für Ihre UITextView in der ViewController.Swift-Datei. Fügen Sie im Abschnitt ViewDidLoad Folgendes ein:

Schnell:

self.textView.contentOffset.y = 0

Ich habe versucht:

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

Ich habe Zeeples Antwort in MonoTouch/Xamarin (C #) übersetzt.

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

Ich musste hier zwei Antworten implementieren, damit meine Ansicht so funktioniert, wie ich will:

Von Juan David Cruz Serrano:

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

Und von Murat Yasar:

automaticallyAdjustsScrollViewInsets = false

Dies ergab eine UITextView, die mit dem Bildlauf ganz oben geladen wird und bei dem die Einfügungen nicht geändert werden, wenn der Bildlauf beginnt. Sehr seltsam, dass dies nicht das Standardverhalten ist.

0
Leon

Swift 4.2 & Swift 5

stellen Sie den Inhaltsoffset sowohl vor als auch nach dem Festlegen des Texts ein. (auf dem Hauptthread)

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

Verwenden Sie den folgenden Code, um die Variable textView jedes Mal oben zu starten

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