Текстовое содержимое 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.