Ответ 1
UITextView*note;
[note setContentOffset:CGPointZero animated:YES];
Это делает это для меня.
Версия Swift (Swift 4.1 с iOS 11 на Xcode 9.3):
note.setContentOffset(.zero, animated: true)
Хорошо, у меня проблемы с UITextView
. Здесь проблема:
Я добавляю текст в UITextView
. Затем пользователь дважды щелкает, чтобы выбрать что-то.
Затем я изменяю текст в UITextView
(программно, как указано выше), а UITextView
прокручивается в нижней части страницы, где есть курсор.
Однако это НЕ, где пользователь нажал. Он ВСЕГДА прокручивается в нижней части UITextView
независимо от того, где пользователь нажал.
Итак, вот мой вопрос: как заставить UITextView
прокручивать вверх до каждого раза при изменении текста? Я пробовал contentOffset
и scrollRangeToVisible
. Ни одна из них не работает.
Любые предложения будут оценены.
UITextView*note;
[note setContentOffset:CGPointZero animated:YES];
Это делает это для меня.
Версия Swift (Swift 4.1 с iOS 11 на Xcode 9.3):
note.setContentOffset(.zero, animated: true)
Если у кого-то есть эта проблема в iOS 8, я обнаружил, что просто установка свойства текста UITextView's
, а затем вызов scrollRangeToVisible
с помощью NSRange
с location:0
, length:0
работал. Мое текстовое представление не редактировалось, и я тестировал как выборочный, так и не выбираемый (ни одна из них не влияла на результат). Вот пример Swift:
myTextView.text = "Text that is long enough to scroll"
myTextView.scrollRangeToVisible(NSRange(location:0, length:0))
И вот мое решение...
override func viewDidLoad() {
textView.scrollEnabled = false
textView.text = "your text"
}
override func viewDidAppear(animated: Bool) {
textView.scrollEnabled = true
}
Вызов
scrollRangeToVisible(NSMakeRange(0, 0))
работает, но назовите его
override func viewDidAppear(animated: Bool)
Я использовал атрибутString в HTML с открытым текстом. Установка смещения содержимого тоже не работала для меня. Это сработало для меня: отключить прокрутку, установить текст, а затем снова включить прокрутку
[yourTextView setScrollEnabled:NO];
yourTextView.text = yourtext;
[yourTextView setScrollEnabled:YES];
Поскольку ни один из этих решений не работал у меня, и я потратил слишком много времени на сбор решений, это, в конечном итоге, решило это для меня.
override func viewWillAppear(animated: Bool) {
dispatch_async(dispatch_get_main_queue(), {
let desiredOffset = CGPoint(x: 0, y: -self.textView.contentInset.top)
self.textView.setContentOffset(desiredOffset, animated: false)
})
}
Это действительно глупо, что это не поведение по умолчанию для этого элемента управления.
Надеюсь, это поможет кому-то другому.
Я не уверен, понимаю ли я ваш вопрос, но пытаетесь ли вы просто прокрутить представление до вершины? Если это так, вы должны сделать
[textview scrollRectToVisible:CGRectMake(0,0,1,1) animated:YES];
Для iOS 10 и Swift 3 я сделал:
override func viewDidLoad() {
super.viewDidLoad()
textview.isScrollEnabled = false
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
textView.isScrollEnabled = true
}
Работал для меня, не уверен, что у вас возникла проблема с последней версией Swift и iOS.
У меня есть обновленный ответ, который будет правильно отображаться в тексте, и без использования пользовательской анимации прокрутки.
override func viewWillAppear(animated: Bool) {
dispatch_async(dispatch_get_main_queue(), {
self.introductionText.scrollRangeToVisible(NSMakeRange(0, 0))
})
Вот как это работает в выпуске iOS 9 так как textView прокручивается сверху, прежде чем появляться на экране
- (void)viewDidLoad
{
[super viewDidLoad];
textView.scrollEnabled = NO;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
textView.scrollEnabled = YES;
}
Вот как я это сделал
Свифт 4:
extension UITextView {
override open func draw(_ rect: CGRect)
{
super.draw(rect)
setContentOffset(CGPoint.zero, animated: false)
}
}
Попробуйте переместить курсор в начало текста.
NSRange r = {0,0};
[yourTextView setSelectedRange:r];
Посмотрите, как это происходит. Убедитесь, что вы вызвали это после того, как все ваши события были уволены или что вы делаете.
[txtView setContentOffset:CGPointMake(0.0, 0.0) animated:YES];
Эта строка кода работает для меня.
Объединив предыдущие ответы, теперь он должен работать:
talePageText.scrollEnabled = false
talePageText.textColor = UIColor.blackColor()
talePageText.font = UIFont(name: "Bradley Hand", size: 24.0)
talePageText.contentOffset = CGPointZero
talePageText.scrollRangeToVisible(NSRange(location:0, length:0))
talePageText.scrollEnabled = true
Моя проблема заключается в том, чтобы textView прокручивал вверх, когда появился вид. Для iOS 10.3.2 и Swift 3.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// It doesn't work. Very strange.
self.textView.setContentOffset(CGPoint.zero, animated: false)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
// It works, but with an animation effection.
self.textView.setContentOffset(CGPoint.zero, animated: false)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// It works.
self.textView.contentOffset = CGPoint.zero
}
Swift 2 Ответ:
textView.scrollEnabled = false
/* Set the content of your textView here */
textView.scrollEnabled = true
Это предотвращает прокрутку текста в конце текста после его установки.
В Swift 3:
viewWillLayoutSubviews - это место для внесения изменений. viewWillAppear должен работать, но логически, макет должен выполняться в viewWillLayoutSubviews.
В отношении методов будут работать как scrollRangeToVisible, так и setContentOffset. Однако setContentOffset позволяет отключить или отключить анимацию.
Предположим, что UITextView назван yourUITextView. Здесь код:
// Connects to the TextView in the interface builder.
@IBOutlet weak var yourUITextView: UITextView!
/// Overrides the viewWillLayoutSubviews of the super class.
override func viewWillLayoutSubviews() {
// Ensures the super class is happy.
super.viewWillLayoutSubviews()
// Option 1:
// Scrolls to a range of text, (0,0) in this very case, animated.
yourUITextView.scrollRangeToVisible(NSRange(location: 0, length: 0))
// Option 2:
// Sets the offset directly, optional animation.
yourUITextView.setContentOffset(CGPoint(x: 0, y: 0), animated: false)
}
Это сработало для меня. Он основан на ответе RyanTCBs, но это вариант 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)];
}
-(void) viewDidAppear:(BOOL)animated{
[mytextView scrollRangeToVisible:NSMakeRange(0,0)];}
- (void)viewWillAppear:(BOOL)animated{
[mytextView scrollRangeToVisible:NSMakeRange(0,0)];}
ViewWillappear
сделает это мгновенно, прежде чем пользователь сможет заметить, но ViewDidDisappear
раздел будет анимировать его лениво.[mytextView setContentOffset:CGPointZero animated:YES];
НЕ работает иногда (я не знаю почему), поэтому используйте scrollrangetovisible.Проблема решена: iOS = 10,2 Swift 3 UITextView
Я использовал только следующую строку:
displayText.contentOffset.y = 0
просто вы можете использовать этот код
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
textView.scrollRangeToVisible(NSMakeRange(0, 0))
}
Это сработало для меня
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
DispatchQueue.main.async {
self.textView.scrollRangeToVisible(NSRange(location: 0, length: 0))
}
}
[self.textView scrollRectToVisible:CGRectMake(0, 0, 320, self.textView.frame.size.height) animated:NO];
-(void)viewWillLayoutSubviews{
[super viewWillLayoutSubviews];
[textview setContentOffset:CGPointZero animated:NO];
}
У меня возникла проблема, но в моем случае 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
}
Для меня отлично работает этот код:
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.
Для меня в 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)
})
где delay:
func delay(delay:Double, closure:()->Void) {
dispatch_after(
dispatch_time(
DISPATCH_TIME_NOW,
Int64(delay * Double(NSEC_PER_SEC))
),
dispatch_get_main_queue(), closure)
}
Попробуйте использовать это решение из 2 строк:
view.layoutIfNeeded()
textView.contentOffset = CGPointMake(textView.contentInset.left, textView.contentInset.top)
Вот мои коды. Он отлично работает.
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()
}
}
Swift 3 version of 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.