Текстовое содержимое UITextView не начинается сверху


79

У меня есть длинный текст из моего файла JSON, но когда я нажимаю ссылку со своего UITableViewCell, чтобы перейти на мою страницу UIViewController, текст UITextView загружает содержимое строки, но он не отображает содержимое с самого начала, и мне нужно прокрутить все вверх время.

Что мне нужно сделать?


Вы пробовали установить для contentOffset значение (0,0)?
— rdelmar

Вы можете редактировать этот вопрос. Под тегами вы видите слово «редактировать». щелкните это, чтобы отредактировать. Я получил предложение отредактировать, но считаю, что пользователь должен отредактировать вопрос.
— LanternMike

посетите эту страницу и посмотрите, подходит ли вам одно из этих решений. Почти все, что здесь есть, есть там, и многое другое stackoverflow.com/questions/1234242/… Если у вас есть вопросы, укажите, что происходит, работает, а не работает то, что вы пробовали.
— LanternMike

Вот ссылка с моей проблемой: ссылка
— Орнило

единственное решение, которое сработало для меня, было взято из другого поста
— Андрей Бас

Ответы:


160

У меня была та же проблема, и оказалось, что мне пришлось установить смещение содержимого в viewDidLayoutSubviews, чтобы оно вступило в силу. Я использую этот код для отображения статического текста с атрибутами.

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

SWIFT 3:

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

4
Из всех ответов этот работает лучше всего. Кроме того, если ваш текст UITextView начинается где-то ближе к вертикальной середине текстового представления, добавление следующего в viewDidLoad тоже исправит это: self.automaticallyAdjustsScrollViewInsets = false
— Wizkid

Интересно то, что решение offuttjillian действительно сработало для меня, но решение, данное вами @Wizkid и Glenn, делает его еще хуже для меня на iOS 9.1 В любом случае оно работает сейчас, и это меня радует ^^
— Frozn

2
хотя это рабочее решение, к сожалению, оно имеет большой побочный эффект - уродливо видимую прокрутку вверх, даже если вы используете viewWillLayoutSubviews: /
— Hofi

Я попробовал почти 6 способов решения проблемы, и этот ответ работал у меня только в iOS9.x.
— KoreanXcodeWorker

работает хорошо , даже если установить его после присвоения текста для UITextView
— Hassy

46

Это единственный способ, который сработал для меня. Я отключаю прокрутку UITextView до загрузки представления, а затем снова включаю его:

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

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

2
лучшее решение для минимального видимого визуального эффекта от прокрутки вверх
— Hofi


У меня были проблемы с загромождением при прокрутке на iPad с помощью этого решения.
— Aliens


19

Программно перед загрузкой содержимого отключите свойство прокрутки textview textview.scrollenabled = NO;

И после загрузки включите прокрутку textview textview.scrollenabled = YES;

Также проверьте XIB, всегда не проверяйте, включена ли прокрутка Textview.


Большое спасибо, но если у нас есть этот uitextview в collectionview или tableview, он не будет работать
— Amr Angry

12

Ответы на вопрос. Пустое пространство в верхней части UITextView в iOS 10 обеспечивает более чистый интерфейс для конечных пользователей.

В viewDidLoadконтроллере представления, содержащем текстовое представление:

 self.automaticallyAdjustsScrollViewInsets = false

Настройка textView.setContentOffset(CGPointMake(0,0), animated: false)и некоторые из этих других предложений действительно работают при вызове, viewDidLayoutSubviews()но на более старых устройствах, таких как iPad 2 и старше, вы действительно увидите, как текст прокручивается при отображении экрана. Это не то, что вы хотите, чтобы конечный пользователь увидел.


4

После использования этих решений у меня все еще были проблемы. Проблема определенно связана с наличием прозрачных панелей навигации и выбором автоматической настройки вставок содержимого в контроллере представления. Если вас не волнует прокрутка текста под панелью навигации, лучше оставить эти настройки отключенными и ограничить верхнюю часть текстового представления нижней частью панели навигации, а не верхней частью контроллера просмотра.

Если, как и я, вы хотели, чтобы он отображался под панелью навигации при прокрутке вниз; тогда решение, которое сработало для меня, заключалось в том, чтобы добавить это.

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

Это просто ищет высоту панели навигации и строки состояния и соответствующим образом корректирует смещение содержимого.

Обратите внимание, что одним из недостатков этого подхода является то, что при вращении устройства вы в конечном итоге прокручиваете его обратно наверх.


Спасибо - это в конечном итоге привело меня к правильной идее :)
— HannahCarney

4

Для меня отлично работает этот код:

    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

Для прокрутки до точного положения и отображения его в верхней части экрана я использую этот код:

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

Установка contentOffset.y прокручивает до конца текста, а затем scrollRangeToVisible прокручивает до значения scrollToLocation. Таким образом, нужная позиция появляется в первой строке scrollView.


4

Подобно некоторым другим ответам, но с дополнительным преимуществом, заключающимся в том, что вы не будете вызывать прокрутку вверх при последующих поворотах устройства. Хорошо работает в 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
}

После того, как я попробовал несколько разных ответов, этот сработал для меня лучше всего. Согласно ответу Swindler, вы можете использовать CGPointZero для CGPoint.
— Митч Дауни

Это важно сделать в этом методе - viewDidLayoutSubviews. Многие ответы заставят вас сделать это в viewWillAppear, но это неправильно. viewDidLayoutSubviews - место для этого. Благодарю.
— geekyaleks

3

Быстрая версия

Потребуется сочетание вещей:

1.) Настройте розетку

  @IBOutlet var textView: UITextView!

2.) В раскадровке на View Controller отключите «Adjust Scroll View Insets»

3.) Установите для содержимого нулевое значение сверху, добавив ниже в свой контроллер представления.

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

'CGPointZero' недоступен в Swift
— ali,

3

Вместо установки смещения содержимого из viewDidLayoutSubviews вы можете написать layoutIfNeeded из viewDidLoad, чтобы установить правильную позицию textview, как показано ниже:

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

Ура !!


2

В решении Swift 2, Xcode 7, чтобы оставить прокрутку включенной, а также чтобы текст начинался вверху, это все, что вам нужно:

@IBOutlet weak var myUITextView: UITextView!

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

1
благодаря! у меня это отлично сработало со Swift 2.2. Ни одно из других решений здесь не работало так гладко и просто.
— Наталья

2

Swift 3.0

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

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

Отключите прокрутку в раскадровке! И включить в коде. переопределить функцию viewDidAppear (_ animated: Bool) {privacyText.isScrollEnabled = true}
— Виталий А

2

Это сработало для меня лучше всего! Я поместил это в viewDidLoad ().

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

1
Выражение не присваивается.
— Bhumesh Purohit

1

Вот еще один способ, который всегда работает для меня. Цель-C:

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

А в Swift:

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

1

Быстрая версия:

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

1

добавьте следующую функцию в свой класс контроллера представления ...

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 里面 加上 滚动 , 这样 用户 会 看到 他 往上 滚动 到 第一 行


не могли бы вы перевести последнее предложение на английский?
— Gilles Gouaillardet,

1

в быстром 4 с приписанным текстом ни один из ответов мне не помогает, и я объединяю некоторые ответы в теме.

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

как насчет того, находится ли uittextview в виде коллекции или в виде таблицы
— Амр Злой

@AmrAngry, я понятия не имею, я просто использовал его для просмотра текста
— hall.keskin

спасибо, я использую tetxview.scrollRangeToVisible (NSMakeRange (0, 0))
— Amr Angry

1

Решение Swift 3, 4, 5:

Шаги по решению проблемы:

  • Отключить прокрутку UITextView
  • установить scrollRectToVisible
  • включить прокрутку UITextView

Код:

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

Это сработало для меня. Надеюсь, это поможет!


Спасибо Mohit за удобное и простое объяснение.
— Praveen Kumar Verma

0

Вот как я это сделал. Я создал подклассы textview и:

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

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

0

В раскадровке выберите контроллер представления, на котором вы разместили текстовое представление. В инспекторе атрибутов снимите флажок «Настроить вставки прокрутки». Вот и все.


0

Поместите этот код в свой класс

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.