web-dev-qa-db-fra.com

Le contenu textuel de UITextView ne commence pas par le haut

J'ai un long texte provenant de mon fichier JSON, mais lorsque je clique sur le lien de mon UITableViewCell pour accéder à ma page UIViewController, le texte UITextView charge le contenu de la chaîne, mais il n'affiche pas le contenu depuis le début et je dois faire défiler tout le contenu. le temps.

Ce que je dois faire?

76
Ornilo

J'ai eu le même problème et il a fallu que je règle le décalage du contenu dans viewDidLayoutSubviews pour que cela prenne effet. J'utilise ce code pour afficher du texte statique attribué.

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

Swift 3:

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    self.textView.setContentOffset(CGPoint.zero, animated: false)
}
151
iosjillian

C'est la seule façon qui a fonctionné pour moi. Je désactive le défilement du ITextView avant que la vue ne soit chargée, puis je l'active à nouveau:

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

    override func viewDidAppear(_ animated: Bool) {
        yourTextView.isScrollEnabled = true
    }
42
Danny182
[self.textView scrollRangeToVisible:NSMakeRange(0, 1)];

dans viewDidLoad

27
Liuk Smith

Avant de charger le contenu par programme, désactivez la propriété scrolling de textview textview.scrollenabled = NO;

Et après le chargement, activez le défilement de textview textview.scrollenabled = YES;

De même, vérifiez le XIB, ne cochez pas toujours le défilement activé de Textview.

18
appsign

Les réponses à la question L'espace vide en haut de UITextView dans iOS 1 offre une expérience beaucoup plus propre à l'utilisateur final.

Dans viewDidLoad du contrôleur de vue contenant la vue texte:

 self.automaticallyAdjustsScrollViewInsets = false

Le réglage de textView.setContentOffset(CGPointMake(0,0), animated: false) et de certaines de ces autres suggestions fonctionne bien lorsqu'il est appelé dans viewDidLayoutSubviews(), mais sur les appareils plus anciens comme iPad 2 et les versions antérieures, le texte défile lorsque l'écran est affiché. Ce n'est pas quelque chose que vous voulez que l'utilisateur final voie.

12
Glenn

J'avais toujours des problèmes après avoir utilisé ces solutions. Le problème semble clairement lié à la présence de barres de navigation transparentes et au choix d'ajuster automatiquement les encarts de contenu sur le contrôleur de vue. Si vous ne vous souciez pas de votre défilement de texte sous la barre de navigation, il est préférable de laisser ces paramètres désactivés et de contraindre le haut de votre affichage de texte au bas de la barre de navigation plutôt qu'au sommet du contrôleur de vue.

Si comme moi, vous vouliez qu'il apparaisse sous votre barre de navigation lorsque vous faites défiler l'écran; alors la solution qui a fonctionné pour moi a été d'ajouter ceci.

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

Ceci ne fait que rechercher la hauteur de la barre de navigation et de la barre d'état et ajuste le décalage du contenu en conséquence.

Notez que l'un des inconvénients de cette approche est que, lorsque l'appareil tourne, vous finissez par revenir au début.

4
Mark Bridges

Semblable à d’autres réponses, mais avec l’avantage supplémentaire de ne pas faire défiler vers le haut les rotations de périphériques suivantes. Fonctionne bien dans 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
}
4
danbretl

Pour moi fonctionne bien ce code:

    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

Pour faire défiler jusqu'à la position exacte et l'afficher en haut de l'écran, j'utilise ce code:

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

La définition de contentOffset.y fait défiler jusqu'à la fin du texte, puis scrollRangeToVisible défile jusqu'à la valeur de scrollToLocation. Ainsi, la position nécessaire apparaît dans la première ligne de scrollView.

4
Igor

Version Swift

Une combinaison de choses sera nécessaire:

1.) Définissez votre sortie

  @IBOutlet var textView: UITextView!

2.) Dans le storyboard de View Controller, désactivez "Ajuster les inserts de la vue de défilement".

3.) Définissez le contenu à zéro en ajoutant ci-dessous à votre contrôleur de vue

override func viewWillLayoutSubviews() {
   super.viewWillLayoutSubviews()
     myUITextView.setContentOffset(CGPointZero, animated: false)
}
3
kelsheikh

Au lieu de définir un décalage de contenu de viewDidLayoutSubviews, vous pouvez écrire layoutIfNeeded à partir de viewDidLoad pour définir la position correcte de textview comme ci-dessous:

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

À votre santé !!

3
Dhaval H. Nena

Cela a fonctionné le mieux pour moi! J'ai placé ceci dans viewDidLoad ().

//TextView Scroll starts from the top
myTextView.contentOffset.y = 0
2
Warren

Swift 3.0

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

override func viewDidAppear(_ animated: Bool) {
    privacyText.isScrollEnabled = true
}
2
MRustamzade

Dans Swift 2, solution Xcode 7, laisser scroll Enabled et faire commencer le texte par le haut, c’est tout ce dont vous avez besoin:

@IBOutlet weak var myUITextView: UITextView!

override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()
    //start scroll at top of text
    myUITextView.scrollRangeToVisible(NSMakeRange(0, 0))
}
2
Brian Ogden

étapes à résoudre

  • Désactiver la vue de défilement UITextView
  • set scrollRectToVisible Enable
  • Défilement UITextView

Swift 3:

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

Cela a fonctionné pour moi.

1
Mohit Kumar

Version rapide:

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

in Swift 4 avec un texte attribué n’importe quelle réponse ne m’aide pas et je combine quelques réponses dans un sujet.

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)
}
1
hall.keskin

Voici une autre façon de le faire qui fonctionne toujours pour moi. Objectif c:

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

Et à Swift:

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

ajoutez la fonction suivante à votre classe de contrôleur de vue ...

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 一

1
myj

Mettez ce code sur votre classe

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

Voici comment je l'ai fait. J'ai sous-classé textview et:

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

override func layoutSubviews() {
    super.layoutSubviews()
    self.scrollEnabled = true
}
0

Dans le storyboard, sélectionnez le contrôleur de vue sur lequel vous avez placé la vue de texte. Dans l'inspecteur d'attributs, décochez la case "Ajuster les encarts de la vue de défilement". C'est ça.

0
Aftab Baig