Lorsque j'ai un texte qui ne remplit pas UITextView, il défile vers le haut et fonctionne comme prévu. Lorsqu'il y a plus de texte que ce qui peut en contenir à l'écran, UITextView défile au centre du texte plutôt qu'au haut.
Voici quelques détails potentiellement pertinents:
Dans viewDidLoad pour donner un peu de remplissage en haut et en bas de UITextView:
self.mainTextView.textContainerInset = UIEdgeInsetsMake(90, 0, 70, 0);
UITextView utilise la mise en page automatique pour l'ancrer 20px du haut, du bas et de chaque côté de l'écran (en IB) afin de permettre différentes tailles et orientations d'écran.
Je peux toujours le faire défiler avec mon doigt une fois chargé.
EDIT J'ai constaté que le fait de supprimer les contraintes de mise en page automatique, puis de fixer la largeur, semble résoudre uniquement le problème, mais uniquement pour cette largeur d'écran.
UITextView est une sous-classe de UIScrollView, vous pouvez donc utiliser ses méthodes. Si tout ce que vous voulez faire est de vous assurer que le texte défile jusqu'en haut, alors, où que le texte soit ajouté, essayez:
[self.mainTextView setContentOffset:CGPointZero animated:NO];
EDIT: AutoLayout avec n'importe quel type de scrollview devient wickky rapidement. Ce réglage d'une largeur fixe résout, ce n'est pas surprenant. Si cela ne fonctionne pas dans -viewDidLayoutSubviews
, alors c'est étrange. La définition manuelle d’une contrainte d’agencement peut fonctionner. Créez d'abord les contraintes dans IB:
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *textViewWidthConstraint;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *textViewHeightConstraint;
puis dans le ViewController
-(void)updateViewConstraints {
self.textViewWidthConstraint.constant = self.view.frame.size.width - 40.0f;
self.textViewHeightConstraint.constant = self.view.frame.size.height - 40.0f;
[super updateViewConstraints];
}
Peut-être encore nécessaire de définirContentOffset dans -viewDidLayoutSubviews
.
(Une autre méthode consisterait à créer une contrainte de mise en page pour "'égales'" et "'égales" »entre textView et son superView, avec une constante de" -40 ". Elle n'est" égale "que si la constante est égale à zéro. sinon, la constante est ajustée, mais comme vous ne pouvez ajouter que cette contrainte à une vue qui contraint les deux vues, vous ne pouvez pas le faire dans IB.)
Vous pouvez vous demander, si je dois faire cela, à quoi sert AutoLayout? J'ai étudié AutoLayout en profondeur et c'est une excellente question.
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)
}
Objectif c
- (void)viewDidLayoutSubviews {
[self.mainTextView setContentOffset:CGPointZero animated:NO];
}
j'ai eu le même problème! Réinitialiser sur les contraintes suggérées et mettre juste (décalage y)
@IBOutlet weak var textContent: UITextView!
override func viewDidLoad() {
textContent.scrollsToTop = true
var contentHeight = textContent.contentSize.height
var offSet = textContent.contentOffset.x
var contentOffset = contentHeight - offSet
textContent.contentOffset = CGPointMake(0, -contentOffset)
}
Rapide
self.textView.scrollRangeToVisible(NSMakeRange(0, 0))
Objectif c
[self.textView scrollRangeToVisible:(NSMakeRange(0, 0))];
Pour iOS9 et les versions ultérieures, textview même sur viewWillAppear: arrive avec CGRect (0,0,1000,1000). Pour que cela fonctionne, vous devez appeler dans viewWillAppear:
[self.view setNeedsLayout];
[self.view layoutIfNeeded];
// * Your code here
Ensuite, textview disposera des données CGRect correctes et vous pourrez effectuer toutes les opérations de défilement dont vous pourriez avoir besoin.
Si vous ne voulez pas jouer avec les contraintes:
override func updateViewConstraints() {
super.updateViewConstraints()
}
override func viewDidLayoutSubviews() {
self.textLabel.setContentOffset(CGPointZero, animated: false)
}
Le problème avec l'insertion de code dans viewDidLayoutSubviews et viewWillLayoutSubviews est que ces méthodes s'appellent beaucoup (lors de la rotation du périphérique, du redimensionnement des vues, etc.). Si vous lisez quelque chose à partir de la vue texte et que vous faites pivoter l'appareil, vous vous attendez à ce que la partie du contenu que vous visualisez reste à l'écran. Vous ne vous attendez pas à ce que cela revienne au début. Au lieu de faire défiler le contenu vers le haut, essayez de conserver la propriété scrollEnabled de la vue texte sur NO (false), puis réactivez-la dans viewDidAppear.
C'est un bug intéressant. Dans notre projet, cela ne se produit que sur les appareils dotés d'un écran de taille iPhone 5
-. Il semble que textview contentOffset
change à un moment donné au cours du cycle de vie du contrôleur de vue. Dans viewDidLoad
et viewWillAppear
, la contentOffset
de textview est 0,0
et, par viewDidAppear
, elle a changé. Vous pouvez le voir se passer dans viewWillLayoutSubviews
. Les contraintes semblent être correctement configurées.
Cela garantira que vous n'appelez pas une méthode de défilement à moins que cela ne soit nécessaire:
if textView.contentOffset.y > 0 {
textView.contentOffset = CGPoint(x: 0, y: 0)
// Or use scrollRectToVisible, scrollRangeToVisible, etc.
}
Rapide
override func viewDidLoad() {
super.viewDidLoad()
textView.isScrollEnabled = false
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
textView.isScrollEnabled = true
}