读书人

单行及多行图文混排聊天应用较比常用

发布时间: 2013-09-11 16:26:28 作者: rapoo

单行及多行图文混排,聊天应用较常用,本文只提供算法。

// TTSingleLineView.h#import <UIKit/UIKit.h>#import "TTLineView.h"#define kChatRoomSingleLineSendFontSize        (18.0f)@interface TTSingleLineView : TTLineView+ (TTSingleLineView *)singleLineView:(NSArray *)views;@end//TTSingleLineView.m#import "TTSingleLineView.h"#define kChatRoomSingleLineDefaultHeight (30.0f)@implementation TTSingleLineView- (id)initWithFrame:(CGRect)frame{    self = [super initWithFrame:frame];    if (self) {        // Initialization code//        self.backgroundColor = [UIColor colorWithWhite:0.4f alpha:0.4f];    }    return self;}+ (TTSingleLineView *)singleLineView:(NSArray *)views{    TTSingleLineView *slv = [[TTSingleLineView alloc] initWithFrame:CGRectZero];    [slv chatRoomSingleLineView:views];    return slv;}- (CGFloat)chatRoomSingleLineView:(NSArray *)array{    CGFloat lineWidth = 0.0f;    for (NSDictionary *dict in array)    {        switch ([self contentType:dict])        {            case kChatRoomText:            {                NSString *contentText = [self chatContentText:dict];                CGFloat fontSize = [self chatContentTextFont:dict];                CGFloat textWidth = [self getStringWidth:contentText size:fontSize];                ChatRoomFontColorMode colorMode = [[dict valueForKey:kChatTextColorTypeKeyName] integerValue];                UIColor *color = [self chatTextColor:colorMode];                                UILabel *l = [[UILabel alloc] initWithFrame:CGRectMake(lineWidth,                                                                       0.0f,                                                                       textWidth,                                                                       kChatRoomSingleLineDefaultHeight)];                l.backgroundColor = [UIColor clearColor];                l.font = kFontOfSize(fontSize);                l.text = contentText;                l.textColor = color;                l.lineBreakMode = NSLineBreakByCharWrapping;                [self addSubview:l];                                lineWidth += textWidth;            }                break;            case kChatRoomRemoteDynamicImage:            case kChatRoomRemoteStaticImage:            {                NSString *imageStr = [self chatImagePath:dict];                CGFloat imageWidth = [self chatImageWidth:dict];                CGFloat imageHeight = [self chatImageHeight:dict];                CGFloat imagePaddingX = [self chatImagePaddingX:dict];                CGFloat imagePaddingY = [self chatImagePaddingY:dict];                                imageStr = [imageStr substringFromIndex:kChatCutOffContentRemoteStillImageType.length];                                UIImageView *imageView = [[UIImageView alloc] initWithFrame:                                          CGRectMake(lineWidth + imagePaddingX,                                                     0.0f + imagePaddingY,                                                     imageWidth,                                                     imageHeight)];                [imageView setImageWithURL:[NSURL URLWithString:imageStr] placeholderImage:nil];                [self addSubview:imageView];                                lineWidth += imageWidth;                lineWidth += imagePaddingX;            }                break;            case kChatRoomLocalDynamicImage:            case kChatRoomLocalStaticImage:            {                NSString *imageStr = [self chatImagePath:dict];                CGFloat imageWidth = [self chatImageWidth:dict];                CGFloat imageHeight = [self chatImageHeight:dict];                CGFloat imagePaddingX = [self chatImagePaddingX:dict];                CGFloat imagePaddingY = [self chatImagePaddingY:dict];                                               imageStr = [imageStr substringFromIndex:kChatCutOffContentRemoteStillImageType.length];                                UIImageView *imageView = [[UIImageView alloc] initWithFrame:                                          CGRectMake(lineWidth + imagePaddingX,                                                     0.0f + imagePaddingY,                                                     imageWidth,                                                     imageHeight)];                imageView.image = kImageNamed(imageStr);                [self addSubview:imageView];                                lineWidth += imageWidth;                lineWidth += imagePaddingX;            }                break;                            default:                break;        }    }    self.frame = CGRectMake(0.0f, 0.0f, lineWidth, kChatRoomSingleLineDefaultHeight);        return kChatRoomSingleLineDefaultHeight;}- (CGFloat)getStringWidth:(NSString *)text size:(CGFloat)fontSize{    CGSize size = [text sizeWithFont:kFontOfSize(fontSize) constrainedToSize:CGSizeMake(MAXFLOAT, kChatRoomSingleLineDefaultHeight)];    return size.width;}/*// Only override drawRect: if you perform custom drawing.// An empty implementation adversely affects performance during animation.- (void)drawRect:(CGRect)rect{    // Drawing code}*/@end// TTMultiLineView.h#import <UIKit/UIKit.h>#import "TTLineView.h"@interface TTMultiLineView : TTLineView@property (nonatomic, assign) CGFloat previousHeight;// View's total height.@property (nonatomic, assign) CGFloat height;@property (nonatomic, assign) CGFloat padding;+ (TTMultiLineView *)multiLineView:(NSArray *)views;@end// TTMultiLineView.m#import "TTMultiLineView.h"#define kChatTextHeightDefault         (24.0f)#define kChatViewWidthMax              (kScreenWidth - self.padding * 2)#define kChatSplitSingleWordWidth      (15.0f)#define kChatContentPadding            (0.0f)// Parse.#define kChatParseTextWidthKeyName     @"chat.parse.text.width"#define kChatParseTextContentKeyName   @"chat.parse.text.content"#define kChatParseTextCutPointKeyName  @"chat.parse.text.cutpoint"@implementation TTMultiLineView- (id)initWithFrame:(CGRect)frame{    self = [super initWithFrame:frame];    if (self) {        // Initialization code    }    return self;}+ (TTMultiLineView *)multiLineView:(NSArray *)views{    TTMultiLineView *mlv = [[TTMultiLineView alloc] initWithFrame:CGRectZero];    [mlv chatMultiLineView:views];    return mlv;}- (CGFloat)chatMultiLineView:(NSArray *)array{    CGFloat viewWidth = 0.0f;    CGFloat viewHeightMax = 0.0f;        if (self.padding == 0.0f)    {        self.padding = kChatContentPadding;    }        for (NSDictionary *dict in array)    {        switch ([self contentType:dict])        {            case kChatRoomText:            {                NSString *contentText = [self chatContentText:dict];                CGFloat fontSize = [self chatContentTextFont:dict];                                if (contentText != nil && contentText.length > 0)                {                    CGSize firstCharSize = [[contentText substringToIndex:1] sizeWithFont:kFontOfSize(fontSize) constrainedToSize:CGSizeMake(MAXFLOAT, kChatTextHeightDefault)];                                        if (viewWidth + firstCharSize.width > kChatViewWidthMax)                    {                        // insert new line if last string reach end.                        self.previousHeight += kChatTextHeightDefault;                        viewWidth = 0.0f;                    }                }                                NSArray *sectionStrs = [self splitString:contentText start:viewWidth size:fontSize];                                // Multiline.                NSUInteger line = 0;                for (NSDictionary *d in sectionStrs)                {                    NSUInteger width = [[d valueForKey:kChatParseTextWidthKeyName] unsignedIntegerValue];                    NSString *text = [d valueForKey:kChatParseTextContentKeyName];                                        ChatRoomFontColorMode colorMode = [[dict valueForKey:kChatTextColorTypeKeyName] integerValue];                    UIColor *color = [self chatTextColor:colorMode];                                        if (line != 0)                    {                        viewWidth = 0.0f;                        if (line == 1)                        {                            // First Line                            self.previousHeight += MAX(kChatTextHeightDefault, viewHeightMax);                            viewHeightMax = kChatTextHeightDefault;                        }                        else                        {                            // > 1 line.                            self.previousHeight += kChatTextHeightDefault;                        }                    }                    else                    {                        viewHeightMax = MAX(viewHeightMax, kChatTextHeightDefault);                    }                                        UILabel *l = [[UILabel alloc] initWithFrame:CGRectMake(viewWidth,                                                                           self.previousHeight,                                                                           width,                                                                           kChatTextHeightDefault)];                    l.backgroundColor = [UIColor clearColor];                    l.font = kFontOfSize(fontSize);                    l.text = text;                    l.textColor = color;                    l.lineBreakMode = NSLineBreakByCharWrapping;//                    l.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleBottomMargin;                    [self addSubview:l];                                        if (line == [sectionStrs count] - 1)                    {                        // Last Line, recode width.                        viewWidth += width;                    }                                        line++;                }            }                break;            case kChatRoomRemoteDynamicImage:            case kChatRoomLocalDynamicImage:            {                NSString *imageStr = [self chatImagePath:dict];                CGFloat imageWidth = [self chatImageWidth:dict];                CGFloat imageHeight = [self chatImageHeight:dict];                CGFloat imagePaddingX = [self chatImagePaddingX:dict];                CGFloat imagePaddingY = [self chatImagePaddingY:dict];                                if (viewWidth + imageWidth > kChatViewWidthMax)                {                    // new line                    self.previousHeight += viewHeightMax;                                        viewHeightMax = MAX(viewHeightMax, imageHeight);                    viewWidth = 0.0f;                }                                imageStr = [imageStr substringFromIndex:kChatCutOffContentLocalDynamicImageType.length];                //                LOGINFO(@"imageStr = %@", imageStr);                                UIImageView *imageView = [[UIImageView alloc] initWithFrame:                                          CGRectMake(viewWidth + imagePaddingX,                                                     self.previousHeight + imagePaddingY,                                                     imageWidth,                                                     imageHeight)];                imageView.image = [UIImage sd_animatedGIFNamed:imageStr];                [self addSubview:imageView];                                viewWidth += imageWidth;                viewWidth += imagePaddingX;                viewHeightMax = MAX(imageHeight, viewHeightMax);            }                break;            case kChatRoomLocalStaticImage:            case kChatRoomRemoteStaticImage:            {                NSString *imageStr = [self chatImagePath:dict];                CGFloat imageWidth = [self chatImageWidth:dict];                CGFloat imageHeight = [self chatImageHeight:dict];                CGFloat imagePaddingX = [self chatImagePaddingX:dict];                CGFloat imagePaddingY = [self chatImagePaddingY:dict];                                //                LOGINFO(@"imageStr = %@", imageStr);                                if (viewWidth + imageWidth > kChatViewWidthMax)                {                    // new line                    self.previousHeight += viewHeightMax;                                        viewHeightMax = MAX(viewHeightMax, imageHeight);                    viewWidth = 0.0f;                }                                imageStr = [imageStr substringFromIndex:kChatCutOffContentRemoteStillImageType.length];                                UIImageView *imageView = [[UIImageView alloc] initWithFrame:                                          CGRectMake(viewWidth + imagePaddingX,                                                     self.previousHeight + imagePaddingY,                                                     imageWidth,                                                     imageHeight)];                [imageView setImageWithURL:[NSURL URLWithString:imageStr] placeholderImage:nil];                [self addSubview:imageView];                                viewWidth += imageWidth;                viewWidth += imagePaddingX;                viewHeightMax = MAX(imageHeight, viewHeightMax);            }                break;                            default:                break;        }    }        CGFloat totalHeight = self.previousHeight + viewHeightMax;    if (totalHeight == 0.0f)    {        // Text Single Line;        totalHeight = kChatTextHeightDefault;    }    self.frame = CGRectMake(self.padding, 0.0f, kChatViewWidthMax, totalHeight);        return totalHeight;}- (NSArray *)splitString:(NSString *)str start:(CGFloat)loc size:(CGFloat)fontSize{    NSMutableArray *array = [NSMutableArray arrayWithCapacity:0];    NSUInteger i = 1;    NSUInteger location = 0;    NSUInteger startPoint = 0;    CGFloat startPaddingX = loc;    //    LOGINFO(@"str = %@ padding = %.2f", str, x);        while (i < str.length)    {        NSRange range = NSMakeRange(location, i - startPoint);                NSString *str1 = [str substringWithRange:range];        CGSize size = [str1 sizeWithFont:kFontOfSize(fontSize) constrainedToSize:CGSizeMake(MAXFLOAT, kChatTextHeightDefault)];//        LOGINFO(@"str1 = %@ size.width = %.2f", str1, size.width);                if (size.width + startPaddingX + kChatSplitSingleWordWidth > kChatViewWidthMax)        {            startPaddingX = 0.0f;            location += str1.length;            startPoint = i;                        NSMutableDictionary *dictionary = [NSMutableDictionary dictionaryWithCapacity:0];            [dictionary setValue:@(size.width) forKey:kChatParseTextWidthKeyName];            [dictionary setValue:str1 forKey:kChatParseTextContentKeyName];            [dictionary setValue:@(i) forKey:kChatParseTextCutPointKeyName];            [array addObject:dictionary];        }                i++;    }        // Last Section String.    NSString *lastSectionStr = [str substringFromIndex:location];    CGSize lastStrSize = [lastSectionStr sizeWithFont:kFontOfSize(fontSize) constrainedToSize:CGSizeMake(MAXFLOAT, kChatTextHeightDefault)];        NSMutableDictionary *dictionary = [NSMutableDictionary dictionaryWithCapacity:0];    [dictionary setValue:@(lastStrSize.width) forKey:kChatParseTextWidthKeyName];    [dictionary setValue:lastSectionStr forKey:kChatParseTextContentKeyName];    [dictionary setValue:@(i) forKey:kChatParseTextCutPointKeyName];    [array addObject:dictionary];        return array;}/*// Only override drawRect: if you perform custom drawing.// An empty implementation adversely affects performance during animation.- (void)drawRect:(CGRect)rect{    // Drawing code}*/@end

读书人网 >移动开发

热点推荐