I'm having real trouble getting my head around this issue.
As the title suggests, I have several UITextViews on a view in an iPhone application. I am programmatically creating them and successfully filling that textview with text, but in some cases the text I put in the view takes up more space than the frame I allocate for it. In this case I would like the text to be truncated, but I can't figure out how to do it.
I have predefined the following constants;
#define viewOriginX 20
#define viewOriginY 180
Here is my UITextView creation code;
textViewOne = [[UITextView alloc] initWithFrame:CGRectMake(viewOriginX, viewOriginY + 65, 280, 45];
textViewOne.delegate = self;
textViewOne.scrollEnabled = NO;
textViewOne.contentInset = UIEdgeInsetsZero;
textViewOne.font = viewFont;
textViewOne.textColor = [UIColor blackColor];
textViewOne.textAlignment = UITextAlignmentLeft;
[self.view addSubview:textViewOne];
In some cases I have 15 to 20 lines of text in here and I would like to truncate it to 2 lines.
Can anyone help me in the right direction?
Thanks in advance! :D
If the text extends beyond the bounds then it's being displayed as truncated. The challenge with UITextView is that, by design, it can hold text that is far larger than its bounds. This is the essence of how a scrolling text view operates.
It can be done using the UITextView contentSize . This will not work if auto layout is ON. With auto layout, the general approach is to use the sizeThatFits method and update the constant value on a height constraint. CGSize sizeThatShouldFitTheContent = [_textView sizeThatFits:_textView.
Sadly, UILabel
with numberOfLines
wont do it if you need the view to be editable. Or you want UITextView
's (native) vertical alignment.
Here's an NSString
category that deletes words from a string, according to it's size in a rect:
@interface NSString (StringThatFits)
- (NSString *)stringByDeletingWordsFromStringToFit:(CGRect)rect
withInset:(CGFloat)inset
usingFont:(UIFont *)font
@end
@implementation NSString (StringThatFits)
- (NSString *)stringByDeletingWordsFromStringToFit:(CGRect)rect
withInset:(CGFloat)inset
usingFont:(UIFont *)font
{
NSString *result = [self copy];
CGSize maxSize = CGSizeMake(rect.size.width - (inset * 2), FLT_MAX);
CGSize size = [result sizeWithFont:font
constrainedToSize:maxSize
lineBreakMode:UILineBreakModeWordWrap];
NSRange range;
if (rect.size.height < size.height)
while (rect.size.height < size.height) {
range = [result rangeOfString:@" "
options:NSBackwardsSearch];
if (range.location != NSNotFound && range.location > 0 ) {
result = [result substringToIndex:range.location];
} else {
result = [result substringToIndex:result.length - 1];
}
size = [result sizeWithFont:font
constrainedToSize:maxSize
lineBreakMode:UILineBreakModeWordWrap];
}
return result;
}
@end
For a UITextView
, use an inset of 8 to account for the way UIKit draws them:
CGRect rect = aTextView.frame;
NSString *truncatedString = [theString stringByDeletingWordsFromStringToFit:rect
withInset:8.f
usingFont:theTextView.font];
Now UITextView
uses TextKit internally, it's much easier.
Rather than truncating the actual string, set the text
(or attributedText
) property to the whole string and truncate the amount of text displayed in the container (just like we do with UILabel
):
self.textView.scrollEnabled = NO;
self.textView.textContainer.maximumNumberOfLines = 0;
self.textView.textContainer.lineBreakMode = NSLineBreakByTruncatingTail;
You can do a character count. For example, if you have UITextField like this:
+--------------------+
|This is a string in |
|a text view. |
+--------------------+
you have something like 20 characters per line. If you know that number you can simply truncate your string by -substringToIndex:
method.
int maxCharacters = 40; // change it to your max
if([myString length] > maxCharacters) {
myString = [myString substringToIndex:maxCharacters];
}
You can also think about UILabel
. Since you need only 2 lines of text, UILabel's numberOfLines
property can solve your problem.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With