Treść tekstowa UITextView nie zaczyna się od góry


79

Mam długi tekst pochodzący z mojego pliku JSON, ale kiedy klikam łącze z mojego UITableViewCell, aby przejść do mojej strony UIViewController, tekst UITextView ładuje zawartość ciągu, ale nie pokazuje zawartości od początku i muszę przewijać wszystko w górę czas.

Co muszę zrobić?


Czy próbowałeś ustawić contentOffset na (0,0)?
— rdelmar

Możesz edytować to pytanie. Pod tagami widzisz „edytuj”. kliknij, aby edytować. Otrzymałem sugestię zmiany, ale uważam, że użytkownik powinien edytować pytanie.
— LanternMike

sprawdź tę stronę i sprawdź, czy jedno z tych rozwiązań działa dla Ciebie. Prawie wszystko, co tu jest, jest tam i więcej stackoverflow.com/questions/1234242/… Jeśli masz pytania, sprecyzuj, co się dzieje, działa, nie działa, co próbowałeś.
— LanternMike

Oto link do mojego problemu: link
— Ornilo

jedyne rozwiązanie, które zadziałało, pochodziło z tego z innego postu
— Andriy Bas

Odpowiedzi:


160

Miałem ten sam problem i okazało się, że musiałem ustawić przesunięcie zawartości w viewDidLayoutSubviews, aby zadziałało. Używam tego kodu do wyświetlania przypisanego tekstu statycznego.

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

SWIFT 3:

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

4
Ze wszystkich odpowiedzi ta działa najlepiej. Ponadto, jeśli tekst UITextView zaczyna się gdzieś w kierunku pionowego środka widoku tekstu, dodanie następującego elementu do viewDidLoad również to naprawi: self.automaticallyAdjustsScrollViewInsets = false
— Wizkid

Ciekawostką jest to, że rozwiązanie offuttjillian zadziałało dla mnie, ale rozwiązanie podane przez Ciebie @Wizkid i Glenn sprawia, że ​​jest jeszcze gorzej na iOS 9.1 W każdym razie działa teraz i to mnie cieszy ^^
— Frozn

2
chociaż jest to działające rozwiązanie, niestety ma duży efekt uboczny brzydkie widoczne przewijanie w górę, nawet jeśli używasz viewWillLayoutSubviews: /
— Hofi

Próbując prawie 6 sposobów rozwiązania problemu, ta odpowiedź zadziałała tylko dla mnie w iOS9.x.
— KoreanXcodeWorker

działa dobrze, nawet jeśli ustawisz go po przypisaniu tekstu do UITextView
— Hassy

46

To jedyny sposób, który zadziałał dla mnie. Wyłączam przewijanie UITextView przed załadowaniem widoku, a następnie włączam go ponownie:

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

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

2
najlepsze rozwiązanie, aby uzyskać jak najmniejszy widoczny efekt wizualny
— rozwijającego

Działało dobrze dla mnie
— thibaut noah

Miałem pewne problemy z bałaganem podczas przewijania na iPadzie, korzystając z tego rozwiązania.
— Cudzoziemcy


19

Przez Programowo przed załadowaniem treści wyłącz właściwość przewijania textview textview.scrollenabled = NO;

A po załadowaniu włącz przewijanie widoku tekstu textview.scrollenabled = YES;

Ponadto sprawdź XIB, zawsze nie zaznaczaj przewijania włączonego w Textview.


wielkie dzięki, ale jeśli mamy ten uitextview w widoku kolekcji lub widoku tabeli, to nie zadziała
— Amr Angry

12

Odpowiedzi na pytanie Puste miejsce u góry UITextView w systemie iOS 10 zapewnia znacznie czystsze wrażenia użytkownika końcowego.

W viewDidLoadkontrolerze widoku zawierającym widok tekstu:

 self.automaticallyAdjustsScrollViewInsets = false

Ustawienia textView.setContentOffset(CGPointMake(0,0), animated: false)i niektóre z tych innych sugestii działają po wywołaniu, viewDidLayoutSubviews()ale na starszych urządzeniach, takich jak iPad 2 i starsze, tekst zostanie przewinięty po wyświetleniu ekranu. To nie jest coś, co chciałbyś zobaczyć dla użytkownika końcowego.


4

Po zastosowaniu tych rozwiązań nadal miałem problemy. Wydaje się, że problem zdecydowanie dotyczy posiadania przezroczystych pasków nawigacji i automatycznego dostosowywania wstawek zawartości na kontrolerze widoku. Jeśli nie zależy Ci na przewijaniu tekstu pod paskiem nawigacyjnym, najlepiej pozostawić te ustawienia wyłączone i ograniczyć górną część widoku tekstu do dołu paska nawigacyjnego, a nie do góry kontrolera widoku.

Jeśli tak jak ja chciałeś, aby pojawiał się pod twoim paskiem nawigacyjnym podczas przewijania w dół; wtedy rozwiązaniem, które zadziałało, było dodanie tego.

- (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];
}

To tylko szuka wysokości paska nawigacji i paska stanu i odpowiednio dostosowuje przesunięcie zawartości.

Zwróć uwagę, że jedną wadą tego podejścia jest to, że gdy urządzenie się obraca, przewijasz z powrotem do góry.


Dziękuję - to ostatecznie doprowadziło mnie do dobrego pomysłu :)
— HannahCarney

4

Dla mnie dobrze działa ten kod:

    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

Aby przewinąć do dokładnej pozycji i pokazać ją na górze ekranu, używam tego kodu:

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

Ustawienie contentOffset.y powoduje przewijanie do końca tekstu, a następnie scrollRangeToVisible przewija w górę do wartości scrollToLocation. W ten sposób potrzebna pozycja pojawia się w pierwszym wierszu scrollView.


4

Podobnie jak w przypadku niektórych innych odpowiedzi, ale z dodatkową korzyścią, że nie spowodujesz przewijania do góry przy kolejnych obrotach urządzenia. Działa dobrze w 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
}

Po wypróbowaniu kilku różnych odpowiedzi, ta zadziałała najlepiej. Zgodnie z odpowiedzią Swindlera możesz użyć CGPointZero dla CGPoint.
— Mitch Downey

Ważne jest, aby zrobić to w tej metodzie - viewDidLayoutSubviews. Wiele odpowiedzi sprawi, że zrobisz to na widokuWillPear, ale to jest złe. viewDidLayoutSubviews to miejsce do zrobienia tego. Dzięki.
— geekyaleks

3

Szybka wersja

Potrzebna będzie kombinacja rzeczy:

1.) Ustaw gniazdko

  @IBOutlet var textView: UITextView!

2.) W scenorysie na Kontrolerze widoku wyłącz opcję „Dostosuj wstawki widoku przewijania”

3.) Ustaw zawartość na zero u góry, dodając poniżej do kontrolera widoku

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

„CGPointZero” jest niedostępne w Swift
— ali

3

Zamiast ustawiać zawartość odsunięty od viewDidLayoutSubviews można napisać layoutIfNeeded z viewDidLoad aby ustawić właściwą pozycję TextView jak poniżej:

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

Twoje zdrowie !!


2

W rozwiązaniu Swift 2, Xcode 7, aby pozostawić przewijanie włączone, a tekst zaczynać się od góry, to wszystko, czego potrzebujesz:

@IBOutlet weak var myUITextView: UITextView!

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

1
dzięki! działało to idealnie dla mnie z Swift 2.2. Żadne z innych rozwiązań nie działało tak płynnie i prosto.
— Natalia

2

Swift 3.0

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

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

Wyłącz przewijanie w Storyboard! I włącz w kodzie. override func viewDidAppear (_ animated: Bool) {privacyText.isScrollEnabled = true}
— Vitaliy A

2

To działało najlepiej dla mnie! Umieściłem to w viewDidLoad ().

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

1
Wyrażenia nie można przypisać.
— Bhumesh Purohit,

1

Oto inny sposób na zrobienie tego, który zawsze działa dla mnie. Cel C:

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

A w Swift:

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

1

Wersja Swift:

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

1

dodaj następującą funkcję do swojej klasy kontrolera widoku ...

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

或者 你 在 ViewDidAppear 里面 加上 滚动 , 这样 用户 会 看到 他 往上 滚动 到 第一 行


czy mógłbyś przetłumaczyć ostatnie zdanie na angielski?
— Gilles Gouaillardet

1

w swift 4 z przypisanym tekstem żadna odpowiedź nie pomaga mi i łączę niektóre odpowiedzi w temacie.

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

a co jeśli uittextview jest w widoku kolekcji lub widoku tabeli
— Amr Angry

@AmrAngry nie mam pojęcia, po prostu używali go do widoku tekstu
— hall.keskin

dzięki, używam tetxview.scrollRangeToVisible (NSMakeRange (0, 0))
— Amr Angry

1

Rozwiązanie Swift 3, 4, 5:

Kroki, aby rozwiązać problem:

  • Wyłącz przewijanie UITextView
  • ustaw scrollRectToVisible
  • włącz przewijanie UITextView

Kod:

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

To zadziałało dla mnie. Mam nadzieję, że to pomoże!


Dzięki Mohit za wygodne, łatwe wyjaśnienie.
— Praveen Kumar Verma

0

Tak to zrobiłem. Podklasowałem textview i:

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

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

0

W scenorysie wybierz kontroler widoku, na którym masz umieszczony widok tekstu. W inspektorze atrybutów odznacz „Dopasuj wstawki widoku przewijania”. Otóż ​​to.


0

Umieść ten kod na swojej klasie

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

-2

Dodaj kod do pliku viewdidload

self.automaticallyAdjustsScrollViewInsets = NO;
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.