我需要为此NSLineBreakByTruncatingHead
获得与UITextField
完全相同的内容。让我们假设原始文本是:
这是无法在UITextField
中显示的长文本
我需要它:
...无法在UITextField中显示
但目前我得到的结果如下:
这是长篇文章,不能......
只是开头的截断。 lineBreakMode
未提供UITextField
属性。我怎样才能实现它?
答案 0 :(得分:2)
我采用了解决方案here并对其进行了修改,以截断字符串的头部而不是尾部。知道它只在未编辑字段时显示省略号。
注意:此解决方案仅适用于iOS 7+。要在iOS 6中使用,请在 NSString + TruncateToWidth.m 文件中使用 sizeWithFont:
代替sizeWithAttributes:
。
编辑:添加了对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;
}
答案 1 :(得分:0)
我有一个类似的要求,我写了一个@ 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))