如何截断UITextView内容以适应缩小的尺寸?

时间:2011-08-14 15:27:42

标签: ios iphone uitextview

我很难解决这个问题。

正如标题所示,我在iPhone应用程序的视图中有几个UITextView。我以编程方式创建它们并成功地用文本填充textview,但在某些情况下,我放在视图中的文本比我为其分配的帧占用更多空间。在这种情况下,我希望文本被截断,但我无法弄清楚如何做到这一点。

我预先定义了以下常量;

#define viewOriginX  20
#define viewOriginY 180

这是我的UITextView创建代码;

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];

在某些情况下,我在这里有15到20行文字,我想将其截断为2行。

任何人都可以帮助我朝正确的方向发展吗?

提前致谢! :d

4 个答案:

答案 0 :(得分:41)

原始答案(iOS 6及以下)

可悲的是,UILabel numberOfLines如果您需要视图可编辑,则不会这样做。或者您希望UITextView(本机)垂直对齐。

这是一个NSString类别,根据字符串中的大小删除字符串中的单词:

@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

对于UITextView,使用插入8来说明UIKit绘制它们的方式:

CGRect rect = aTextView.frame;
NSString *truncatedString = [theString stringByDeletingWordsFromStringToFit:rect
                                     withInset:8.f
                                     usingFont:theTextView.font];

更新了答案(iOS 7)

现在UITextView在内部使用TextKit,它更容易。

不是截断实际的字符串,而是将text(或attributedText)属性设置为整个字符串,并截断容器中显示的文本的数量(就像我们使用UILabel):

self.textView.scrollEnabled = NO;
self.textView.textContainer.maximumNumberOfLines = 0;
self.textView.textContainer.lineBreakMode = NSLineBreakByTruncatingTail;

答案 1 :(得分:1)

你可以做一个字符数。例如,如果你有这样的UITextField:

+--------------------+
|This is a string in |
|a text view.        |
+--------------------+

每行有20个字符。如果您知道该号码,则可以通过-substringToIndex:方法截断字符串。

int maxCharacters = 40; // change it to your max
if([myString length] > maxCharacters) {
    myString = [myString substringToIndex:maxCharacters];
}

您还可以考虑UILabel。由于您只需要2行文本,因此UILabel的numberOfLines属性可以解决您的问题。

答案 2 :(得分:1)

由于iOS 7中不推荐使用sizeWithFont:constrainedToSize:lineBreakMode:,因此我做了一些更改:

- (NSString *)stringByDeletingWordsFromStringToFit:(CGRect)rect
                                     withInset:(CGFloat)inset
                                     usingFont:(UIFont *)font
{
    NSString *result = [self copy];
    CGSize maxSize = CGSizeMake(rect.size.width  - (inset * 2), FLT_MAX);
    if (!font) font = [UIFont systemFontOfSize:[UIFont systemFontSize]];
    CGRect boundingRect = [result boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName: font, } context:nil];
    CGSize size = boundingRect.size;
    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];
            }

            if (!font) font = [UIFont systemFontOfSize:[UIFont systemFontSize]];
            CGRect boundingRect = [result boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName: font, } context:nil];
            size = boundingRect.size;
        }

    return result;

}

答案 3 :(得分:0)

这里是我编写的用于截断字符串(通过单词)以适合特定宽度和高度的代码的和平:

- (NSString *)stringByTruncatingString:(NSString *)string toHeight:(CGFloat)height maxWidth:(CGFloat)width withFont: (UIFont *)font {

    NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
    paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;
    NSDictionary *attrDict = [NSDictionary dictionaryWithObjectsAndKeys:font, NSFontAttributeName, paragraphStyle, NSParagraphStyleAttributeName, nil];
    NSMutableString *truncatedString = [string mutableCopy];

    if ([string sizeWithAttributes: @{NSFontAttributeName: font}].height > height) {
        // this line is optional, i wrote for better performance in case the string is too big
        if([truncatedString length] > 150) truncatedString = [[truncatedString substringToIndex:150] mutableCopy];
        // keep removing the last word until string is short enough
        while ([truncatedString boundingRectWithSize:CGSizeMake(width, CGFLOAT_MAX) options:NSStringDrawingTruncatesLastVisibleLine|NSStringDrawingUsesLineFragmentOrigin attributes:attrDict context:nil].size.height > height) {
            NSRange wordrange= [truncatedString rangeOfString: @" " options: NSBackwardsSearch];
            truncatedString = [[truncatedString substringToIndex: wordrange.location] mutableCopy];
        }
        // add elipsis to the end
        truncatedString = [NSMutableString stringWithFormat:@"%@...",truncatedString];
    }
    return truncatedString;
}

用法:

NSString *smallString = [self stringByTruncatingString:veryBigString toHeight:65 maxWidth:200 withFont:[UIFont systemFontSize:14.0f]];