zoukankan      html  css  js  c++  java
  • 单行及多行图文混排,聊天应用较常用,本文只提供算法。

    // 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
    


  • 相关阅读:
    HTTP断点续传 规格严格
    Java Shutdown 规格严格
    linux 命令源码 规格严格
    JTable调整列宽 规格严格
    linux 多CPU 规格严格
    Hello can not find git path 规格严格
    Kill 规格严格
    拜拜牛人 规格严格
    Swing 规格严格
    Debugging hangs in JVM (on AIX but methodology applicable to other platforms) 规格严格
  • 原文地址:https://www.cnblogs.com/james1207/p/3313170.html
Copyright © 2011-2022 走看看