web-dev-qa-db-fra.com

comment rendre UITextView height dynamique en fonction de la longueur du texte?

Comme vous pouvez le voir sur cette image

le UITextView change sa hauteur en fonction de la longueur du texte, je veux lui faire ajuster sa hauteur en fonction de la longueur du texte.

* J'ai vu d'autres questions, mais les solutions n'y ont pas fonctionné

 example

29
DeyaEldeen

this Works pour moi, toutes les autres solutions ne fonctionnaient pas.

func adjustUITextViewHeight(arg : UITextView)
{
    arg.translatesAutoresizingMaskIntoConstraints = true
    arg.sizeToFit()
    arg.scrollEnabled = false
}

Dans Swift 4, la syntaxe de arg.scrollEnabled = false a été remplacée par arg.isScrollEnabled = false.

74
DeyaEldeen

Essayez ceci:

CGRect frame = self.textView.frame;
frame.size.height = self.textView.contentSize.height;
self.textView.frame = frame;

Edit- Voici le Swift:

var frame = self.textView.frame
frame.size.height = self.textView.contentSize.height
self.textView.frame = frame
14
John Farkerson

Dans Storyboard/Interface Builder, désactivez simplement le défilement dans l'inspecteur d'attributs.

Dans le code textField.isScrollEnabled = false devrait faire l'affaire.

10
Tum

Suivi de la réponse de DeyaEldeen. 
Dans mon cas. Je cultive la hauteur de la vue texte automatiquement en ajoutant 

Swift 3 

textView.translatesAutoresizingMaskIntoConstraints = false textView.isScrollEnabled = false

9
Brady Huang

Swift 4

Ajoutez-le à votre classe 

UITextViewDelegate

func textViewDidChange(_ textView: UITextView) {
      let fixedWidth = textView.frame.size.width
      textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.greatestFiniteMagnitude))
      let newSize = textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.greatestFiniteMagnitude))
      var newFrame = textView.frame
      newFrame.size = CGSize(width: max(newSize.width, fixedWidth), height: newSize.height)
      textView.frame = newFrame
}
7
ZAFAR007

c'est simple à faire de manière programmatique. il suffit de suivre ces étapes

  1. ajouter un observateur à la longueur du contenu du champ de texte

    [yourTextViewObject addObserver:self forKeyPath:@"contentSize" options:(NSKeyValueObservingOptionNew) context:NULL];
    
  2. observer l'observateur

    -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    UITextView *tv = object;
    
        //Center vertical alignment
        CGFloat topCorrect = ([tv bounds].size.height - [tv contentSize].height * [tv zoomScale])/2.0;
        topCorrect = ( topCorrect < 0.0 ? 0.0 : topCorrect );
        tv.contentOffset = (CGPoint){.x = 0, .y = -topCorrect};
    
    
        mTextViewHeightConstraint.constant = tv.contentSize.height;
    
        [UIView animateWithDuration:0.2 animations:^{
    
            [self.view layoutIfNeeded];
        }];
    
    }
    
  3. si vous voulez que textviewHeight cesse d'augmenter après un certain temps pendant la frappe, mettez-le en œuvre et définissez délégué délégué textview sur self.

    -(BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
    {
        if(range.length + range.location > textView.text.length)
        {
            return NO;
        }
    
        NSUInteger newLength = [textView.text length] + [text length] - range.length;
    
        return (newLength > 100) ? NO : YES;
    
    }
    
2
Shaik Riyaz

il suffit de faire une connexion avec la contrainte de hauteur de votre textView 

@IBOutlet var textView: UITextView!
@IBOutlet var textViewHeightConstraint: NSLayoutConstraint!

et utilisez ce code ci-dessous 

textViewHeightConstraint.constant = self.textView.contentSize.height
2
Rishabh Shukla

Swift 4

Changer la taille en tapant

UITextViewDelegate

func textViewDidChange(_ textView: UITextView) {
        yourTextView.translatesAutoresizingMaskIntoConstraints = true
        yourTextView.sizeToFit()
        yourTextView.isScrollEnabled = false

        let calHeight = yourTextView.frame.size.height
        yourTextView.frame = CGRect(x: 16, y: 193, width: self.view.frame.size.width - 32, height: calHeight)
    }

Changer la taille en charge

func textViewNotasChange(arg : UITextView) {
        arg.translatesAutoresizingMaskIntoConstraints = true
        arg.sizeToFit()
        arg.isScrollEnabled = false

        let calHeight = arg.frame.size.height
        arg.frame = CGRect(x: 16, y: 40, width: self.view.frame.size.width - 32, height: calHeight)
    }

Appelez la fonction de la deuxième option comme ceci:

textViewNotasChange(arg: yourTextView)
1
oscar castellon

ça marche

func textViewDidChange(_ textView: UITextView) {
    let fixedWidth = textviewconclusion.frame.size.width
    textviewconclusion.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.greatestFiniteMagnitude))
    let newSize = textviewconclusion.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.greatestFiniteMagnitude))
    var newFrame = textviewconclusion.frame
    newFrame.size = CGSize(width: max(newSize.width, fixedWidth), height: newSize.height)
    textviewconclusion.frame = newFrame
}
1
OneTeam

Dans mon projet, le contrôleur de vue est impliqué dans de nombreuses contraintes et StackView, et je règle la hauteur de TextView en tant que contrainte. Elle varie en fonction de la valeur textView.contentSize.height.

step1: obtenir un point de vente IB 

@IBOutlet weak var textViewHeight: NSLayoutConstraint!

step2: utilisez la méthode de délégation ci-dessous.

extension NewPostViewController: UITextViewDelegate {
     func textViewDidChange(_ textView: UITextView) {
          textViewHeight.constant = self.textView.contentSize.height + 10
     }
}
1
De Zheng

1 Ajouter un observateur à la longueur du contenu du champ de texte

   yourTextView.addObserver(self, forKeyPath: "contentSize", options: (NSKeyValueObservingOptions.new), context: nil);

2 Observateur de la mise en œuvre

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        let tv = object as! UITextView;
        var topCorrect = (tv.bounds.size.height - tv.contentSize.height * tv.zoomScale)/2.0;
        topCorrect = ( topCorrect < 0.0 ? 0.0 : topCorrect );
        tv.contentOffset.x = 0;
        tv.contentOffset.y = -topCorrect;
        self.yourTextView.contentSize.height = tv.contentSize.height;
        UIView.animate(withDuration: 0.2, animations: {
            self.view.layoutIfNeeded();
        });
    }
0
Sachin Nikumbh

Voici deux pièges dans iOS 8.3 lors de l’arrivée de textView.textContainer.maximumNumberOfLines = 10

Reportez-vous à mon Gist , s'il vous plaît.

textView.attributedText = originalContent

let lineLimit = 10
textView.isEditable = true
textView.isScrollEnabled = false
textView.textContainerInset = .zero // default is (8, 0, 8, 0)
textView.textContainer.maximumNumberOfLines = lineLimit // Important condition
textView.textContainer.lineBreakMode = .byTruncatingTail

// two incomplete methods, which do NOT work in iOS 8.3

// size.width可能比maxSize.width小 ————遗憾的是 iOS 8.3 上此方法无视maximumNumberOfLines参数,所以得借助于UILabel
// size.width may be less than maxSize.width, ---- Do NOT work in iOS 8.3, which disregards textView.textContainer.maximumNumberOfLines
// let size = textView.sizeThatFits(maxSize) 

// 遗憾的是 iOS 8.3 上此方法失效了,得借助于UILabel
// Does not work in iOS 8.3
// let size = textView.layoutManager.usedRectForTextContainer(textView.textContainer).size 

// Suggested method: use a temperary label to get its size
let label = UILabel(); label.attributedText = originalContent
let size = label.textRect(forBounds: CGRect(Origin: .zero, size: maxSize), limitedToNumberOfLines: lineLimit).size
textView.frame.size = size
0
DawnSong

Vous pouvez le faire avec IB.

  1. Créer un débouché à partir de la contrainte de hauteur UITextView .  enter image description here

  2. Hériter de votre UIViewController de UITextViewDelegate

  3. Ensuite

`

func textViewDidChange(_ textView: UITextView) {

    // calculate text height
    let constraintRect = CGSize(width: textView.frame.width,
                                height: .greatestFiniteMagnitude)
    let boundingBox = self.boundingRect(with: constraintRect,
                                        options: .usesLineFragmentOrigin,
                                        attributes: [.font: textView.font],
                                        context: nil)
    let height = ceil(boundingBox.height)

    // textViewHeightConstraint - your height constraint outlet from IB
    if height > textViewHeightConstraint.constant {
        textViewHeightConstraint.constant = height

        UIView.animate(withDuration: 0.3, animations: {
            self.view.layoutIfNeeded()
        })
    }
}`
0
Booharin

Mieux encore Swift 4 ajouter comme extension:

extension UITextView {
    func resizeForHeight(){
        self.translatesAutoresizingMaskIntoConstraints = true
        self.sizeToFit()
        self.isScrollEnabled = false
    }
}
0
Alex Bailey