I need to achieve something exactly like NSLineBreakByTruncatingHead
for UITextField
as shown here. Let's assume the original text is:
This is the long text that cannot be shown inside a UITextField
I need it like:
...cannot be shown inside a UITextField
but currently I am getting something like:
This is the long text that cannot...
simply the truncation at the beginning. The lineBreakMode
property is not given for UITextField
. How can I achieve it?
I took the solution here and modified it to truncate the head of a string instead of the tail. Know that it only shows the ellipsis when the field is not being edited.
NOTE: This solution is for iOS 7+ only. To use in iOS 6, use sizeWithFont:
instead of sizeWithAttributes:
in the NSString+TruncateToWidth.m file.
EDIT: Added support for 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;
}
Using it:
...
// 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;
}