Dans mon contrôleur de vue, j'ai une UITextView. Ce textview est rempli avec une chaîne. La chaîne peut être courte ou longue. En fonction de la longueur de la chaîne, la hauteur de la vue de texte doit être ajustée… .. J'utilise des storyboards et une mise en page automatique.
J'ai quelques problèmes avec la hauteur de la vue de texte.
Parfois, la hauteur est parfaitement adaptée au texte. Parfois, non, le texte est recadré sur la première ligne. En bas, la vue texte est jaune. le bleu est un conteneur dans une vue à défilement. Le violet est l'endroit idéal pour une photo.
Les textes proviennent de ma base de données principale, ce sont des attributs de chaîne. Entre l'écran 1 et 2, la seule chose qui a changé est la chaîne.
Si j'imprime les chaînes dans la console, j'ai les textes corrects:
my amazing new title
Another funny title for demo
Les contraintes de ma textview:
Je ne comprends pas pourquoi j'ai 2 affichages différents.
MODIFIER
J'ai essayé le conseil @Nate, dans viewDidLoad, j'ai ajouté:
myTextViewTitle.text="my amazing new title"
myTextViewTitle.setContentHuggingPriority(1000, forAxis: UILayoutConstraintAxis.Vertical)
myTextViewTitle.setContentCompressionResistancePriority(1000, forAxis: UILayoutConstraintAxis.Vertical)
myTextViewTitle.setTranslatesAutoresizingMaskIntoConstraints(false)
let views = ["new_view": myTextViewTitle]
var constrs = NSLayoutConstraint.constraintsWithVisualFormat("|-8-[new_view]-8-|", options: NSLayoutFormatOptions(0), metrics: nil, views: views)
self.view.addConstraints(constrs)
self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-8-[new_view]", options: NSLayoutFormatOptions(0), metrics: nil, views: views))
self.myTextViewTitle.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:[new_view(220@300)]", options: NSLayoutFormatOptions(0), metrics: nil, views: views))
Aucun résultat. Avec ou sans contrainte de hauteur ajoutée pour ma visualisation de texte dans le constructeur d'interface ...
EDIT 2
J'ai besoin d'un UITextView et non d'un UIlabel, à cause du bouton Précédent, pour utiliser un chemin d'exclusion.
let exclusionPathBack:UIBezierPath = UIBezierPath(rect: CGRect(x:backButton.bounds.Origin.x, y:backButton.bounds.Origin.y, width:backButton.bounds.width+10, height:backButton.bounds.height))
myTextViewTitle.textContainer.exclusionPaths=[exclusionPathBack]
J'ai trouvé une solution.
Je me suis concentré sur la hauteur de mon UITextView, puis j'ai lu un article sur le rapport hauteur/largeur. Je voulais essayer et ça a fonctionné!
Donc, dans le storyboard, j'ai ajouté un rapport d'aspect pour la vue texte et j'ai coché l'option "Supprimer au moment de la construction".
Dans viewDidLayoutSubviews (), j'ai écrit:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
let contentSize = self.myTextViewTitle.sizeThatFits(self.myTextViewTitle.bounds.size)
var frame = self.myTextViewTitle.frame
frame.size.height = contentSize.height
self.myTextViewTitle.frame = frame
aspectRatioTextViewConstraint = NSLayoutConstraint(item: self.myTextViewTitle, attribute: .Height, relatedBy: .Equal, toItem: self.myTextViewTitle, attribute: .Width, multiplier: myTextViewTitle.bounds.height/myTextViewTitle.bounds.width, constant: 1)
self.myTextViewTitle.addConstraint(aspectRatioTextViewConstraint!)
}
Ça fonctionne parfaitement.
Commencez par désactiver le défilement . De UITextView. Deux options:
Créez un UITextView et connectez-le avec IBOutlet (TextView). Ajoutez une contrainte de hauteur UITextView avec une hauteur par défaut, connectez-la avec IBOutlet (TextViewHeightConstraint). Lorsque vous définissez le texte de votre UITextView de manière asynchrone, vous devez calculer la hauteur de UITextView et lui attribuer la contrainte de hauteur.
CGSize sizeThatFitsTextView = [TextView sizeThatFits:CGSizeMake(TextView.frame.size.width, MAXFLOAT)];
TextViewHeightConstraint.constant = sizeThatFitsTextView.height;
Dans Swift 3.0, où tvHeightConstraint est la contrainte de hauteur du sujet TextView (si vous l'utilisez pour plusieurs vues de texte, l'ajouter aux entrées de fonction):
func textViewDidChange(textView: UITextView) {
let size = textView.sizeThatFits(CGSize(width: textView.frame.size.width, height: CGFloat.greatestFiniteMagnitude))
if size.height != tvHeightConstraint.constant && size.height > textView.frame.size.height{
tvHeightConstraint.constant = size.height
textView.setContentOffset(CGPoint.zero, animated: false)
}
}
H/T à @cmi et @Pablo Ruan
Dans Swift 2.3:
func textViewDidChange(textView: UITextView) {
let size = textView.sizeThatFits(CGSize(width: textView.frame.size.width, height: CGFloat.max))
if size.height != TXV_Height.constant && size.height > textView.frame.size.height{
TXV_Height.constant = size.height
textView.setContentOffset(CGPointZero, animated: false)
}
}
J'ai adapté votre code et je l'ai utilisé pour les deux: layout subview et textViewDidChange. Merci beaucoup d'avoir fait ma journée après une heure de dépannage ...
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
textViewDidChange(self.recordingTitleTV)
}
func textViewDidChange(_ textView: UITextView) {
let contentSize = textView.sizeThatFits(textView.bounds.size)
var frame = textView.frame
frame.size.height = contentSize.height
textView.frame = frame
let aspectRatioTextViewConstraint = NSLayoutConstraint(item: textView, attribute: .height, relatedBy: .equal, toItem: textView, attribute: .width, multiplier: textView.bounds.height/textView.bounds.width, constant: 1)
textView.addConstraint(aspectRatioTextViewConstraint)
}
Ma solution simple à un problème extrêmement similaire:
J'ai utilisé des étiquettes avec le nombre de lignes défini sur 0 au lieu d'essayer d'utiliser des champs de texte ou des vues. Ensuite, j'ai coupé les bords d'attaque et de fuite dans les conteneurs des étiquettes, ce qui limite leur largeur dans mon cas, avec la constante 0 pour les contraintes. Le problème est de définir le nombre de lignes sur 0 pour permettre aux étiquettes de se développer ou de se réduire en fonction de leur contenu. Le texte n'est jamais coupé et la hauteur des étiquettes ne dépasse jamais leur contenu pour toutes les classes de taille que j'ai configurées pour les largeurs (les largeurs de conteneur dans mon cas). Testé pour IOS 8.0 et versions ultérieures (assurez-vous également que la case "explicite" n'est pas cochée en regard des attributs "Largeur préférée" pour toutes les étiquettes pour les largeurs d'étiquette à ajuster pour différentes classes de taille) - fonctionne parfaitement
Pourquoi ne pas avoir une image pour le bouton de retour et un UILabel pour votre texte et utiliser autolayout pour les positionner? Et peut-être une troisième vue pour le fond jaune.