Find the number of characters that fit into a UITextView with a constant width and height with a given string?

In my application, I need to set Read more to the text view if the text input is large. My approach is to find a range of strings that will fit into the text view and add See More to it.Is there is any way to achieve this in Swift. The requirement is to emulate the “read more” parameter in order to display the full text in detail in a panel like facebook.

+7
ios swift nsstring uitextview nsrange
source share
3 answers

The function you are looking for is CTFramesetterSuggestFrameSizeWithConstraints . In essence, this allows you to find out the number of characters that correspond to a specific frame. You can use this number to turn off the current text and insert a button.

I wrote an implementation of this function for a subclass of UILabel:

 - (NSInteger)numberOfCharactersThatFitLabel { // Create an 'CTFramesetterRef' from an attributed string CTFontRef fontRef = CTFontCreateWithName((CFStringRef)self.font.fontName, self.font.pointSize, NULL); NSDictionary *attributes = [NSDictionary dictionaryWithObject:(__bridge id)fontRef forKey:(id)kCTFontAttributeName]; CFRelease(fontRef); NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:self.text attributes:attributes]; CTFramesetterRef frameSetterRef = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)attributedString); // Get a suggested character count that would fit the attributed string CFRange characterFitRange; CTFramesetterSuggestFrameSizeWithConstraints(frameSetterRef, CFRangeMake(0,0), NULL, CGSizeMake(self.bounds.size.width, self.numberOfLines*self.font.lineHeight), &characterFitRange); CFRelease(frameSetterRef); return (NSInteger)characterFitRange.length; } 

Here is a bug post for the full implementation of cutting off random text to a specified number of lines and adding the text “see more” to it.

+6
source share

This is a bit complicated because some letters are wider than others. But you can check the line width using sizeWithAttributes -method:

 var yourString: String = textField.text let myString: NSString = originalString as NSString //Set your font and add attributes if needed. let stringSize: CGSize = myString.sizeWithAttributes([NSFontAttributeName: yourFont]) 

Now you get CGSize, and you can check if the width of your text field is wider.

 if(sizeOfYourTextfield < stringSize){ //String is too large for your UITextField } 
+2
source share

Rough quick translation kgaidis great answer.

 extension UILabel { func numberOfCharactersThatFitLabel() -> Int { let fontRef = CTFontCreateWithName(self.font.fontName as CFStringRef, self.font.pointSize, nil) let attributes = NSDictionary(dictionary: [kCTFontAttributeName : fontRef]) let attributeString = NSAttributedString(string: text!, attributes: attributes as? [String : AnyObject]) let frameSetterRef = CTFramesetterCreateWithAttributedString(attributeString as CFAttributedStringRef) var characterFitRange:CFRange CTFramesetterSuggestFrameSizeWithConstraints(frameSetterRef, CFRangeMake(0, 0), nil, CGSizeMake(bounds.size.width, CGFloat(numberOfLines)*font.lineHeight), &characterFitRange) return characterFitRange.length } } 
+2
source share

All Articles