Ios 如何为UITextField实现类似NSLineBreakbyTruncingHead的功能?

Ios 如何为UITextField实现类似NSLineBreakbyTruncingHead的功能?,ios,objective-c,uitextfield,Ios,Objective C,Uitextfield,我需要为UITextField实现类似于NSLineBreakByTruncatingHead的功能,如下所示。假设原文是: 这是无法在UITextField中显示的长文本 我需要它,就像: …无法显示在UITextField内 但目前我得到的是: 这是一篇很长的文章,不能 只需在开始时进行截断。未为UITextField提供lineBreakMode属性。如何实现它?我采用了解决方案,并对其进行了修改,以截断字符串的头部而不是尾部。请知道,它仅在未编辑字段时显示省略号 注意:此解决方案仅适用于

我需要为
UITextField
实现类似于
NSLineBreakByTruncatingHead
的功能,如下所示。假设原文是:

这是无法在UITextField中显示的长文本

我需要它,就像:

…无法显示在UITextField内

但目前我得到的是:

这是一篇很长的文章,不能

只需在开始时进行截断。未为
UITextField
提供
lineBreakMode
属性。如何实现它?

我采用了解决方案,并对其进行了修改,以截断字符串的头部而不是尾部。请知道,它仅在未编辑字段时显示省略号

注意:此解决方案仅适用于iOS 7+版本。要在iOS 6中使用,请在NSString+truncateTowitWidth.m文件中使用
sizeWidthFont:
而不是
sizeWidthAttributes:

编辑:增加了对iOS 6的支持

NSString+TruncateToWidth.h

@interface NSString (TruncateToWidth)
- (NSString*)stringByTruncatingToWidth:(CGFloat)width withFont:(UIFont *)font;
@end
NSString+TruncateToWidth.m

#import "NSString+TruncateToWidth.h"

#define ellipsis @"…"

@implementation NSString (TruncateToWidth)

- (NSString*)stringByTruncatingToWidth:(CGFloat)width withFont:(UIFont *)font
{
    // Create copy that will be the returned result
    NSMutableString *truncatedString = [self mutableCopy];

    // Make sure string is longer than requested width
    if ([self widthWithFont:font] > width)
    {
        // Accommodate for ellipsis we'll tack on the beginning
        width -= [ellipsis widthWithFont:font];

        // Get range for first character in string
        NSRange range = {0, 1};

        // Loop, deleting characters until string fits within width
        while ([truncatedString widthWithFont:font] > width)
        {
            // Delete character at beginning
            [truncatedString deleteCharactersInRange:range];
        }

        // Append ellipsis
        [truncatedString replaceCharactersInRange:NSMakeRange(0, 0) withString:ellipsis];
    }

    return truncatedString;
}

- (CGFloat)widthWithFont:(UIFont *)font
{
    if([self respondsToSelector:@selector(sizeWithAttributes:)])
        return [self sizeWithAttributes:@{NSFontAttributeName:font}].width;
    return [self sizeWithFont:font].width;
}
使用它:

...
// Make sure to import the header file where you want to use it
// assumes instance variable holds your string that populates the field
fieldString = @"abcdefghijklmnopqrstuvwxyz1234567890";
// Size will need to be less than text field's width to account for padding
_myTextField.text = [fieldString stringByTruncatingToWidth:(_myTextField.frame.size.width - 15) withFont:_myTextField.font];
...

// use textFieldShouldBeginEditing to make it animate from the start of the field to the end of the string if you prefer that. I found it a little distracting
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
    textField.text = fieldString;
}

- (BOOL)textFieldShouldEndEditing:(UITextField *)textField
{
    fieldString = textField.text;
    textField.text = [textField.text stringByTruncatingToWidth:(textField.frame.size.width - 15) withFont:textField.font];

    return YES;
}

我有一个类似的要求,我写了一个@Stonz2解决方案的Swift版本,它在大多数情况下都有效,但由于该要求后来被删除,尚未在生产中使用。。。无论如何,把它贴在这里

    extension String {

    func stringByTruncatingLeadingForWidth(width: CGFloat, withFont font: UIFont) -> String{

        var modifiedString = self
        var mutableWidth = width
        let ellipsis = "..."
        if (self.widthOfString(usingFont: font) > width) {
            let ellipsisWidth = ellipsis.widthOfString(usingFont: font)

            // else this will go for infinite loop...mutable width will go -ve
            if mutableWidth > ellipsisWidth {
                mutableWidth -= ellipsis.widthOfString(usingFont: font)
            }
            let range = NSMakeRange(0, 1)

            while modifiedString.widthOfString(usingFont: font) > mutableWidth {
                modifiedString.deleteCharactersInRange(range: range)
                print(modifiedString)
                print(mutableWidth)
            }
            guard let swiftRange = Range(NSMakeRange(0, 3), in: modifiedString) else { return ""  }
            modifiedString.replaceSubrange(swiftRange, with: [".",".","."])
        }
        return modifiedString
    }
    func widthOfString(usingFont font: UIFont) -> CGFloat {
        let fontAttributes = [NSAttributedString.Key.font: font]
        let size = self.size(withAttributes: fontAttributes)
        return size.width
    }

    mutating func deleteCharactersInRange(range: NSRange) {
        guard let swiftRange = Range(range, in: self) else { return  }
        self.removeSubrange(swiftRange)
    }
}

var str1 = "Hello how are you"

let newStr = str1.stringByTruncatingLeadingForWidth(width: 100, withFont: .systemFont(ofSize: 15))

我不得不把“padding”的数字比预期的(15)高一点,因为它有时不够短,并且会在末尾加上一个省略号。谢谢你,我已经投票了,因为你真的找到了它,而且你的解释很清楚。再次感谢,从苹果的文档来看,这非常简单。