IOS高访微信聊天对话界面(sizeWithFont:constrainedToSize和stretchableImageWithLeftCapWidth的使用)

大家好,百忙之中,抽出点空,写个微博,话说好久没写。

最近项目中有碰到写类似微信聊天界面上的效果,特整理了一下,写了一个小的Demo,希望给没头绪的同学们一个参考!

Demo下载地址:http://download.youkuaiyun.com/detail/rhljiayou/6524347

先看一下效果图:左图为截取微信的,右图是本demo的效果

     


再看一下主要代码实现:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. @implementation ViewController  
  2.   
  3. - (void)viewDidLoad  
  4. {  
  5.     [super viewDidLoad];  
  6.       
  7.     NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:@"weixin",@"name",@"微信团队欢迎你。很高兴你开启了微信生活,期待能为你和朋友们带来愉快的沟通体检。",@"content", nil];  
  8.     NSDictionary *dict1 = [NSDictionary dictionaryWithObjectsAndKeys:@"rhl",@"name",@"hello",@"content", nil];  
  9.     NSDictionary *dict2 = [NSDictionary dictionaryWithObjectsAndKeys:@"rhl",@"name",@"0",@"content", nil];  
  10.     NSDictionary *dict3 = [NSDictionary dictionaryWithObjectsAndKeys:@"weixin",@"name",@"谢谢反馈,已收录。",@"content", nil];  
  11.     NSDictionary *dict4 = [NSDictionary dictionaryWithObjectsAndKeys:@"rhl",@"name",@"0",@"content", nil];  
  12.     NSDictionary *dict5 = [NSDictionary dictionaryWithObjectsAndKeys:@"weixin",@"name",@"谢谢反馈,已收录。",@"content", nil];  
  13.     NSDictionary *dict6 = [NSDictionary dictionaryWithObjectsAndKeys:@"rhl",@"name",@"大数据测试,长数据测试,大数据测试,长数据测试,大数据测试,长数据测试,大数据测试,长数据测试,大数据测试,长数据测试,大数据测试,长数据测试。",@"content", nil];  
  14.       
  15.     _resultArray = [NSMutableArray arrayWithObjects:dict,dict1,dict2,dict3,dict4,dict5,dict6, nil];  
  16.       
  17.   
  18. }  
  19.   
  20. - (void)didReceiveMemoryWarning  
  21. {  
  22.     [super didReceiveMemoryWarning];  
  23.     // Dispose of any resources that can be recreated.  
  24. }  
  25.   
  26. //泡泡文本  
  27. - (UIView *)bubbleView:(NSString *)text from:(BOOL)fromSelf withPosition:(int)position{  
  28.       
  29.     //计算大小  
  30.     UIFont *font = [UIFont systemFontOfSize:14];  
  31.     CGSize size = [text sizeWithFont:font constrainedToSize:CGSizeMake(180.0f, 20000.0f) lineBreakMode:NSLineBreakByWordWrapping];  
  32.       
  33.     // build single chat bubble cell with given text  
  34.     UIView *returnView = [[UIView alloc] initWithFrame:CGRectZero];  
  35.     returnView.backgroundColor = [UIColor clearColor];  
  36.       
  37.     //背影图片  
  38.     UIImage *bubble = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:fromSelf?@"SenderAppNodeBkg_HL":@"ReceiverTextNodeBkg" ofType:@"png"]];  
  39.       
  40.     UIImageView *bubbleImageView = [[UIImageView alloc] initWithImage:[bubble stretchableImageWithLeftCapWidth:floorf(bubble.size.width/2) topCapHeight:floorf(bubble.size.height/2)]];  
  41.     NSLog(@"%f,%f",size.width,size.height);  
  42.       
  43.       
  44.     //添加文本信息  
  45.     UILabel *bubbleText = [[UILabel alloc] initWithFrame:CGRectMake(fromSelf?15.0f:22.0f, 20.0f, size.width+10, size.height+10)];  
  46.     bubbleText.backgroundColor = [UIColor clearColor];  
  47.     bubbleText.font = font;  
  48.     bubbleText.numberOfLines = 0;  
  49.     bubbleText.lineBreakMode = NSLineBreakByWordWrapping;  
  50.     bubbleText.text = text;  
  51.       
  52.     bubbleImageView.frame = CGRectMake(0.0f, 14.0f, bubbleText.frame.size.width+30.0f, bubbleText.frame.size.height+20.0f);  
  53.       
  54.     if(fromSelf)  
  55.         returnView.frame = CGRectMake(320-position-(bubbleText.frame.size.width+30.0f), 0.0f, bubbleText.frame.size.width+30.0f, bubbleText.frame.size.height+30.0f);  
  56.     else  
  57.         returnView.frame = CGRectMake(position, 0.0f, bubbleText.frame.size.width+30.0f, bubbleText.frame.size.height+30.0f);  
  58.       
  59.     [returnView addSubview:bubbleImageView];  
  60.     [returnView addSubview:bubbleText];  
  61.       
  62.     return returnView;  
  63. }  
  64.   
  65. //泡泡语音  
  66. - (UIView *)yuyinView:(NSInteger)logntime from:(BOOL)fromSelf withIndexRow:(NSInteger)indexRow  withPosition:(int)position{  
  67.       
  68.     //根据语音长度  
  69.     int yuyinwidth = 66+fromSelf;  
  70.       
  71.     UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];  
  72.     button.tag = indexRow;  
  73.     if(fromSelf)  
  74.         button.frame =CGRectMake(320-position-yuyinwidth, 10, yuyinwidth, 54);  
  75.     else  
  76.         button.frame =CGRectMake(position, 10, yuyinwidth, 54);  
  77.       
  78.     //image偏移量  
  79.     UIEdgeInsets imageInsert;  
  80.     imageInsert.top = -10;  
  81.     imageInsert.left = fromSelf?button.frame.size.width/3:-button.frame.size.width/3;  
  82.     button.imageEdgeInsets = imageInsert;  
  83.       
  84.     [button setImage:[UIImage imageNamed:fromSelf?@"SenderVoiceNodePlaying":@"ReceiverVoiceNodePlaying"] forState:UIControlStateNormal];  
  85.     UIImage *backgroundImage = [UIImage imageNamed:fromSelf?@"SenderVoiceNodeDownloading":@"ReceiverVoiceNodeDownloading"];  
  86.     backgroundImage = [backgroundImage stretchableImageWithLeftCapWidth:20 topCapHeight:0];  
  87.     [button setBackgroundImage:backgroundImage forState:UIControlStateNormal];  
  88.       
  89.     UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(fromSelf?-30:button.frame.size.width, 0, 30, button.frame.size.height)];  
  90.     label.text = [NSString stringWithFormat:@"%d''",logntime];  
  91.     label.textColor = [UIColor grayColor];  
  92.     label.font = [UIFont systemFontOfSize:13];  
  93.     label.textAlignment = NSTextAlignmentCenter;  
  94.     label.backgroundColor = [UIColor clearColor];  
  95.     [button addSubview:label];  
  96.       
  97.     return button;  
  98. }  
  99.   
  100. #pragma UITableView  
  101.   
  102. - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView  
  103. {  
  104.     return 1;  
  105. }  
  106.   
  107. -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section  
  108. {  
  109.     return _resultArray.count;  
  110. }  
  111.   
  112. -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath  
  113. {  
  114.     NSDictionary *dict = [_resultArray objectAtIndex:indexPath.row];  
  115.     UIFont *font = [UIFont systemFontOfSize:14];  
  116.     CGSize size = [[dict objectForKey:@"content"] sizeWithFont:font constrainedToSize:CGSizeMake(180.0f, 20000.0f) lineBreakMode:NSLineBreakByWordWrapping];  
  117.       
  118.     return size.height+44;  
  119. }  
  120.   
  121. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath  
  122. {  
  123.       
  124.     static NSString *CellIdentifier = @"Cell";  
  125.     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];  
  126.     if (cell == nil) {  
  127.         cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];  
  128.         cell.selectionStyle = UITableViewCellSelectionStyleNone;  
  129.           
  130.     }else{  
  131.         for (UIView *cellView in cell.subviews){  
  132.             [cellView removeFromSuperview];  
  133.         }  
  134.     }  
  135.       
  136.     NSDictionary *dict = [_resultArray objectAtIndex:indexPath.row];  
  137.       
  138.     //创建头像  
  139.     UIImageView *photo ;  
  140.     if ([[dict objectForKey:@"name"]isEqualToString:@"rhl"]) {  
  141.         photo = [[UIImageView alloc]initWithFrame:CGRectMake(320-60, 10, 50, 50)];  
  142.         [cell addSubview:photo];  
  143.         photo.image = [UIImage imageNamed:@"photo1"];  
  144.           
  145.         if ([[dict objectForKey:@"content"] isEqualToString:@"0"]) {  
  146.             [cell addSubview:[self yuyinView:1 from:YES withIndexRow:indexPath.row withPosition:65]];  
  147.                
  148.               
  149.         }else{  
  150.             [cell addSubview:[self bubbleView:[dict objectForKey:@"content"] from:YES withPosition:65]];  
  151.         }  
  152.           
  153.     }else{  
  154.         photo = [[UIImageView alloc]initWithFrame:CGRectMake(10, 10, 50, 50)];  
  155.         [cell addSubview:photo];  
  156.         photo.image = [UIImage imageNamed:@"photo"];  
  157.           
  158.         if ([[dict objectForKey:@"content"] isEqualToString:@"0"]) {  
  159.             [cell addSubview:[self yuyinView:1 from:NO withIndexRow:indexPath.row withPosition:65]];  
  160.         }else{  
  161.             [cell addSubview:[self bubbleView:[dict objectForKey:@"content"] from:NO withPosition:65]];  
  162.         }  
  163.     }  
  164.       
  165.     return cell;  
  166.       
  167. }  
  168.   
  169. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath  
  170. {  
  171.       
  172. }  
  173.   
  174. @end  

其实很简单,主要说一下两个知识点,重要的两个知识点就能写出完美的泡泡对话聊天!

第一个是NSString中的一个方法:

- (CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size lineBreakMode:(NSLineBreakMode)lineBreakMode;

根据文本内容,算出所需要的大小CGSize;

第二个是UIImage中的一个方法:

- (UIImage *)stretchableImageWithLeftCapWidth:(NSInteger)leftCapWidth topCapHeight:(NSInteger)topCapHeight;

这里有几遍文章供大家参考这个方法的使用:
http://blog.youkuaiyun.com/lixing333/article/details/7589281

http://blog.youkuaiyun.com/w122079514/article/details/7848980

http://www.cnblogs.com/bandy/archive/2012/04/25/2469369.html


2013-12-31 10:19编辑

感谢这位朋友的提出


写此Demo的时候,没有考虑到那么多,发现了一些问题,具体请参考后来写的此文章: 

IOS高访新浪微博界面(讲解如何自定义UITableViewCell,处理@#链接 特殊字符)

可以做个参考,另外更新一下此Demo的下载:

http://download.youkuaiyun.com/detail/rhljiayou/6791445


转载来自任海丽博客

资源下载链接为: https://pan.quark.cn/s/f989b9092fc5 HttpServletRequestWrapper 是 Java Servlet API 中的一个工具类,位于 javax.servlet.http 包中,用于对 HttpServletRequest 对象进行封装,从而在 Web 应用中实现对 HTTP 请求的拦截、修改或增强等功能。通过继承该类并覆盖相关方法,开发者可以轻松地自定义请求处理逻辑,例如修改请求参数、添加请求头、记录日志等。 参数过滤:在请求到达处理器之前,可以对请求参数进行检查或修改,例如去除 URL 编码、过滤敏感信息或进行安全检查。 请求头操作:可以修改或添加请求头,比如设置自定义的 Content-Type 或添加认证信息。 请求属性扩展:在原始请求的基础上添加自定义属性,供后续处理使用。 日志记录:在处理请求前记录请求信息,如 URL、参数、请求头等,便于调试监控。 跨域支持:通过添加 CORS 相关的响应头,允许来自不同源的请求。 HttpServletRequestWrapper 通过继承 HttpServletRequest 接口并重写其方法来实现功能。开发者可以在重写的方法中添加自定义逻辑,例如在获取参数时进行过滤,或在读取请求体时进行解密。当调用这些方法时,实际上是调用了包装器中的方法,从而实现了对原始请求的修改或增强。 以下是一个简单的示例,展示如何创建一个用于过滤请求参数的包装器: 在 doFilter 方法中,可以使用 CustomRequestWrapper 包装原始请求: 这样,每当调用 getParameterValues 方法时,都会先经过自定义的过滤逻辑。 HttpServletRequestWrapper 是 Java Web 开发中一个强大的工具,它提供了灵活的扩展性,允许开发者
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值