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

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

在我的应用程序中,如果文本输入是 large.so,我需要将阅读更多设置到文本视图中我的方法是找到适合文本视图的字符串范围,并将查看更多附加到 it.Is 在 Swift.The 中有什么方法可以实现它的要求是模拟阅读更多选项,以便像 facebook 一样在点击时以详细视图显示完整文本。

有点复杂,因为有些字母比其他字母宽。但是您可以使用 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])

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

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

您要查找的函数是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 用于将随机文本截断到指定行数并向其附加 "view more" 文本的完整实现。

kgaidis 出色回答的粗略 swift 翻译。

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

这是 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 函数参数中的高度值。