2015-03-07 22 views
6

Hızlı bir şekilde bir uygulama üzerinde çalışıyorum. Şu anda, özel hücrelerle bir tablo görünümü popülasyonu üzerinde çalışıyorum, bkz. screenshot. Ancak, şu anda metin setine sahibim, başlık tam olarak 2 satır olacak ve özet tam olarak 3 satır. Bunu yaparak, metin bazen kesilir. Şimdi, başlıkta metin için önceliği ayarlamak istiyorum, böylece başlık 2 satır uzunluğunda kesilirse, onu 3 satıra genişletirim ve özeti yalnızca 2 satır yapar. Bunu otomatik düzende yapmayı denedim, ancak başarısız oldu. Şimdi, this ve this'a göre aşağıdaki yaklaşımı denedim, ancak aşağıdaki işlev, metnin kesilmiş olup olmadığını da doğru bir şekilde belirleyemedi.UILabel - iOS için Ayar Kontrolü, Swift

func isTruncated(label:UILabel) -> Bool { 
    let context = NSStringDrawingContext() 
    let text : NSAttributedString = NSAttributedString(string: label.text!, attributes: [NSFontAttributeName : label.font]) 

    let labelSize : CGSize = CGSize(width: label.frame.width, height: CGFloat.max) 


    let options : NSStringDrawingOptions = unsafeBitCast(NSStringDrawingOptions.UsesLineFragmentOrigin.rawValue | NSStringDrawingOptions.UsesFontLeading.rawValue, NSStringDrawingOptions.self) 

    let labelRect : CGRect = text.boundingRectWithSize(labelSize, options: options, context: context) 

    if Float(labelRect.height/label.font.lineHeight) > Float(label.numberOfLines) { 
     return true 
    } else { 
     return false 
    } 
} 

Herhangi biri yardımcı olabilir mi? Bu işi yapmak için işlevimi nasıl değiştirebilirim? Veya farklı otomatik yerleşim kısıtlamaları ile çalışmalı ve nasıl? Çok teşekkürler!


DÜZENLEME: bu benim şimdiki kodudur. Bazı otomatik mizanpajlar yapıldı, ancak storyboard değiştirildi, ancak değişen otomatik düzen kodda yapıldı. ithalat Sen UILabel sahiptir senin satır sayısını almak için NSString den sizeWithAttributes yöntemi kullanabilirsiniz

class FeedTableViewCell: UITableViewCell { 

var thumbnailImage = UIImageView() 

@IBOutlet var titleText: UILabel! 

@IBOutlet var summaryText: UILabel! 

@IBOutlet var sourceAndDateText: UILabel! 

var imgTitleConst = NSLayoutConstraint() 
var imgSummaryConst = NSLayoutConstraint() 
var imgDetailConst = NSLayoutConstraint() 

var titleConst = NSLayoutConstraint() 
var summaryConst = NSLayoutConstraint() 
var detailConst = NSLayoutConstraint() 

var titleHeightConst = NSLayoutConstraint() 
var summaryHeightConst = NSLayoutConstraint() 


var imageRemoved = false 
var titleConstAdd = false 
override func awakeFromNib() { 
    super.awakeFromNib() 
    thumbnailImage.clipsToBounds = true 
    summaryText.clipsToBounds = true 
    titleText.clipsToBounds = true 
    sourceAndDateText.clipsToBounds = true 
    addImage() 

} 

    func removeImage() { 
    if let viewToRemove = self.viewWithTag(123) { 
     imageRemoved = true 
     viewToRemove.removeFromSuperview() 
      self.contentView.removeConstraints([imgTitleConst, imgSummaryConst, imgDetailConst]) 
     titleConst = NSLayoutConstraint(item: self.titleText, attribute: NSLayoutAttribute.Left, relatedBy: NSLayoutRelation.Equal, toItem: self.contentView, attribute: NSLayoutAttribute.Left, multiplier: 1, constant: 14) 

     summaryConst = NSLayoutConstraint(item: summaryText, attribute: NSLayoutAttribute.Left, relatedBy: NSLayoutRelation.Equal, toItem: self.contentView, attribute: NSLayoutAttribute.Left, multiplier: 1, constant: 14) 

     detailConst = NSLayoutConstraint(item: sourceAndDateText, attribute: NSLayoutAttribute.Left, relatedBy: NSLayoutRelation.Equal, toItem: self.contentView, attribute: NSLayoutAttribute.Left, multiplier: 1, constant: 14) 

     self.contentView.addConstraints([titleConst, detailConst, summaryConst]) 
     setNumberOfLines() 
     self.contentView.layoutSubviews() 
    } 


} 

func addImage() { 
    thumbnailImage.tag = 123 
    thumbnailImage.image = UIImage(named: "placeholder") 
    thumbnailImage.frame = CGRectMake(14, 12, 100, 100) 
    thumbnailImage.contentMode = UIViewContentMode.ScaleAspectFill 
    thumbnailImage.clipsToBounds = true 
    self.contentView.addSubview(thumbnailImage) 

    if imageRemoved { 
     self.contentView.removeConstraints([titleConst, summaryConst, detailConst]) 
    } 


    var widthConst = NSLayoutConstraint(item: thumbnailImage, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: 100) 
    var heightConst = NSLayoutConstraint(item: thumbnailImage, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: 100) 
    var leftConst = NSLayoutConstraint(item: thumbnailImage, attribute: NSLayoutAttribute.Left, relatedBy: NSLayoutRelation.Equal, toItem: self.contentView, attribute: NSLayoutAttribute.Left, multiplier: 1, constant: 14) 
    var topConst = NSLayoutConstraint(item: thumbnailImage, attribute: NSLayoutAttribute.Top, relatedBy: NSLayoutRelation.Equal, toItem: self.contentView, attribute: NSLayoutAttribute.Top, multiplier: 1, constant: 12) 



     imgTitleConst = NSLayoutConstraint(item: self.titleText, attribute: NSLayoutAttribute.Left, relatedBy: NSLayoutRelation.Equal, toItem: self.thumbnailImage, attribute: NSLayoutAttribute.Right, multiplier: 1, constant: 8) 

    imgSummaryConst = NSLayoutConstraint(item: summaryText, attribute: NSLayoutAttribute.Left, relatedBy: NSLayoutRelation.Equal, toItem: self.thumbnailImage, attribute: NSLayoutAttribute.Right, multiplier: 1, constant: 8) 

    imgDetailConst = NSLayoutConstraint(item: sourceAndDateText, attribute: NSLayoutAttribute.Left, relatedBy: NSLayoutRelation.Equal, toItem: self.thumbnailImage, attribute: NSLayoutAttribute.Right, multiplier: 1, constant: 8) 


    self.contentView.addConstraints([widthConst, heightConst, leftConst, topConst, imgTitleConst, imgSummaryConst, imgDetailConst]) 
    setNumberOfLines() 
    self.contentView.layoutSubviews() 

} 




override func setSelected(selected: Bool, animated: Bool) { 
    super.setSelected(selected, animated: animated) 

    // Configure the view for the selected state 
} 

func setNumberOfLines() { 

    if titleConstAdd { 
     self.contentView.removeConstraints([titleHeightConst, summaryHeightConst]) 
    } 
    if titleText.numberOfLines == 3 { 
     titleText.numberOfLines = 2 
    } 
    if countLabelLines(titleText) > 2 { 
     titleText.numberOfLines = 3 
     summaryText.numberOfLines = 2 
     println("adjusting label heigh to be taller") 
     titleHeightConst = NSLayoutConstraint(item: titleText, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: 51) 
     summaryHeightConst = NSLayoutConstraint(item: summaryText, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: 32) 
     self.contentView.addConstraints([titleHeightConst, summaryHeightConst]) 
    } else { 
     titleText.numberOfLines = 2 
     summaryText.numberOfLines = 3 

     titleHeightConst = NSLayoutConstraint(item: titleText, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: 36) 
      summaryHeightConst = NSLayoutConstraint(item: summaryText, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: 47) 
     self.contentView.addConstraints([titleHeightConst, summaryHeightConst]) 
    } 

    titleConstAdd = true 


} 
} 


func countLabelLines(label:UILabel)->Int{ 

if let text = label.text{ 
    // cast text to NSString so we can use sizeWithAttributes 
    var myText = text as NSString 

    //Set attributes 
    var attributes = [NSFontAttributeName : UIFont.boldSystemFontOfSize(14)] 

    //Calculate the size of your UILabel by using the systemfont and the paragraph we created before. Edit the font and replace it with yours if you use another 

    var labelSize = myText.boundingRectWithSize(CGSizeMake(label.bounds.width, CGFloat.max), options: NSStringDrawingOptions.UsesLineFragmentOrigin, attributes: attributes, context: nil) 

    //Now we return the amount of lines using the ceil method 
    var lines = ceil(CGFloat(labelSize.height)/label.font.lineHeight) 
    println(labelSize.height) 
    println("\(lines)") 
    return Int(lines) 
} 

return 0 

} 

cevap

10

UIKit. Bu yöntemi kullanan ilk NSString için etiket metnini döküm gerekir: Bu yöntem işe yaramazsa etiket sabit bir genişliğe değil çünkü

func countLabelLines(label:UILabel)->Int{ 

    if let text = label.text{ 
     // cast text to NSString so we can use sizeWithAttributes 
     var myText = text as NSString 
     //A Paragraph that we use to set the lineBreakMode. 
     var paragraph = NSMutableParagraphStyle() 
     //Set the lineBreakMode to wordWrapping 
     paragraph.lineBreakMode = NSLineBreakMode.ByWordWrapping 

     //Calculate the size of your UILabel by using the systemfont and the paragraph we created before. Edit the font and replace it with yours if you use another 
     var labelSize = myText.sizeWithAttributes([NSFontAttributeName : UIFont.systemFontOfSize(17), NSParagraphStyleAttributeName : paragraph.copy()]) 

     //Now we return the amount of lines using the ceil method 
     var lines = ceil(CGFloat(size.height)/label.font.lineHeight) 
     return Int(lines) 
    } 

    return 0 

} 

Edit

, sen etiketin boyutunu almak için boundingRectWithSize'u kullanabilir ve bunu ceil yöntemiyle kullanabilirsiniz.

Bu sabit genişlikte etiket ve hat sabit sayıda ya da sabit bir yükseklikte için çalışır
func countLabelLines(label:UILabel)->Int{ 

    if let text = label.text{ 
     // cast text to NSString so we can use sizeWithAttributes 
     var myText = text as NSString 

     //Set attributes 
     var attributes = [NSFontAttributeName : UIFont.systemFontOfSize(UIFont.systemFontSize())] 

     //Calculate the size of your UILabel by using the systemfont and the paragraph we created before. Edit the font and replace it with yours if you use another 
     var labelSize = myText.boundingRectWithSize(CGSizeMake(label.bounds.width, CGFloat.max), options: NSStringDrawingOptions.UsesLineFragmentOrigin, attributes: attributes, context: nil) 

     //Now we return the amount of lines using the ceil method 
     var lines = ceil(CGFloat(labelSize.height)/label.font.lineHeight) 
     return Int(lines) 
    } 

    return 0 

} 
+0

Çok teşekkürler, ancak yöntem her zaman benim için 1 değerini döndürür. Bunun nedeni, belirtilen genişliğin olmamasıdır. Bunu çözmenin bir yolu var mı? –

+0

Başka bir olasılık daha ekledim. Orada başka bir işlev kullanmalısın. İşe yaramalı. :) – Christian

+0

Hm, teşekkürler, bu kod çalışmalı, ama bir şekilde otomatik düzenimin buna karşı çalıştığını düşünüyorum. Bazı hücrelerin kullanıldığı bu [ekran görüntüsü] 'ne (https://www.dropbox.com/s/ioocjbziyfmkxu7/iOS%20Simulator%20Screen%20Shot%2008%20Mar%202015%2014.14.42.png?dl=0) bakın. Daha fazla alana gerek yok daha fazla yer ayrılır ve daha fazla alana ihtiyaç duyan bazı hücreler daha fazla alan tahsis edilmez. Kontrol ettim ve yüksekliği hesaplamak için fonksiyonla ilgili bir şey var. Belki de etiket sınırları bir şekilde doğru değil mi? Orijinal gönderiimi tableView hücresi kodumla düzenledim. Yardım ettiğin için teşekkür ederim! –

2

:

extension UILabel { 
    func willBeTruncated() -> Bool { 
     let label:UILabel = UILabel(frame: CGRectMake(0, 0, self.bounds.width, CGFloat.max)) 
     label.numberOfLines = 0 
     label.lineBreakMode = NSLineBreakMode.ByWordWrapping 
     label.font = self.font 
     label.text = self.text 
     label.sizeToFit() 
     if label.frame.height > self.frame.height { 
      return true 
     } 
     return false 
    } 
} 
+0

Bu, yalnızca etiket yerleşim düzeni ile oluşturulmuşsa çalışacaktır! – StackUnderflow

4

Swift 3

basit bir çözüm ayrıldıktan sonra hat sayısını sayma dize ve etiketin maksimum satır sayısı ile karşılaştırın.

import Foundation 
import UIKit 

extension UILabel { 

    func countLabelLines() -> Int { 
     // Call self.layoutIfNeeded() if your view is uses auto layout 
     let myText = self.text! as NSString 
     let attributes = [NSFontAttributeName : self.font] 

     let labelSize = myText.boundingRect(with: CGSize(width: self.bounds.width, height: CGFloat.greatestFiniteMagnitude), options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes: attributes, context: nil) 
     return Int(ceil(CGFloat(labelSize.height)/self.font.lineHeight)) 
    } 

    func isTruncated() -> Bool { 

     if (self.countLabelLines() > self.numberOfLines) { 
      return true 
     } 
     return false 
    } 
} 
+0

Bu, yalnızca etiket yerleşim düzeni ile oluşturulmuşsa çalışacaktır! – StackUnderflow