2017-08-30 1 views
4

Ich habe derzeit die folgende Erweiterung auf UITextField, um das Bounding Rect für eine gegebene Zeichenfolge zu berechnen.UITextView's boundingRect funktioniert nicht richtig

func widthHeight(font: UIFont) -> CGRect { 
    let constraintRect = CGSize(width: 200, height: 1000) 
    let boundingBox = self.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [NSFontAttributeName: font], context: nil) 
    return boundingBox 
} 

Die Breite für constraintRect ist die maximale Breite I für die Box zulassen möchten.

stelle ich die Werte und die Zellen wie folgt aus:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 
    if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuse, for: indexPath) as? ChatCollectionViewCell { 

     let text = self.chatLog[indexPath.row].text 
     cell.chatTextView.text = text 

     cell.chatViewWidth = (text?.widthHeight(font: UIFont.systemFont(ofSize: 16)).width)! 

     return cell 
    } 
    return UICollectionViewCell() 
} 

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { 
    if let text = self.chatLog[indexPath.row].text {    
     let box = text.widthHeight(font: UIFont.systemFont(ofSize: 16)) 
     return CGSize(width: view.frame.width, height: box.height + 10) 
    } 
    return CGSize(width: self.view.frame.width, height: 60) 
} 

Wenn dieser Code ausgeführt wird, werde ich massiv verkalkuliert Zellgrößen: enter image description here

Wie Sie sehr verwirrt sehen können, werden die Rahmen Sicht oben. Die erste Zeile ist "Heya", die zweite Zeile ist "Wie läuft das Leben so weit" und die dritte Zeile ist "Ich bin ein Hefter, du bist ein Lehrbuch." Manche Zellen sind zu eng, manche Zellen sind zu breit.

Hier einige zusätzliche Code für meine benutzerdefinierte collectionViewCell:

override init(frame: CGRect) { 
    super.init(frame: frame) 

    setupViews() 
} 

override func layoutSubviews() { 

    chatView.frame = CGRect(x: 0, y: 0, width: chatViewWidth, height: frame.height) 
    chatTextView.frame = CGRect(x: chatView.frame.origin.x + 10, y: 0, width: chatView.frame.width - 20, height: chatView.frame.height) 
} 

func setupViews() {  

    if isTextFromCurrentUser { 
     chatTextView.frame = CGRect(x: 10, y: 0, width: frame.width - 140, height: frame.height) 
     chatTextView.backgroundColor = .white 
    } else { 
     chatTextView.frame = CGRect(x: frame.width - 150, y: 0, width: frame.width - 140, height: frame.height) 
     chatTextView.backgroundColor = .blue 
    } 

    chatTextView.font = UIFont.systemFont(ofSize: 16) 
    chatTextView.layer.cornerRadius = 9 
    chatTextView.clipsToBounds = true 
    chatTextView.autoresizingMask = UIViewAutoresizing.flexibleHeight 
    chatTextView.isScrollEnabled = false 

    contentView.addSubview(chatView) 
    contentView.addSubview(chatTextView) 
} 
+2

'widthHeight (...)' ist sicherlich ein seltsamer Name für ein Verfahren, das im wesentlichen eine ** Größe liefert ** ... :-) –

Antwort

1

Chemo,

Wie ich es ein Chat-Blase glauben, an die Sie für die Höhe zu setzen versuchen und Chat-Blase kann nicht jede Scroll haben Vergewissern Sie sich, dass die scrollleiste von textView deaktiviert ist.

Zweite als Chat-Blase sollte ihre Höhe erhöhen basierend auf dem Inhalt und es gibt keine Höhenbegrenzung Verwendung CGFloat.greatestFiniteMagnitude wie möglich Höhe, die Sie aufnehmen können, während boundingRect Berechnung

func widthHeight(font: UIFont) -> CGRect { 
    let constraintRect = CGSize(width: 200, height: CGFloat.greatestFiniteMagnitude) 
    let boundingBox = self.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [NSFontAttributeName: font], context: nil) 
    return boundingBox 
} 

Schließlich stellen Sie sicher, es gibt keine contentInset Satz der Textvorschau. Wenn contentInset als links 5 und rechts 5 eingestellt sind, ziehen Sie 10 (5 + 5) von der maximalen Breite ab, die Sie aufnehmen können.

Da Höhe ist die einzige Variable hier in Gleichung Einstellung Breite ist genau der Schlüssel, um die richtige Höhe zu bekommen. Stellen Sie sicher, dass Sie die Zeilenoptionen richtig mit der Eigenschaft textViews übereinstimmen.

Vorschlag:

UITableView kann Verwendung automatischer Höhe für die Zelle machen und auf Textview Scroll deaktivieren Einstellung macht Textview seine Größe zu berechnen, basierend auf dem Text. Ich meine, TextView wird die implizite Größe respektieren.

Da ich glaube, dass Sie eine Chat-App erstellen, wo jede Blase eine Zelle ist, erwägen Sie vernünftigere Option der Verwendung von UITableView und nutzen Sie den Vorteil der automatischen Zellenhöhe und dann summieren mit CollectionView, die Sie die Größe für jeden Artikel zur Verfügung stellt manuell.

Prise Tipps: D

Ich habe persönlich verwendet rect begrenzt und verwalten die genaue Höhe Methode für Text nach Lasten von Versuch und Irrtum zu berechnen. Ich persönlich schlage vor, eine textView-Instanz zu erstellen, deren Eigenschaft genau der Eigenschaft von textView in Ihrem Storyboard entspricht und dann den Text, den Sie anzeigen möchten, zu setzen und sizeThatFits zu verwenden, um die tatsächliche Größe von textView zu erhalten.

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { 
     let textView = UITextView(frame: CGRect.zero) 
     //set textView property here 
     textView.text = self.chatLog[indexPath.row].text 
     let size = textView.sizeThatFits(CGSize(width: textView.bounds.width, height: CGFloat.greatestFiniteMagnitude)) 
     return size; 
} 
+0

Yesss es Ihnen danken! Ich wechselte schließlich zu NSLayoutConstraints, die die Dinge klarer machten, und UidGeinsets haben definitiv alles vermasselt. – chemo

+0

@chemo: bin froh, dass Sie das Problem Kumpel gelöst :) Happy Coding und immer willkommen –