Как заставить UITextView прокручивать вверх каждый раз, когда я изменяю текст? - PullRequest
91 голосов
/ 05 августа 2009

ОК, у меня проблема с UITextView. Вот проблема:

Я добавляю текст к UITextView. Затем пользователь дважды щелкает, чтобы выбрать что-то. Затем я изменяю текст в UITextView (программно, как указано выше), а UITextView прокручивается вниз страницы, где находится курсор.

Однако это не то место, где пользователь нажал. Он ВСЕГДА прокручивается до нижней части UITextView независимо от того, где пользователь нажал.

Итак, вот мой вопрос: как заставить UITextView прокручивать вверх каждый раз, когда я изменяю текст? Я пробовал contentOffset и scrollRangeToVisible. Ни одна из них не работает.

Любые предложения будут оценены.

Ответы [ 36 ]

3 голосов
/ 16 декабря 2015

Это сработало для меня. Он основан на ответе RyanTCB, но это вариант Objective-C того же решения:

- (void) viewWillAppear:(BOOL)animated {
    // For some reason the text view, which is a scroll view, did scroll to the end of the text which seems to hide the imprint etc at the beginning of the text.
    // On some devices it is not obvious that there is more text when the user scrolls up.
    // Therefore we need to scroll textView to the top.
    [self.textView scrollRangeToVisible:NSMakeRange(0, 0)];
}
3 голосов
/ 14 января 2017

Проблема решена: iOS = 10,2 Свифт 3 UITextView

Я просто использовал следующую строку:

displayText.contentOffset.y = 0
2 голосов
/ 24 апреля 2016
-(void)viewWillLayoutSubviews{
    [super viewWillLayoutSubviews];

    [textview setContentOffset:CGPointZero animated:NO];
}
2 голосов
/ 27 февраля 2017

У меня была проблема, но в моем случае textview - это подпрограмма некоторого пользовательского представления и добавила его в ViewController. Ни одно из решений не помогло мне. Для решения проблемы добавлена ​​задержка 0,1 сек, а затем включена прокрутка. У меня это сработало.

textView.isScrollEnabled = false
..
textView.text = // set your text here

let dispatchTime = DispatchTime.now() + 0.1
DispatchQueue.main.asyncAfter(deadline: dispatchTime) {
   self.textView.isScrollEnabled = true
}
2 голосов
/ 25 мая 2015
[self.textView scrollRectToVisible:CGRectMake(0, 0, 320, self.textView.frame.size.height) animated:NO];
1 голос
/ 02 января 2018

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

Прокручивать нечего, когда TextView еще не появилось.

Вам нужно подождать, пока сначала появится TextView, и только затем установить его положение прокрутки внутри метода viewDidAppear, как показано ниже:

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    textView.setContentOffset(CGPoint.zero, animated: false)
}
1 голос
/ 14 сентября 2017

Swift 3 версия ответа drew_s ранее, единственное, что сработало для меня после того, как я попробовал большинство других ответов.

    override func viewWillAppear(_ animated: Bool) {
    DispatchQueue.main.async{
        let desiredOffset = CGPoint(x: 0, y: -self.person_description.contentInset.top)
        self.person_description.setContentOffset(desiredOffset, animated: false)
    }
}

Это был вырез и вставка рабочего кода. Замените person_description вашей переменной textview.

1 голос
/ 14 июня 2017

Вот мои коды. Работает нормально.

class MyViewController: ... 
{
  private offsetY: CGFloat = 0
  @IBOutlet weak var textView: UITextView!
  ...

  override viewWillAppear(...) 
  {
      ...
      offsetY = self.textView.contentOffset.y
      ...
  }
  ...
  func refreshView() {
      let offSetY = textView.contentOffset.y
      self.textView.setContentOffset(CGPoint(x:0, y:0), animated: true)
      DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
        [unowned self] in
        self.textView.setContentOffset(CGPoint(x:0, y:self.offSetY), 
           animated: true)
        self.textView.setNeedsDisplay()
      }
  }
1 голос
/ 27 апреля 2016

Для меня в iOS 9 он перестал работать для меня с приписанной строкой с методом scrollRangeToVisible (1 строка была жирным шрифтом, другие строки были с обычным шрифтом)

Так что мне пришлось использовать:

textViewMain.attributedText = attributedString
textViewMain.scrollRangeToVisible(NSRange(location:0, length:0))
delay(0.0, closure: { 
                self.textViewMain.scrollRectToVisible(CGRectMake(0, 0, 10, 10), animated: false)
            })

где задержка:

func delay(delay:Double, closure:()->Void) {
    dispatch_after(
        dispatch_time(
            DISPATCH_TIME_NOW,
            Int64(delay * Double(NSEC_PER_SEC))
        ),
        dispatch_get_main_queue(), closure)
}
1 голос
/ 07 декабря 2015

У меня нормально работает этот код:

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

    //this part of code scrolls to top
    textView.contentOffset.y = -64
    textView.scrollEnabled = false
    textView.layoutIfNeeded() //if don't work, try to delete this line
    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 появляется нужная позиция.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...