标签:
用到的技术:自定义cell,通知机制,代理模式 transform
1.自定义cell(通过代码自定义cell)
①首先新建一个类继承UITableViewCell
②重写initWithStyle:reuseIdentifier方法
这里只需要把所有要显示的子控件添加到contenView中,在这一步一般不需要设置属性的, 但是如果是一些子控件中一些静态的属性,字需要一次性设置的话,就在这里 设置,在重写frameSet方法的时候在把一些比较动态的数据填充上去以及设置
每个子控件的frame
③提供两个模型
数据模型:存放数据
frame模型:通过拿到数据模型来计算每一个空间的frame,并设置为readOnly
2.通知机制
由此可见,我们可以这样认为 ,在一个程序运行过程中,有很多控件向通知中心发送通知,而我们可以随时随地的接收想要的通知,这点类似于代理,但是区别于的代理的是,通知比代理灵活,而且通知是多对多关系,一个对象可以告诉N个对象发生什么事情,一个对象能得知N个对象发生什么事情,而代理是一对一关系,一个对象只能告诉一个对象发生什么事情。
通知发布
- (void)postNotificationName:(NSString *)aName object:(id)anObject userInfo:(NSDictionary *)aUserInfo; //发布一个名称为aName的通知,anObject为这个通知的发布者,aUserInfo为额外信息
通知监听
通知中心提供方法来注册一个监听通知的监听器(换言之就是,将自定义通知公之于世)
- (void)addObserver:(id)observer selector:(SEL)aSelector name:(NSString *)aName object:(id)anObject; /** observer:监听器,即谁要接收这个通知 aSelector:收到通知后,回调监听器的这个方法,并且把通知对象当做参数传入 aName:通知的名称。如果为nil,那么无论通知的名称是什么,监听器都能收到这个通知 anObject:通知发布者。如果为anObject和aName都为nil,监听器都收到所有的通知*/
取消注册监听器
/* 通知中心不会保留(retain)监听器对象,在通知中心注册过的对象,必须在该对象释放前取消注册。否则,当相应的通知再次出现时,通知中心仍然会向该监听器发送消息。因为相应的监听器对象已经被释放了,所以可能会导致应用崩溃 通知中心提供了相应的方法来取消注册监听器 */ - (void)removeObserver:(id)observer; - (void)removeObserver:(id)observer name:(NSString *)aName object:(id)anObject; //一般在监听器销毁之前取消注册(如在监听器中加入下列代码): - (void)dealloc { //[super dealloc]; 非ARC中需要调用此句 [[NSNotificationCenter defaultCenter] removeObserver:self]; }
通知监听
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChangeFrame:) name:UIKeyboardWillChangeFrameNotification object:nil];
3 代理模式
简单步骤就是:一个协议 一个返回实现该协议的id类型的delegate 还有就是 在使用短实现协议,并且实现协议的方法
难点:自定义cell,聊天图片的无变化拉伸,键盘的监听
思路:新建模型一个计算位置的,一个填充数据的
新建View.用于显示每一个cell里面的数据m
细节:
/** * 数据模型 * MessageDataModel.m */ @implementation MessageDataModel +(instancetype)messageWithDict:(NSDictionary *)dict{ return [[self alloc] initWithDict:dict]; } -(instancetype)initWithDict:(NSDictionary *)dict{ if(self = [super init]){ [self setValuesForKeysWithDictionary:dict]; } return self; } @end
/** * 位置模型 * MessageFrameData.m */ #define MJTextFont [UIFont systemFontOfSize:15] #import "MessageFrameData.h" #import "MessageDataModel.h" @implementation MessageFrameData -(void)setMessage:(MessageDataModel *)message { _message = message; // 间距 CGFloat padding = 10; // 屏幕的宽度 CGFloat screenW = [UIScreen mainScreen].bounds.size.width; NSLog(@"==========%f",screenW); // 时间布局 if(!message.hideTime){ CGFloat timeX = 0; CGFloat timeY = 0; CGFloat timeW = screenW; CGFloat timeH = 40; _timeF = CGRectMake(timeX, timeY, timeW, timeH); } // 头像布局 CGFloat iconY = CGRectGetMaxY(_timeF)+padding; CGFloat iconW = 40; CGFloat iconH = 40; CGFloat iconX; if(message.type == MessageTypeOther){//别人发的 iconX = padding; } else{//自己发的 iconX = screenW - padding -iconW; } _iconF = CGRectMake(iconX, iconY, iconW, iconH); // 正文 CGFloat textY = iconY; // 能显示的最大size CGSize textMaxSize = CGSizeMake(150, MAXFLOAT); // 文本的真实size CGSize textSize = [self sizeWithText:message.text font:MJTextFont maxSize:textMaxSize]; // 最终确定的size; CGSize textBtnSize = CGSizeMake(textSize.width+ TextPadding*2, textSize.height+ TextPadding*2); CGFloat textX; if(message.type == MessageTypeOther){ textX = CGRectGetMaxX(_iconF)+padding; } else{ textX = iconX - padding -textBtnSize.width; } _textF = (CGRect){{textX,textY},textBtnSize}; // _textF = CGRectMake(textX, textY, textSize.width, textSize.height); CGFloat textMaxY = CGRectGetMaxY(_textF); CGFloat iconMaxY = CGRectGetMaxY(_iconF); _cellHeight = MAX(textMaxY, iconMaxY) + padding; } /** * 计算文字尺寸 * * @param text 需要计算尺寸的文字 * @param font 文字的字体 * @param maxSize 文字的最大尺寸 */ - (CGSize)sizeWithText:(NSString *)text font:(UIFont *)font maxSize:(CGSize)maxSize { NSDictionary *attrs = @{NSFontAttributeName : font}; return [text boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:attrs context:nil].size; } @end
/** * 自定义cell,用于填充数据和设置frame */ #define MJTextFont [UIFont systemFontOfSize:15] #import "QQQViewCellTableViewCell.h" #import "MessageDataModel.h" #import "UIImage+Extension.h" @interface QQQViewCellTableViewCell() //内容 @property (nonatomic, weak) UIButton *textView; //发送时间 @property (nonatomic, weak) UIImageView *iconView; @property (nonatomic, weak)UILabel *timeView; @end @implementation QQQViewCellTableViewCell /** * 重写 */ -(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { // 先调用父类方法 self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; if (self){ // 子空间的创建和初始化 // 时间 UILabel *timeView = [[UILabel alloc] init]; timeView.textAlignment = NSTextAlignmentCenter; timeView.textColor = [UIColor grayColor]; timeView.font = [UIFont systemFontOfSize:13]; [self.contentView addSubview:timeView]; self.timeView = timeView; // 头像 UIImageView *iconView = [[UIImageView alloc] init]; [self.contentView addSubview:iconView]; self.iconView = iconView; // 正文 UIButton *textView = [[UIButton alloc] init]; textView.titleLabel.numberOfLines = 0; // textView.backgroundColor = [UIColor grayColor]; textView.titleLabel.font = MJTextFont; [textView setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; // 设置内边距 textView.contentEdgeInsets = UIEdgeInsetsMake(TextPadding, TextPadding, TextPadding, TextPadding); [self.contentView addSubview:textView]; self.textView = textView; // 设置cell的背景颜色 self.backgroundColor = [UIColor clearColor]; } return self; } //这是布局 -(void)setModel:(MessageFrameData *)model { _model = model; MessageDataModel *message = model.message; // 时间 self.timeView.text = message.time; self.timeView.frame = model.timeF; // 头像 NSString *icon = (message.type == MessageTypeOther)?@"other":@"me"; self.iconView.image = [UIImage imageNamed:icon]; self.iconView.frame = model.iconF; // 正文 [self.textView setTitle:message.text forState:UIControlStateNormal]; self.textView.frame = model.textF; // 设置正文背景图 if (message.type == MessageTypeMe){ [self.textView setBackgroundImage:[UIImage resizableImage:@"chat_send_nor"] forState:UIControlStateNormal]; } else{ [self.textView setBackgroundImage:[UIImage resizableImage:@"chat_recive_nor"] forState:UIControlStateNormal]; } } +(instancetype)cellWithTableView:(UITableView *)tableView{ static NSString *ID = @"qqmessage"; QQQViewCellTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; if(cell == nil){ cell = [[QQQViewCellTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID]; } return cell; } @end
标签:
原文地址:http://www.cnblogs.com/superYou/p/4227498.html