使用给定字符串查找具有恒定宽度和高度的UITextView中的字符数?

时间:2015-01-22 07:20:25

标签: ios swift nsstring uitextview nsrange

在我的应用程序中,如果文本输入很大,我需要在文本视图中设置Read more。所以我的方法是找到适合文本视图的字符串范围并附加查看更多信息。有什么办法吗?在Swift中实现它。要求是模拟阅读更多选项,以便像Facebook一样在详细视图中显示完整的文本。

4 个答案:

答案 0 :(得分:6)

您正在寻找的功能是CTFramesetterSuggestFrameSizeWithConstraints。从本质上讲,它允许您找出适合某个帧的字符数。您可以使用该编号剪切当前文本并插入按钮。

我为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's a bog post完全实现将随机文本剪切为指定行数并向其添加“查看更多”文本。

答案 1 :(得分:2)

这有点复杂,因为有些字母比其他字母宽。但您可以使用sizeWithAttributes - 方法检查字符串的宽度:

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])

现在您收到一个CGSize,您可以检查宽度是否比文本字段宽。

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

答案 2 :(得分:2)

kgaidis优秀答案的粗略翻译。

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

答案 3 :(得分:1)

这是Swift 4 UITextView扩展名

extension UITextView {

    func numberOfCharactersThatFitTextView() -> Int {
        let fontRef = CTFontCreateWithName(font!.fontName as CFString, font!.pointSize, nil)
        let attributes = [kCTFontAttributeName : fontRef]
        let attributedString = NSAttributedString(string: text!, attributes: attributes as [NSAttributedStringKey : Any])
        let frameSetterRef = CTFramesetterCreateWithAttributedString(attributedString as CFAttributedString)

        var characterFitRange: CFRange = CFRange()

        CTFramesetterSuggestFrameSizeWithConstraints(frameSetterRef, CFRangeMake(0, 0), nil, CGSize(width: bounds.size.width, height: bounds.size.height), &characterFitRange)
        return Int(characterFitRange.length)

    }
}

如果文本多于预期文本,则可以尝试在CTFramesetterSuggestFrameSizeWithConstraints函数参数中调整高度值。