数据模型:

#import <Foundation/Foundation.h>typedef enum{LLMessageTypeMe,LLMessageTypeOther
}LLMessageType;@interface LLMessage : NSObject/***  time*/
@property (nonatomic, copy) NSString *time;/***  text*/
@property (nonatomic, copy) NSString *text;/***  type 定义为枚举类型的好处*/
@property (nonatomic, assign) LLMessageType type;/***  hiddenTime 时间是否隐藏*/
@property (nonatomic, assign, getter=isHiddenTime) BOOL hiddenTime;- (instancetype)initWithDic:(NSDictionary *)dic;
+ (instancetype)messageWithDic:(NSDictionary *)dic;+ (NSMutableArray *)messageList;@end

#import "LLMessage.h"@implementation LLMessage- (instancetype)initWithDic:(NSDictionary *)dic
{if (self = [super init]) {[self setValuesForKeysWithDictionary:dic];}return self;
}+ (instancetype)messageWithDic:(NSDictionary *)dic
{return [[self alloc] initWithDic:dic];
}+ (NSMutableArray *)messageList
{NSString *path = [[NSBundle mainBundle] pathForResource:@"messages" ofType:@"plist"];NSArray *dicArr = [NSArray arrayWithContentsOfFile:path];NSMutableArray *tmpArr = [[NSMutableArray alloc] initWithCapacity:dicArr.count];for (NSDictionary *dic in dicArr) {LLMessage *endMessage = [tmpArr lastObject];LLMessage *message = [LLMessage messageWithDic:dic];if ([message.time isEqualToString:endMessage.time]) {message.hiddenTime = YES;}[tmpArr addObject:message];}return tmpArr;
}@end

frame模型

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#define LLTIMEFONT [UIFont systemFontOfSize:12]
#define LLTEXTFONT [UIFont systemFontOfSize:13]
#define LLPADDING 20
@class LLMessage;
@interface LLMessageFrame : NSObject@property (nonatomic, strong) LLMessage *message;@property (nonatomic, assign,readonly) CGRect timeF;@property (nonatomic, assign, readonly) CGRect textF;@property (nonatomic, assign, readonly) CGRect iconF;@property (nonatomic, assign, readonly) CGFloat cellHeight;+ (NSMutableArray *)messageFrameList;@end

#import "LLMessageFrame.h"
#import "LLMessage.h"
#import "NSString+LLNSStringExtension.h"
@implementation LLMessageFrame+ (NSMutableArray *)messageFrameList
{NSMutableArray *messageArr = [LLMessage messageList];NSMutableArray *tmpArray = [[NSMutableArray alloc] initWithCapacity:messageArr.count];for (LLMessage *message in messageArr) {LLMessageFrame *frame = [[LLMessageFrame alloc] init];frame.message = message;[tmpArray addObject:frame];}return tmpArray;
}- (void)setMessage:(LLMessage *)message
{_message = message;CGFloat margin = 10;// 时间CGFloat timeX = 0;CGFloat timeY = 0;CGFloat timeW = 320;CGFloat timeH = 40;if (!message.isHiddenTime){_timeF = CGRectMake(timeX, timeY, timeW, timeH);}// iconCGFloat iconY = CGRectGetMaxY(_timeF);CGFloat iconWH = 30;CGFloat iconX;if (message.type == LLMessageTypeMe) { // Me
        iconX = timeW - iconWH - margin;} else { // Other
        iconX = margin;}_iconF = CGRectMake(iconX, iconY, iconWH, iconWH);// textCGFloat textY = iconY;CGSize textSize = [message.text textOfSize:CGSizeMake(200, MAXFLOAT) font:LLTEXTFONT];CGSize buttonSize = CGSizeMake(textSize.width + LLPADDING * 2, textSize.height + LLPADDING * 2);CGFloat textX;if (message.type == LLMessageTypeMe) { // Me
        textX = iconX - margin - buttonSize.width;} else {textX = CGRectGetMaxX(_iconF) + margin;}_textF = (CGRect){{textX, textY} , buttonSize};CGFloat textMaxY = CGRectGetMaxY(_textF);CGFloat iconMaxY = CGRectGetMaxY(_iconF);_cellHeight = MAX(textMaxY, iconMaxY);}@end

代码自定义cell

#import <UIKit/UIKit.h>
@class LLMessageFrame;
@interface LLMessageCell : UITableViewCell@property (nonatomic, strong) LLMessageFrame *messageFrame;+ (instancetype)messageCellWith:(UITableView *)tableView;@end

#import "LLMessageCell.h"
#import "LLMessageFrame.h"
#import "LLMessage.h"
#import <UIKit/UIKit.h>
#import "UIImage+LLUIImageExtension.h"
@interface LLMessageCell ()@property (nonatomic, weak) UILabel *timeView;
@property (nonatomic, weak) UIImageView *iconView;
@property (nonatomic, weak) UIButton *textView;@end@implementation LLMessageCell+ (instancetype)messageCellWith:(UITableView *)tableView
{static NSString *ID = @"messageCell";LLMessageCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];if (!cell) {cell = [[LLMessageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];}return cell;
}- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {// 创建cell子控件self.backgroundColor = [UIColor clearColor];// timeUILabel *timeView = [[UILabel alloc] init];[self.contentView addSubview:timeView];timeView.textAlignment = NSTextAlignmentCenter;timeView.font = LLTIMEFONT;self.timeView = timeView;// iconUIImageView *iconView = [[UIImageView alloc] init];[self.contentView addSubview:iconView];self.iconView = iconView;// textUIButton *textView = [[UIButton alloc] init];[self.contentView addSubview: textView];textView.titleLabel.font = LLTEXTFONT;textView.titleLabel.numberOfLines = 0;textView.contentEdgeInsets = UIEdgeInsetsMake(LLPADDING, LLPADDING, LLPADDING, LLPADDING);self.textView = textView;}return self;
}- (void)setMessageFrame:(LLMessageFrame *)messageFrame
{_messageFrame = messageFrame;// 1,设置数据
    [self setDate];// 2,设置frame
    [self setSubviewsFrame];
}- (void)setDate
{LLMessage *message = self.messageFrame.message;self.timeView.text = message.time;NSString *iconName = message.type == LLMessageTypeMe ? @"me" : @"other";self.iconView.image = [UIImage imageNamed:iconName];// 设置图片背景#warning 设置按钮上label字体方法[self.textView setTitle:message.text forState:UIControlStateNormal];if (message.type == LLMessageTypeMe) {[self.textView setBackgroundImage:[UIImage registerImage:@"chat_send_nor"] forState:UIControlStateNormal];[self.textView setBackgroundImage:[UIImage registerImage:@"chat_send_press_pic"] forState:UIControlStateHighlighted];[self.textView setTitleColor:[UIColor redColor] forState:UIControlStateNormal];} else {[self.textView setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];[self.textView setBackgroundImage:[UIImage registerImage:@"chat_recive_nor"] forState:UIControlStateNormal];[self.textView setBackgroundImage:[UIImage registerImage:@"chat_recive_press_pic"] forState:UIControlStateHighlighted];}
}- (void)setSubviewsFrame
{self.timeView.frame = self.messageFrame.timeF;self.iconView.frame = self.messageFrame.iconF;self.textView.frame = self.messageFrame.textF;
}@end

分类:NSString

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>@interface NSString (LLNSStringExtension)- (CGSize)textOfSize:(CGSize)maxSize font:(UIFont *)font;@end#import "NSString+LLNSStringExtension.h"@implementation NSString (LLNSStringExtension)- (CGSize)textOfSize:(CGSize)maxSize font:(UIFont *)font
{return [self boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName : font} context:nil].size;
}@end

UIImage分类

#import <UIKit/UIKit.h>@interface UIImage (LLUIImageExtension)+ (UIImage *)registerImage:(NSString *)imageName;@end#import "UIImage+LLUIImageExtension.h"
#import <UIKit/UIKit.h>
@implementation UIImage (LLUIImageExtension)+ (UIImage *)registerImage:(NSString *)imageName
{UIImage * image = [UIImage imageNamed:imageName];return [image stretchableImageWithLeftCapWidth:image.size.width * 0.5 topCapHeight:image.size.height * 0.5];
}@end

controller:

#import "ViewController.h"
#import "LLMessageFrame.h"
#import "LLMessage.h"
#import "LLMessageCell.h"@interface ViewController () <UITableViewDataSource, UITableViewDelegate, UITextFieldDelegate>@property (nonatomic, strong) NSMutableArray *messageFrames;@property (weak, nonatomic) IBOutlet UITableView *tableView;@property (weak, nonatomic) IBOutlet UIView *footerView;
@property (weak, nonatomic) IBOutlet UITextField *textField;@end@implementation ViewController#pragma mark - 懒加载数据模型
- (NSMutableArray *)messageFrames
{if (!_messageFrames) {_messageFrames = [LLMessageFrame messageFrameList];}return _messageFrames;
}- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view, typically from a nib.// 隐藏分割线self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;// 取消tableView的点击self.tableView.allowsSelection = NO;self.tableView.backgroundColor = [UIColor colorWithRed:240/255.0 green:224/255.0 blue:224/255.0 alpha:1.0];// 监听通知[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(clickTextFiled:) name:UIKeyboardWillChangeFrameNotification object:nil];// 设置文本框左边内容默认有间距self.textField.leftView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 8, 0)];self.textField.leftViewMode = UITextFieldViewModeAlways;
}- (void)clickTextFiled:(NSNotification *)noti
{CGRect rect = [noti.userInfo[@"UIKeyboardFrameEndUserInfoKey"] CGRectValue];CGFloat moveY = rect.origin.y - self.view.frame.size.height;self.view.transform = CGAffineTransformMakeTranslation(0, moveY);
}- (void)dealloc
{[[NSNotificationCenter defaultCenter] removeObserver:self];
}#pragma mark - 数据源方法
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{return self.messageFrames.count;
}- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{// 1,创建cellLLMessageCell *cell = [LLMessageCell messageCellWith:tableView];// 2,设置cellcell.messageFrame = self.messageFrames[indexPath.row];return cell;
}#pragma mark - 代理方法
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{return [self.messageFrames[indexPath.row] cellHeight];
}- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{[self.view endEditing:YES];
}#pragma mark - 文本框代理方法
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{LLMessageFrame *frame = [[LLMessageFrame alloc] init];LLMessage *message = [[LLMessage alloc] init];NSDate *date = [NSDate date];NSDateFormatter *formatter = [[NSDateFormatter alloc] init];formatter.dateFormat = @"hh:mm";NSString *time = [formatter stringFromDate:date];message.time = time;message.text = textField.text;message.type = LLMessageTypeMe;LLMessageFrame *lastMF = [self.messageFrames lastObject];if ([lastMF.message.time isEqualToString:message.time]) {message.hiddenTime = YES;}frame.message = message;[self.messageFrames addObject:frame];// 刷新
    [self.tableView reloadData];// 自动上滚NSIndexPath *path = [NSIndexPath indexPathForRow:self.messageFrames.count - 1 inSection:0];[self.tableView scrollToRowAtIndexPath:path atScrollPosition:UITableViewScrollPositionBottom animated:YES];textField.text = nil;return YES;
}- (BOOL)prefersStatusBarHidden
{return YES;
}@end

效果;

转载于:https://www.cnblogs.com/-boy/p/4133663.html

UI基础之UITableView案例QQ聊天界面相关推荐

  1. C语言实现类似QQ聊天界面抖动功能

    该博文为原创文章,未经博主同意不得转载,如同意转载请注明博文出处 本文章博客地址:https://cplusplus.blog.csdn.net/article/details/104991863 实 ...

  2. 点击跳转到QQ聊天界面

    <!--//需要添加好友验证--><a href="tencent://message/?uin=QQ号码&Site=&Menu=yes"> ...

  3. gui编程实践(2)--qq聊天界面 JTextArea多行文本框组件

    //qq聊天界面 package com.test; import java.awt.*; import javax.swing.*; public class Demo8_10 extends JF ...

  4. 【3】QQ 聊天界面

    1.说明 稍微修改了下QQ示例里面的聊天界面界面,然后把代码扣过来完成了QQ聊天界面部分,效果还可以. 不过自己添加了消息响应:窗口抖动,截屏,字体栏的显示和隐藏 2.代码部分 // QQTalk.h ...

  5. qt小项目 代码实现简易的QQ聊天界面

    qt小项目 代码实现简易的QQ聊天界面 代码 效果图 总结 代码 myDialog.h #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QW ...

  6. QQ聊天界面的布局和设计(IOS篇)-第二季

    QQChat Layout - 第二季 本来第二季是快写好了, 也花了点功夫, 结果gitbook出了点问题, 给没掉了.有些细节可能会一带而过, 如有疑问, 相互交流进步~. 在第一季中我们完成了Q ...

  7. 防qq聊天界面纯HTML5,html5 实现qq聊天的气泡效果

    教程:http://m.blog.csdn.net/blog/yhc13429826359/38778337 写的很好.自己实现的时候,由于img float:left,会脱离文档流,导致结构混乱. ...

  8. UI界面编写(仿QQ聊天界面)

    UI界面编写实战 这里我们模拟QQ聊天的主界面,编写一个简单的聊天界面. 项目描述 首先搭建我们的主界面,在最上边放一个标题栏,然后是一个ListView,用于展示发送的消息,最下边是选择要发送的表情 ...

  9. android布局基础及范例:QQ登陆界面设计

    使用android手机的用户想必都有android手机QQ客户端吧,我们是不是觉得QQ登陆界面非常漂亮美观而且具有亲和力?我们是不是也想作出像 QQ那样美观的界面?有的人肯定会问,做UI那不是美工人员 ...

最新文章

  1. Win10 + ubuntu16双系统安装以及cuda,cudnn安装
  2. Android与JS混编(js调用android相机扫描二维码)
  3. office软件的发展前景_2018年办公软件产业发展趋势
  4. python 两个乘号是什么_(2)Python 变量和运算符
  5. 2021年中国大学生程序设计竞赛 女生专场 - 热身赛 Problem C. 口算训练(质因子分解)
  6. 吉林省统考计算机英语作文,2019年吉林省学位英语作文必背范文(我最……的题材) - 希赛网...
  7. 515Nod 1126 求递推序列的第n项【矩阵快速幂】
  8. (三)Java中的HashMap与HashTable的区别
  9. 疑似Bug:简书安卓10.7首页搜索关键字屏蔽敏感词不彻底
  10. 荔枝派Nano 全流程指南
  11. Anaconda 踩过的一些坑
  12. 叉乘点乘混合运算公式_七(上)数学:有理数混合运算常考题型笔记100%整理,收藏+学习...
  13. 5月31日武汉国金天地亮灯仪式鎏光绽放!
  14. chrome 打包安装插件
  15. LeetCode 319 灯泡开关[数学] HERODING的LeetCode之路
  16. linux Xinetd服务简介
  17. word表格分页时怎样能自动生成表头
  18. Android 仿朋友圈,文字图片视频多条目,自动播放暂停
  19. 目标检测算法中ROI提取方法比较+源码分析
  20. [MySQL数据库]-基础多表练习题---员工工资

热门文章

  1. 连接目标数据库+无恢复目录连接目标数据库+使用有恢复目录连接目标数据库+注册数据库+目录同步+取消目标数据库的连接...
  2. BZOJ2301: [HAOI2011]Problem b[莫比乌斯反演 容斥原理]【学习笔记】
  3. 小试牛刀:文本处理工具之grep、egrep详解
  4. 后续:为LAMP添加XCache加速。
  5. 利用ping/ipconfig/nslookup/dig/whois简单工具测试DNS
  6. css3中的渐变效果及花斑动画的实现
  7. Navigator对象
  8. Js中RegExp对象
  9. 想唱你就唱卡拉ok_如何将电唱机与其他设备连接起来
  10. 开源 三层模型_开源模型将如何超越其他模型