Der Textinhalt von UITextView beginnt nicht von oben


79

Ich habe einen langen Text aus meiner JSON-Datei, aber wenn ich auf den Link von meiner UITableViewCell klicke, um zu meiner UIViewController-Seite zu gelangen, lädt der UITextView-Text den String-Inhalt, zeigt aber nicht den Inhalt von Anfang an an und ich muss alle nach oben scrollen die Zeit.

Was ich tun muss?


Haben Sie versucht, contentOffset auf (0,0) zu setzen?
Rdelmar

Sie können diese Frage bearbeiten. Unter den Tags sehen Sie "Bearbeiten". Klicken Sie zum Bearbeiten darauf. Ich habe einen Vorschlag für eine Bearbeitung erhalten, bin jedoch der Meinung, dass der Benutzer die Frage bearbeiten sollte.
LanternMike

Überprüfen Sie auf dieser Seite, ob eine dieser Lösungen für Sie geeignet ist. Fast alles hier ist dort und mehr stackoverflow.com/questions/1234242/… Wenn Sie Fragen haben, geben Sie genau an, was los ist, funktioniert, nicht funktioniert, was Sie versucht haben.
LanternMike

Hier ist der Link zu meinem Problem: Link
Ornilo

Die einzige Lösung, die für mich funktionierte, war von diesem aus einem anderen Beitrag
Andriy Bas

Antworten:


159

Ich hatte das gleiche Problem und es stellte sich heraus, dass ich den Inhaltsoffset in viewDidLayoutSubviews festlegen musste, damit er wirksam wird. Ich verwende diesen Code, um zugeschriebenen statischen Text anzuzeigen.

- (void)viewDidLayoutSubviews {
    [self.yourTextView setContentOffset:CGPointZero animated:NO];
}

SWIFT 3:

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

4
Von allen Antworten funktioniert diese am besten. Wenn Ihr UITextView-Text irgendwo in der vertikalen Mitte der Textansicht beginnt, wird dies durch Hinzufügen von Folgendem zu viewDidLoad ebenfalls behoben: self.automaticallyAdjustsScrollViewInsets = false
Wizkid

Das Interessante ist, dass die Lösung von offuttjillian für mich funktioniert hat, aber die von Ihnen @Wizkid und Glenn gegebene Lösung macht es für mich unter iOS 9.1 noch schlimmer. Wie auch immer, es funktioniert jetzt und das freut mich ^^
Frozn

2
Obwohl dies eine funktionierende Lösung ist, hat es leider einen großen Nebeneffekt, den hässlichen sichtbaren Upscroll, selbst wenn Sie verwenden viewWillLayoutSubviews: /
Hofi

Diese Antwort hat fast 6 Möglichkeiten zur Lösung des Problems versucht und funktionierte nur für mich in iOS9.x.
KoreanXcodeWorker

funktioniert auch dann gut, wenn es nach dem Zuweisen von Text für UITextView
Hassy

46

Dies ist der einzige Weg, der für mich funktioniert hat. Ich deaktiviere den Bildlauf der UITextView, bevor die Ansicht geladen wird, und aktiviere sie dann erneut:

  override func viewWillAppear(_ animated: Bool) {
        yourTextView.isScrollEnabled = false
    }

    override func viewDidAppear(_ animated: Bool) {
        yourTextView.isScrollEnabled = true
    }

2
Die beste Lösung, um den minimalen sichtbaren visuellen Effekt der Schriftrolle
Hofi

Hat gut
funktioniert

Ich hatte einige Probleme beim Scrollen auf dem iPad mit dieser Lösung.
Aliens

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

im viewDidLoad


19

Deaktivieren Sie vor dem Laden des Inhalts programmgesteuert die Bildlaufeigenschaft von textview textview.scrollenabled = NO;

Und nach dem Laden aktivieren Sie das Scrollen der Textansicht textview.scrollenabled = YES;

XIBAktivieren Sie auch das Kontrollkästchen , das in Textansicht immer aktiviert ist.


Vielen Dank, aber wenn wir diese Uitextview in Collectionview oder Tableview haben, wird es nicht funktionieren
Amr Angry

12

Die Antworten auf die Frage Leerzeichen oben in UITextView in iOS 10 bieten eine viel sauberere Endbenutzererfahrung.

In viewDidLoadder Ansichtssteuerung, die die Textansicht enthält:

 self.automaticallyAdjustsScrollViewInsets = false

Die Einstellungen textView.setContentOffset(CGPointMake(0,0), animated: false)und einige dieser anderen Vorschläge funktionieren, wenn sie im aufgerufen werden. viewDidLayoutSubviews()Auf älteren Geräten wie iPad 2 und älter wird der Text jedoch tatsächlich gescrollt, wenn der Bildschirm angezeigt wird. Das soll der Endbenutzer nicht sehen.


4

Ich hatte immer noch Probleme, nachdem ich diese Lösungen verwendet hatte. Das Problem scheint definitiv darin zu liegen, transparente Navigationsleisten zu haben und die Inhaltseinfügungen auf dem Ansichts-Controller automatisch anzupassen. Wenn Sie sich nicht dafür interessieren, dass Ihr Text unter der Navigationsleiste gescrollt wird, lassen Sie diese Einstellungen am besten deaktiviert und beschränken Sie den oberen Rand Ihrer Textansicht auf den unteren Rand der Navigationsleiste und nicht auf den oberen Rand des Ansichtscontrollers.

Wenn Sie wie ich möchten, dass es beim Scrollen nach unten unter Ihrer Navigationsleiste angezeigt wird; dann war die Lösung, die für mich funktionierte, dies hinzuzufügen.

- (void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];

    CGFloat offset = self.navigationController.navigationBar.frame.size.height+[UIApplication sharedApplication].statusBarFrame.size.height;

    [self.textView setContentOffset:CGPointMake(0, -offset) animated:NO];
}

Dies sucht nur nach der Höhe der Navigationsleiste und der Statusleiste und passt den Inhaltsversatz entsprechend an.

Beachten Sie, dass ein Nachteil dieses Ansatzes darin besteht, dass Sie beim Drehen des Geräts nach oben scrollen.


Vielen Dank - das hat mich letztendlich zur richtigen Idee geführt :)
HannahCarney

4

Für mich funktioniert dieser Code gut:

    textView.attributedText = newText //or textView.text = ...

    //this part of code scrolls to top
    textView.contentOffset.y = -64 //or = 0 if no Navigation Bar
    textView.scrollEnabled = false
    textView.layoutIfNeeded()
    textView.scrollEnabled = true

Um zur exakten Position zu scrollen und sie oben auf dem Bildschirm anzuzeigen, verwende ich diesen Code:

    var scrollToLocation = 50 //<needed position>
    textView.contentOffset.y = textView.contentSize.height
    textView.scrollRangeToVisible(NSRange.init(location: scrollToLocation, length: 1))

Wenn Sie contentOffset.y festlegen, wird ein Bildlauf zum Ende des Texts ausgeführt, und scrollRangeToVisible führt einen Bildlauf bis zum Wert von scrollToLocation durch. Dabei erscheint die benötigte Position in der ersten Zeile von scrollView.


4

Ähnlich wie bei einigen anderen Antworten, jedoch mit dem zusätzlichen Vorteil, dass bei nachfolgenden Gerätedrehungen kein Bildlauf nach oben erfolgt. Funktioniert gut in Swift 2.2

/// Whether view has laid out subviews at least once before.
var viewDidLayoutSubviewsAtLeastOnce = false

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    if !viewDidLayoutSubviewsAtLeastOnce {
        textView.setContentOffset(CGPoint(x: 0, y: -textView.contentInset.top), animated: false)
    }

    viewDidLayoutSubviewsAtLeastOnce = true
}

Nachdem ich ein paar verschiedene Antworten ausprobiert hatte, funktionierte diese am besten für mich. Gemäß der Antwort von Swindler können Sie CGPointZero für CGPoint verwenden.
Mitch Downey

Es ist wichtig, dies in dieser Methode zu tun - viewDidLayoutSubviews. Bei vielen Antworten müssen Sie dies in viewWillAppear tun, aber das ist falsch. viewDidLayoutSubviews ist der richtige Ort dafür. Vielen Dank.
Geekyaleks

3

Schnelle Version

Eine Kombination von Dingen wird benötigt:

1.) Stellen Sie Ihre Steckdose ein

  @IBOutlet var textView: UITextView!

2.) Deaktivieren Sie im Storyboard des View Controllers "Scroll View Insets anpassen".

3.) Setzen Sie den Inhalt auf Null, indem Sie unten Ihrem Ansichts-Controller hinzufügen

override func viewWillLayoutSubviews() {
   super.viewWillLayoutSubviews()
     myUITextView.setContentOffset(CGPointZero, animated: false)
}

'CGPointZero' ist in Swift
ali

3

Anstatt den Inhaltsversatz von viewDidLayoutSubviews festzulegen , können Sie layoutIfNeeded von viewDidLoad aus schreiben , um die richtige Position der Textansicht wie folgt festzulegen:

    self.textView.layoutIfNeeded()
    self.textView.setContentOffset(CGPoint.zero, animated: false)

Prost !!


2

In der Swift 2, Xcode 7-Lösung ist dies alles, was Sie benötigen , um den Bildlauf aktiviert zu lassen und den Text oben zu beginnen:

@IBOutlet weak var myUITextView: UITextView!

override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()
    //start scroll at top of text
    myUITextView.scrollRangeToVisible(NSMakeRange(0, 0))
}

1
Vielen Dank! Das hat bei Swift 2.2 perfekt funktioniert. Keine der anderen Lösungen hier funktionierte so reibungslos und einfach.
Natalia

2

Swift 3.0

override func viewWillAppear(_ animated: Bool) {
    privacyText.isScrollEnabled = false
}

override func viewDidAppear(_ animated: Bool) {
    privacyText.isScrollEnabled = true
}

Deaktivieren Sie das Scrollen im Storyboard! Und im Code aktivieren. überschreiben func viewDidAppear (_ animiert: Bool) {privacyText.isScrollEnabled = true}
Vitaliy A

2

Das hat bei mir am besten funktioniert! Ich habe dies in viewDidLoad () platziert.

//TextView Scroll starts from the top
myTextView.contentOffset.y = 0

1
Ausdruck ist nicht zuweisbar.
Bhumesh Purohit

1

Hier ist eine andere Möglichkeit, die immer für mich funktioniert. Ziel c:

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    [self.textView setContentOffset:CGPointZero animated:NO];
}

Und in Swift:

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

1

Schnelle Version:

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

1

Fügen Sie Ihrer View Controller-Klasse die folgende Funktion hinzu ...

Swift 3

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

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

- (void)viewDidLayoutSubviews {
    [self.mainTextView setContentOffset:CGPointZero animated:NO];
}

D 你 里面 ViewDidAppear 里面 加上 滚动 , 这样 用户 用户 会 看到 他 往上 滚动 到


Könnten Sie bitte den letzten Satz ins Englische übersetzen?
Gilles Gouaillardet

1

In Swift 4 mit zugeschriebenem Text hilft mir keine Antwort und ich kombiniere einige Antworten im Thema.

override func viewWillAppear(_ animated: Bool) {
     super.viewWillAppear(animated)
     uiTextview.isScrollEnabled = false
}

override func viewDidAppear(_ animated: Bool) {
     uiTextview.isScrollEnabled = true
     uiTextview.setContentOffset(CGPoint.zero, animated: false)
}

Was ist, wenn die Uittextview in der Sammlungsansicht oder Tabellenansicht ist
Amr Angry

@ AmrAngry Ich habe keine Ahnung, ich habe es nur für die
Textansicht

danke ich benutze tetxview.scrollRangeToVisible (NSMakeRange (0, 0))
Amr Angry

1

Schnelle 3, 4, 5 Lösung:

Schritte zur Lösung des Problems:

  • Deaktivieren Sie den UITextView-Bildlauf
  • setze scrollRectToVisible
  • Aktivieren Sie den UITextView-Bildlauf

Code:

yourTextView.isScrollEnabled = false
let rect:CGRect = CGRect(x: 0, y: 0, width: 1, height: 1)
yourTextView.scrollRectToVisible(rect, animated: false)
yourTextView.isScrollEnabled = true

Das hat bei mir funktioniert. Hoffe das wird helfen!


Vielen Dank an Mohit für eine einfache Erklärung.
Praveen Kumar Verma

0

So habe ich es gemacht. Ich habe Textansicht in Unterklassen unterteilt und:

override func willMoveToSuperview(newSuperview: UIView?) {
    self.scrollEnabled = false
}

override func layoutSubviews() {
    super.layoutSubviews()
    self.scrollEnabled = true
}

0

Wählen Sie im Storyboard den Ansichts-Controller aus, auf dem Sie die Textansicht platziert haben. Deaktivieren Sie im Attributinspektor das Kontrollkästchen "Bildlaufansichten anpassen". Das ist es.


0

Fügen Sie diesen Code Ihrer Klasse hinzu

override func viewDidLayoutSubviews() {
        self.About_TV.setContentOffset(.zero, animated: false) // About_TV : your text view name)
    }

-2

Fügen Sie dem viewdidload Code hinzu

self.automaticallyAdjustsScrollViewInsets = NO;
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.