重新更新一篇可以说整个工程聊天界面最重要的一part,聊天列表的实现,这里我采用循序渐进的方法来完成学习,我先用setFrame的方法来实现,虽然setFrame方法复杂,但是对整体理解的要求更加高,更能理解面相对象的很多特性,例如封装、类的抽象化、对象消息传参等等重要的知识点。而setFrame的实现也是先实现纯文本的对话形式,当保证文本可以正常无bug的实现后再开枝散叶式地添加语音、图像、视频、表情等等等。而且setFrame的方法必须上网参考别人的起码三种实现,因为不同的代码风格和有一些实现技巧都可以对比对比,并且取其精华去其糟粕。当setFrame可以很好地实现,那么就开始尝试masonry的实现!

纯文本下setFrame方法:

先来看看实现一:

实现的类结构:

          

Model层的实现:

一:

ChartMessage.h

typedef enum
{kMessageFrom = 0,kMessageTo} ChartMessageType;#import <Foundation/Foundation.h>@interface ChartMessage : NSObject@property (nonatomic, assign) ChartMessageType messageType;//是消息的发送者还是接收者
@property (nonatomic, copy) NSString* icon;//icon是头像对应UIImage
@property (nonatomic, copy) NSString* content;//内容
@property (nonatomic, copy) NSDictionary* dict;//dic 装的是什么?@end

ChartMessage.m

#import "ChartMessage.h"@implementation ChartMessage//这里可以开始掌握一种写法,在set方法里面设置数据变量
- (void)setDict:(NSDictionary *)dict
{_dict = dict;self.icon = dict[@"icon"];self.content = dict[@"content"];self.messageType = [dict[@"type"] intValue];
}@end

二:

ChartCellFrame.h

#import "ChartMessage.h"
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>@interface ChartCellFrame : NSObject@property (nonatomic, assign) CGRect iconRect;              //图标的Rect值
@property (nonatomic, assign) CGRect chartViewRect;         //聊天内容的Rect值
@property (nonatomic, strong) ChartMessage* chartMessage;   //聊天内容
@property (nonatomic, assign) CGFloat cellHeight;           //整体的高度@end

ChartCellFrame.m

#import "QQChating.h"
#import "ChartCellFrame.h"@implementation ChartCellFrame- (void)setChartMessage:(ChartMessage *)chartMessage
{_chartMessage = chartMessage;CGSize winSize = [UIScreen mainScreen].bounds.size;CGFloat iconX = kIconMarginX;CGFloat iconY = kIconMarginY;CGFloat iconWidth  = 40;CGFloat iconHeight = 40;if (chartMessage.messageType == kMessageFrom){}else if (chartMessage.messageType == kMessageTo){iconX = winSize.width - kIconMarginX - iconWidth;}self.iconRect = CGRectMake(iconX, iconY, iconWidth, iconHeight);CGFloat contentX = CGRectGetMaxX(self.iconRect) + kIconMarginX;CGFloat contentY = iconY;//这里为什么是写死200NSDictionary* attributes = @{NSFontAttributeName:[UIFont fontWithName:@"HelveticaNeue" size:13]};CGSize contentSize = [chartMessage.content boundingRectWithSize:CGSizeMake(200, MAXFLOAT)options:NSStringDrawingTruncatesLastVisibleLine |NSStringDrawingUsesLineFragmentOrigin |NSStringDrawingUsesFontLeadingattributes:attributescontext:nil].size;if (chartMessage.messageType == kMessageTo){contentX = iconX - kIconMarginX - contentSize.width - iconWidth;}self.chartViewRect = CGRectMake(contentX, contentY,contentSize.width + 35,contentSize.height + 30);self.cellHeight = MAX(CGRectGetMaxY(self.iconRect), CGRectGetMaxY(self.chartViewRect)) + kIconMarginY;
}@end

View层的实现:

一:

ChartContentViewDelegate.h

#import <Foundation/Foundation.h>
@class ChartContentView, ChartMessage;@protocol ChartContentViewDelegate <NSObject>//定义一个委托类,越来越觉得委托的作用和接口一样了。
//如何定义参数上都是一门学问,例如可以传的东西有,self自身(self这种东西很有用的)
//这个时候就要第一个参数的类是self类,同时另外的参数可以根据需求来
- (void)chartContentViewLongPress:(ChartContentView *)chartView content:(NSString *)content;
- (void)chartContentViewTapPress:(ChartContentView *)chartView content:(NSString *)content;@end

二:

ChartContentView.h

#import "QQChating.h"
#import <UIKit/UIKit.h>
#import "ChartMessage.h"
#import "ChartContentViewDelegate.h"@interface ChartContentView : UIView@property (nonatomic, strong)UILabel* contentLabel;
@property (nonatomic, strong)ChartMessage* chartMessage;
@property (nonatomic, strong)UIImageView* backImageView;
@property (nonatomic, strong)id<ChartContentViewDelegate> delegate;@end

ChartContentView.m

#import "ChartContentView.h"@implementation ChartContentView- (id)initWithFrame:(CGRect)frame
{self = [super initWithFrame:frame];if (self){self.backImageView = [[UIImageView alloc] init];self.backImageView.userInteractionEnabled = YES;[self addSubview:self.backImageView];self.contentLabel = [[UILabel alloc] init];self.contentLabel.numberOfLines = 0;self.contentLabel.textAlignment = NSTextAlignmentLeft;self.contentLabel.font = [UIFont fontWithName:@"HelveticaNeue" size:13];[self addSubview:self.contentLabel];[self addGestureRecognizer:[[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longTap:)]];[self addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapPress:)]];}return self;
}- (void)setFrame:(CGRect)frame
{[super setFrame:frame];self.backImageView.frame = self.bounds;CGFloat contentLabelX = 0;if (self.chartMessage.messageType == kMessageFrom){contentLabelX = kContentStartMargin*0.8;}else if (self.chartMessage.messageType == kMessageTo){contentLabelX = kContentStartMargin*0.5;}self.contentLabel.frame = CGRectMake(contentLabelX, -3,self.frame.size.width-kContentStartMargin-5, self.frame.size.height);
}/***  表面上是一个普通的手势,其实内涵乾坤*  这里的乾坤就是表面上是contentView的长按操作*  其实就是为了委托方法的实现*  就相当于textField输入框的代理方法里面,你一输入,调用的却是self.delegate的执行代理方法*/
- (void)longTap:(UILongPressGestureRecognizer *)longTap
{if ([self.delegate respondsToSelector:@selector(chartContentViewLongPress:content:)]){[self.delegate chartContentViewLongPress:self content:self.contentLabel.text];}
}- (void)tapPress:(UILongPressGestureRecognizer *)tapPress
{if ([self.delegate respondsToSelector:@selector(chartContentViewTapPress:content:)]){[self.delegate chartContentViewTapPress:self content:self.contentLabel.text];}
}@end

接下篇!

imitate wechat - 3相关推荐

  1. 广东东软学院安卓实验报告二:“编写聊天APP界面”

    Android schoolwork entertainment app: imitating wechat Software tips: for learning only. The phone n ...

  2. 苹果开源代码中惊现“wechat”,老外注释的吐槽亮了!

    点击上方蓝色"方志朋",选择"设为星标"回复"666"获取独家整理的学习资料! 每个科技大厂的开源项目,几乎都是各领域开发者最重要的研究学习 ...

  3. Ubuntu14.04下安装wechat(微信)

    安装步骤 无意中发现了一个巨牛的人工智能教程,忍不住分享一下给大家.教程不仅是零基础,通俗易懂,而且非常风趣幽默,像看小说一样!觉得太牛了,所以分享给大家.点这里可以跳转到教程 https://www ...

  4. 微信(WeChat)电脑端多开

    0x00 前言 不知道大家有没有多个微信号,我反正有一两三个. 现在电脑端微信使用频率也比较高,主要用于大文件传输,或者手机电脑文件互传等等,除了不能收红包和看朋友圈,貌似电脑端没其他毛病. 哦,还有 ...

  5. Android wechat 分享

    本篇简单介绍Android App中接入wechat分享流程. wechat分享 微信开放平台 1.1 在微信开放平台申请成为开发者 微信开放平台 2.2 创建移动应用 -> 创建成功以后(七天 ...

  6. Zabbix-3.0.3实现微信(WeChat)告警

    Zabbix可以通过多种方式把告警信息发送到指定人,常用的有邮件,短信报警方式,但是越来越多的企业开始使用zabbix结合微信作为主要的告警方式,这样可以及时有效的把告警信息推送到接收人,方便告警的及 ...

  7. WeChat:微信小程序设计流程注册完善、设计开发、审核发布之详细攻略

    WeChat:微信小程序设计流程注册&完善.设计&开发.审核&发布之详细攻略 目录 微信小程序设计流程 1.注册 2.小程序信息完善 3.开发小程序 3.1.开发文档 3.2. ...

  8. WeChat之小工具:基于C++程序代码设计的查看微信撤销、撤回消息(包括文本、图片、视频等)GUI小工具

    WeChat之小工具:基于C++程序代码设计的查看微信撤销.撤回消息(包括文本.图片.视频等)GUI小工具 导读      哈哈,千万不要给程序猿随便发信息,程序猿认真起来,别说你发的微信信息,就连你 ...

  9. why wechat is not a good place for the learning, but csdn is

    it is because there are so many built in functions available at the system however, the wechat, espe ...

  10. 使用docker运行微信wechat的安装脚本

    docker运行wechat,只需要运行下面的脚本即可 #!/usr/bin/env bash # # dochat.sh - Docker WeChat for Linux # # Author: ...

最新文章

  1. 华为atn980传输设备_在头发丝中实现每秒1000张高清DVD传输
  2. 微信小程序点餐+SpringBoot(包括后台)
  3. 2202年了,AI还是不如猫!图灵奖得主Yann LeCun:3大挑战依然无解
  4. 实战:将企业域名解析委派给企业DNS服务器
  5. 5月18发布会,这次TDSQL又有什么大动作?
  6. CentOS7 Firewall NAT 及端口映射
  7. 单片机led闪烁代码_单片机、555实现LED闪烁电路
  8. 我要3万取款机怎么取_自助取款机一天可以取多少,能取出来几万呢?
  9. 1.11 双向神经网络
  10. Vue.js 条件渲染 v-if、v-show、v-else
  11. Bailian2966 时区转换【时区计算】
  12. CentOS 7 安装 Scrapy 记录
  13. Docker详解(十六)——Docker私有化仓库创建
  14. C++ TLV格式解析
  15. 只有韦小宝最适合当产品经理
  16. matlab 线性最小二乘法,matlab_最小二乘法线性和非线性拟合.ppt
  17. 【滤波器】6. 高通滤波器
  18. Minecraft我的世界开服教程
  19. js Deferred的使用
  20. Gaussian 计算静电云图确定吸附位点

热门文章

  1. 城市天际线伊甸园39W人口存档
  2. centos7 文件系统修复
  3. OneDrive免费5T云盘空间
  4. python爬虫学习之爬取169图片网站
  5. 重磅:国家基金委八大学部公布“优先发展领域及主要研究方向”
  6. 生成永不过期的微信群二维码
  7. [Codeforces1148C]Crazy Diamond——构造
  8. 北京的旅游攻略(持续更新中)
  9. 计算机为何引入16进制,计算机内存地址为什么要用16进制数来表示
  10. vue awe-dnd+ant 自定义表格排序显隐