El contenido de texto de UITextView no comienza desde arriba

79

Tengo un texto largo proveniente de mi archivo JSON, pero cuando hago clic en el enlace de mi UITableViewCell para ir a mi página UIViewController, el texto UITextView carga el contenido de la cadena pero no muestra el contenido desde el principio y tengo que desplazarme hacia arriba. el tiempo.

¿Lo que necesito hacer?

Ornilo
fuente
¿Ha intentado establecer contentOffset en (0,0)?
rdelmar
Puede editar esta pregunta. Debajo de las etiquetas verá "editar". haga clic en eso para editar. Recibí una sugerencia para editar, pero creo que el usuario debería editar la pregunta.
LanternMike
Consulte esta página y compruebe si alguna de estas soluciones funciona para usted. Casi todo lo que hay aquí está allí y más stackoverflow.com/questions/1234242/… Si tiene preguntas, sea específico sobre lo que está pasando, funciona, no funciona lo que intentó.
LanternMike
Aquí está el enlace con mi problema: enlace
Ornilo
la única solución que funcionó para mí fue de esta de otra publicación
Andriy Bas

Respuestas:

160

Tuve el mismo problema y resultó que tuve que establecer el desplazamiento de contenido en viewDidLayoutSubviews para que surta efecto. Estoy usando este código para mostrar texto estático atribuido.

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

SWIFT 3:

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    self.textView.setContentOffset(CGPoint.zero, animated: false)
}
iosjillian
fuente
4
De todas las respuestas, esta es la que mejor funciona. Además, si el texto de UITextView comienza en algún lugar hacia el centro vertical de la vista de texto, agregar lo siguiente a viewDidLoad también lo solucionará: self.automaticallyAdjustsScrollViewInsets = false
Wizkid
Lo interesante es que la solución de offuttjillian funcionó para mí, pero la solución que me dieron @Wizkid y Glenn lo hace aún peor para mí en iOS 9.1. De todos modos, ahora está funcionando y eso me hace feliz ^^
Frozn
2
aunque esta es una solución que funciona, desafortunadamente tiene un gran efecto secundario: el desplazamiento ascendente visible y feo incluso si está utilizando viewWillLayoutSubviews: /
Hofi
Intentando casi 6 formas de resolver el problema, esta respuesta solo funcionó para mí en iOS9.x.
KoreanXcodeWorker
funciona bien incluso si se configura después de asignar texto para UITextView
Hassy
46

Esta es la única forma que funcionó para mí. Deshabilito el desplazamiento de UITextView antes de que se cargue la vista y luego lo habilito de nuevo:

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

    override func viewDidAppear(_ animated: Bool) {
        yourTextView.isScrollEnabled = true
    }
DanielZanchi
fuente
2
la mejor solución para tener el mínimo efecto visual visible del desplazamiento hacia arriba
Hofi
Funcionó bien para mí
thibaut noah
Tuve algunos problemas de desorden al desplazarme en el iPad al utilizar esa solución.
Aliens
27
[self.textView scrollRangeToVisible:NSMakeRange(0, 1)];

en viewDidLoad

Liuk Smith
fuente
19

Mediante programación antes de cargar el contenido, deshabilite la propiedad de desplazamiento de textview textview.scrollenabled = NO;

Y después de cargar, habilite el desplazamiento de la vista de texto textview.scrollenabled = YES;

Además, verifique XIB, siempre no verifique el desplazamiento habilitado de Textview.

Subathra D
fuente
muchas gracias, pero si tenemos este uitextview en collectionview o tableview no funcionará
Amr Angry
12

Las respuestas a la pregunta El espacio en blanco en la parte superior de UITextView en iOS 10 brindan una experiencia de usuario final mucho más limpia.

En viewDidLoadel controlador de vista que contiene la vista de texto:

 self.automaticallyAdjustsScrollViewInsets = false

La configuración textView.setContentOffset(CGPointMake(0,0), animated: false)y algunas de estas otras sugerencias funcionan cuando se llama en el, viewDidLayoutSubviews()pero en dispositivos más antiguos como iPad 2 y más antiguos, verá que el texto se desplaza cuando se muestra la pantalla. Eso no es algo que desee que vea el usuario final.

Glenn
fuente
4

Seguía teniendo problemas después de usar estas soluciones. El problema definitivamente parece estar relacionado con tener barras de navegación transparentes y seleccionar ajustar automáticamente las inserciones de contenido en el controlador de vista. Si no le importa que su texto se desplace debajo de la barra de navegación, es mejor dejar esta configuración desactivada y restringir la parte superior de su vista de texto a la parte inferior de la barra de navegación, en lugar de a la parte superior del controlador de vista.

Si, como yo, querías que apareciera debajo de tu barra de navegación cuando te desplazas hacia abajo; entonces la solución que funcionó para mí fue agregar esto.

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

Esto solo busca la altura de la barra de navegación y la barra de estado y ajusta el desplazamiento de contenido en consecuencia.

Tenga en cuenta que una desventaja de este enfoque es que cuando el dispositivo gira, terminará desplazándose hacia la parte superior.

Mark Bridges
fuente
Gracias, esto finalmente me llevó a la idea correcta :)
HannahCarney
4

Para mí funciona bien este código:

    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

Para desplazarse a la posición exacta y mostrarlo en la parte superior de la pantalla, uso este código:

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

La configuración de contentOffset.y se desplaza hasta el final del texto, y luego scrollRangeToVisible se desplaza hasta el valor de scrollToLocation. Por lo tanto, la posición necesaria aparece en la primera línea de scrollView.

Igor
fuente
4

Similar a algunas otras respuestas, pero con el beneficio adicional de que no provocará un desplazamiento hacia arriba en las rotaciones posteriores del dispositivo. Funciona bien en 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
}
danbretl
fuente
Después de probar algunas respuestas diferentes, esta funcionó mejor para mí. Según la respuesta de Swindler, puede usar CGPointZero para CGPoint.
Mitch Downey
Es importante hacer esto con este método: viewDidLayoutSubviews. Muchas respuestas te harán hacer esto en viewWillAppear, pero esto está mal. viewDidLayoutSubviews es el lugar para hacer esto. Gracias.
geekyaleks
3

Versión rápida

Se necesitará una combinación de cosas:

1.) Configura tu salida

  @IBOutlet var textView: UITextView!

2.) En el guión gráfico en el controlador de vista, desactive "Ajustar inserciones de vista de desplazamiento"

3.) Establezca el contenido en la parte superior cero agregando a continuación a su controlador de vista

override func viewWillLayoutSubviews() {
   super.viewWillLayoutSubviews()
     myUITextView.setContentOffset(CGPointZero, animated: false)
}
kelsheikh
fuente
'CGPointZero' no está disponible en Swift
ali
3

En lugar de configurar el desplazamiento de contenido de viewDidLayoutSubviews , puede escribir layoutIfNeeded desde viewDidLoad para establecer la posición adecuada de textview como se muestra a continuación:

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

Salud !!

Dhaval H. Nena
fuente
2

En Swift 2, la solución Xcode 7, para dejar el desplazamiento habilitado y para que el texto comience en la parte superior, esto es todo lo que necesita:

@IBOutlet weak var myUITextView: UITextView!

override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()
    //start scroll at top of text
    myUITextView.scrollRangeToVisible(NSMakeRange(0, 0))
}
Brian Ogden
fuente
1
¡Gracias! esto funcionó perfectamente para mí con Swift 2.2. Ninguna de las otras soluciones aquí funcionó de manera tan fluida y sencilla.
Natalia
2

Swift 3.0

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

override func viewDidAppear(_ animated: Bool) {
    privacyText.isScrollEnabled = true
}
MRustamzade
fuente
¡Desactive el desplazamiento en Storyboard! Y habilítelo en el código. anular func viewDidAppear (_ animado: Bool) {privacyText.isScrollEnabled = true}
Vitaliy A
2

¡Esto funcionó mejor para mí! Coloqué esto dentro de viewDidLoad ().

//TextView Scroll starts from the top
myTextView.contentOffset.y = 0
Madriguera
fuente
1
La expresión no es asignable.
Bhumesh Purohit
1

Aquí hay otra forma de hacerlo que siempre me funciona. C objetivo:

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

Y en Swift:

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

Versión rápida:

override func viewDidLayoutSubviews() {
    yourTextView.setContentOffset(CGPointZero, animated: false)
}
Rashwan L
fuente
1

agregue la siguiente función a su clase de controlador de vista ...

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
fuente
¿podría traducir la última oración al inglés?
Gilles Gouaillardet
1

en swift 4 con texto atribuido, cualquiera de las respuestas no me ayuda y combino algunas respuestas en el tema.

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)
}
hall.keskin
fuente
¿Qué pasa si uittextview está en la vista de colección o en la vista de tabla
Amr Angry
@AmrAngry no tengo idea, solo lo usé para la vista de texto
hall.keskin
gracias, uso tetxview.scrollRangeToVisible (NSMakeRange (0, 0))
Amr Angry
1

Solución rápida 3, 4, 5:

Pasos para solucionar el problema:

  • Deshabilitar el desplazamiento de UITextView
  • establecer scrollRectToVisible
  • habilitar el desplazamiento UITextView

Código:

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

Esto funcionó para mí. ¡Espero que te ayude!

Mohit Kumar
fuente
Gracias Mohit por una explicación práctica y sencilla.
Praveen Kumar Verma
0

Así es como lo hice. He subclasificado textview y:

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

override func layoutSubviews() {
    super.layoutSubviews()
    self.scrollEnabled = true
}
Víctor Tatarasanu
fuente
0

Desde el guión gráfico, seleccione el controlador de vista en el que ha colocado la vista de texto. En el inspector de atributos, desactive "Ajustar recuadros de vista de desplazamiento". Eso es.

Aftab Baig
fuente
0

Pon este código en tu clase

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

Agregar código a viewdidload

self.automaticallyAdjustsScrollViewInsets = NO;
Eva Hsueh
fuente