Текстовое содержимое 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
27
[self.textView scrollRangeToVisible:NSMakeRange(0, 1)];

в viewDidLoad

Люк Смит
источник
19

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

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

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

Subathra D
источник
Большое спасибо, но если у нас есть этот 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)
}
Kelsheikh
источник
'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 里面 加上 滚动 , 这样 用户 会 看到 他 往上 滚动 到 第一 行

myj
источник
не могли бы вы перевести последнее предложение на английский?
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)
    }
Нимиша Джоши
источник
-2

Добавить код в viewdidload

self.automaticallyAdjustsScrollViewInsets = NO;
Ева Сюэ
источник