2015-03-07 6 views
6

मैं एक ऐप पर तेजी से काम कर रहा हूं। वर्तमान में, मैं कस्टम कक्षों के साथ तालिका दृश्य की आबादी पर काम कर रहा हूं, screenshot देखें। हालांकि, अभी मेरे पास टेक्स्ट सेट है ताकि शीर्षक बिल्कुल 2 लाइनें हो और सारांश बिल्कुल 3 लाइनें हो। ऐसा करके, पाठ को कभी-कभी छोटा कर दिया जाता है। अब, मैं शीर्षक में टेक्स्ट के लिए प्राथमिकता सेट करना चाहता हूं, ताकि अगर शीर्षक 2 लाइनों के समय छोटा हो जाए तो मैं इसे 3 लाइनों तक विस्तारित करता हूं और सारांश केवल 2 पंक्तियां बना देता हूं। मैंने ऑटो लेआउट के साथ ऐसा करने की कोशिश की, लेकिन असफल रहा। अब मैंने this और this के अनुसार निम्नलिखित दृष्टिकोण का प्रयास किया है, लेकिन नीचे दिया गया कार्य भी सटीक रूप से निर्धारित नहीं होता है कि पाठ छोटा हो गया है या नहीं।UILabel में ट्रंकेशन की जांच करें - आईओएस, स्विफ्ट

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 
    } 
} 

क्या कोई मदद कर सकता है? यह काम करने के लिए मैं अपना काम कैसे बदल सकता हूं? या विभिन्न ऑटो लेआउट बाधाओं के साथ काम करना चाहिए और कैसे? बहुत बहुत धन्यवाद!


संपादित करें: इस मेरे वर्तमान कोड है। कुछ ऑटो लेआउट स्टोरीबोर्ड किया जाता है, हालांकि बदलते ऑटो लेआउट को कोड में किया जाता है। आयात UIKit

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 

} 

उत्तर

10

आप लाइनों अपने UILabel है की संख्या प्राप्त करने NSString से sizeWithAttributes विधि का उपयोग कर सकते हैं। आप इस विधि का उपयोग करने के लिए NSString पहले करने के लिए अपने लेबल पाठ कास्ट करने के लिए करना होगा: क्योंकि अपने लेबल एक निश्चित चौड़ाई नहीं है इस विधि आप के लिए काम नहीं करता है

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 

} 

संपादित

, आप लेबल का आकार प्राप्त करने के लिए boundingRectWithSize का उपयोग कर सकते हैं और ceil विधि के साथ इसका उपयोग कर सकते हैं।

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

बहुत बहुत धन्यवाद, हालांकि विधि हमेशा मेरे लिए 1 लौटाती है। मुझे लगता है कि ऐसा इसलिए है क्योंकि कोई चौड़ाई निर्दिष्ट नहीं है। क्या आपके पास इसे हल करने का कोई तरीका है? –

+0

मैंने एक और संभावना जोड़ दी है। वहां आपको एक और फ़ंक्शन का उपयोग करना होगा। यह काम करना चाहिए। :) – Christian

+0

एचएम, धन्यवाद, कोड को काम करना चाहिए, लेकिन मुझे लगता है कि किसी भी तरह से मेरा ऑटो लेआउट इसके खिलाफ काम कर रहा है। इसे देखें [स्क्रीनशॉट] (https://www.dropbox.com/s/ioocjbziyfmkxu7/iOS%20Simulator%20Screen%20Shot%2008%20Mar%202015%2014.14.42.png?dl=0), जिसमें कुछ कक्ष अधिक जगह की आवश्यकता नहीं है और अधिक जगह आवंटित की जाती है और कुछ कोशिकाओं को अधिक जगह की आवश्यकता होती है जिन्हें अधिक जगह आवंटित नहीं की जाती है। मैंने जांच की है, और ऊंचाई की गणना करने के लिए फ़ंक्शन के साथ इसका कुछ संबंध है। शायद लेबल सीमाएं किसी भी तरह सटीक नहीं हैं? मैंने तालिका के दृश्य के लिए अपने मूल पोस्ट को अपने कोड के साथ संपादित किया है। आपकी सहायताके लिए धन्यवाद! –

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

यह केवल तभी काम करेगा जब लेबल लेआउट पास के साथ प्रस्तुत किया गया हो! – StackUnderflow

4

स्विफ्ट 3

एक सरल समाधान बताए के बाद लाइनों की संख्या की गणना कर रहा है स्ट्रिंग और लेबल की लाइनों की अधिकतम संख्या की तुलना करें।

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

यह केवल तभी काम करेगा जब लेबल लेआउट पास के साथ प्रस्तुत किया गया हो! – StackUnderflow

संबंधित मुद्दे