imitate wechat - 3
2015-09-07 21:14
183 查看
重新更新一篇可以说整个工程聊天界面最重要的一part,聊天列表的实现,这里我采用循序渐进的方法来完成学习,我先用setFrame的方法来实现,虽然setFrame方法复杂,但是对整体理解的要求更加高,更能理解面相对象的很多特性,例如封装、类的抽象化、对象消息传参等等重要的知识点。而setFrame的实现也是先实现纯文本的对话形式,当保证文本可以正常无bug的实现后再开枝散叶式地添加语音、图像、视频、表情等等等。而且setFrame的方法必须上网参考别人的起码三种实现,因为不同的代码风格和有一些实现技巧都可以对比对比,并且取其精华去其糟粕。当setFrame可以很好地实现,那么就开始尝试masonry的实现!
纯文本下setFrame方法:
先来看看实现一:
实现的类结构:
Model层的实现:
一:
ChartMessage.h
ChartMessage.m
二:
ChartCellFrame.h
ChartCellFrame.m
View层的实现:
一:
ChartContentViewDelegate.h
二:
ChartContentView.h
ChartContentView.m
接下篇!
纯文本下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; //这里为什么是写死200 NSDictionary* attributes = @{NSFontAttributeName:[UIFont fontWithName:@"HelveticaNeue" size:13]}; CGSize contentSize = [chartMessage.content boundingRectWithSize:CGSizeMake(200, MAXFLOAT) options:NSStringDrawingTruncatesLastVisibleLine | NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:attributes context: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
接下篇!
相关文章推荐
- R语言包_rCharts
- hdu 2602 Bone Collector (0-1背包)
- 数据存储详解(三)---->数据库存储
- DEV控件之ChartControl用法 z
- 只有输入法记得
- 数据库操作(C#)
- win7系统MSC 文件的作用。
- Java中==操作符与equals方法的区别
- Hibernate.initialize(Obj)用法
- HDOJ 4268 Alice and Bob 贪心
- 基础算法(二) ———— 判断一个字符串中的所有字符是否都不
- Atitit.异常的设计原理与 策略处理 java 最佳实践 p93
- [POJ 2492]A Bug's Life[并查集]
- MVC程序设计思想
- Atitit.异常的设计原理与 策略处理 java 最佳实践 p93
- 使用jaxp对比xml进行DOM解析
- 锐捷上网认证常见问题及解决办法
- 程序算法艺术与实践:基础知识之函数的渐近的界
- stock——mantis使用基础
- 火星A+B