简单的聊天页面

本来公司一直想写商城的项目,可是后台又在做催收系统,这个做完才能开始这个项目。看了一下商城的里面有个简单的和客服聊天的页面。结合环信自己做了一个简单的IM聊天页面。

2.gif

利用了环信的框架,写了个登录注册添加好友的功能。环信还是很好用的,他有自己封装好的IM连天界面,自己处理一下就好了。但是再好的东西也是有不足。有些东西还是满足不了客户的需求。以前也没做过聊天的功能。先学习了简单的页面开始。废话不多说,开始吧!
今天我们主要讲聊天的页面是怎么实现的。


3029240E-B4A9-40BF-A9F9-EE92244AE914.png

也就是这个界面。看是简单,好了 我们开始吧!!!
大家都知道这是用tableView实现的,首先你要先写个tableView,然后自定个tableViewCell,上面的一些控件需要我们自己根据数据的类型我们来判断。这些大致的思路,上代码。

7BD8901B-C25C-4A43-95F4-DBDE387E91D0.png

这是聊天页面需要的一些类。两个类目分别封装了处理聊天字体的自适应和处理气泡的方法。
处理字体自适应的方法NSStrin+Extension
.h

//测量文本的尺寸
- (CGSize)sizeWithFont:(UIFont *)font maxSize:(CGSize)maxSize;

.m

-(CGSize)sizeWithFont:(UIFont *)font maxSize:(CGSize)maxSize {
    CGSize size = [self boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:font} context:nil].size;
    return size;
}

处理气泡拉伸的方法UIImage+Extension
.h

+ (UIImage *)resizableImage:(NSString *)imageName;

.m

+(UIImage *)resizableImage:(NSString *)imageName {
    UIImage *imge = [UIImage imageNamed:imageName];
    //取图片部分的1 × 1拉伸
    UIEdgeInsets insets = UIEdgeInsetsMake(imge.size.height / 2, imge.size.width / 2, imge.size.height / 2 + 1, imge.size.width / 2 + 1);
    return [imge resizableImageWithCapInsets:insets];
}

自定义cell
.h

@class JYJ_Message;
#define MESSAGE_TIME_FONT [UIFont systemFontOfSize:13]
#define MESSAGE_TEXT_FONT [UIFont systemFontOfSize:15]
#define TEXT_INSET 20
@interface JYJ_CustomChatTableViewCell : UITableViewCell
@property (nonatomic, strong) JYJ_Message *message;//我们需要处理的数据

既然我们自定义的cell里面出现了数据,我们先说一下数据
.h

//枚举类型
typedef enum {
    JYJMeessageTyMe = 0,
    JYJ_MessageTyOther = 1,
} JYJ_MessageType;
@interface JYJ_Message : NSObject
/**内容  */
@property (nonatomic, strong) NSString *text;

/** 时间 */
@property (nonatomic, strong) NSString *time;

/** 类型 */
@property (nonatomic, assign) JYJ_MessageType type;

/** <cellHeight> */
@property (nonatomic, assign) CGFloat cellHeight;
/** 是否隐藏时间 */

@property (nonatomic, assign) BOOL hideTime;

- (instancetype) initWithDictionary:(NSDictionary *) dictionary;
+ (instancetype) messageWithDictionary:(NSDictionary *) dictionary;
+ (instancetype) message;


.m

- (instancetype) initWithDictionary:(NSDictionary *) dictionary {
    if (self = [super init]) {
        [self setValuesForKeysWithDictionary:dictionary];
    }
    
    return self;
}

+ (instancetype) messageWithDictionary:(NSDictionary *) dictionary {
    return [[self alloc] initWithDictionary:dictionary];
}

+ (instancetype) message {
    return [self messageWithDictionary:nil];
}
- (void)setValue:(id)value forUndefinedKey:(NSString *)key {
    
}

其实大部分的代码都是我们自定义的cell里面,里面的一些判断和计算。不要忘记把我们自己封装的方法引进来

#import "NSString+Extension.h"
#import "UIImage+Extension.h"

cell的.m 我们在延展中写的一些属性

@interface JYJ_CustomChatTableViewCell ()
//时间
@property (nonatomic, strong) UILabel *timeLabel;
/** 头像 */
@property(nonatomic, weak) UIImageView *iconView;

/** 信息 */
@property(nonatomic, weak) UIButton *textView;


@end

下面开始了长篇大论

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
    if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
        [self createSubViews];
    }
    return self;
}
- (void)createSubViews {
    self.timeLabel = [[UILabel alloc]init];
    [self.contentView addSubview:_timeLabel];
    self.timeLabel.textColor = [UIColor whiteColor];
    // 2.头像
    UIImageView *iconView = [[UIImageView alloc] init];
    [self.contentView addSubview:iconView];
    self.iconView = iconView;
    
    // 3.信息
    UIButton *textView = [UIButton buttonWithType:UIButtonTypeCustom];
    [textView setTitle:@"text" forState:UIControlStateNormal];
    
    textView.titleLabel.font = [UIFont systemFontOfSize:13];
    // 3.1 如果是浅色背景,记得设置字体颜色,因为按钮的字体颜色默认是白色
    [textView setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    [textView.titleLabel setNumberOfLines:0]; // 设置自动换行
    
    // 3.2 调整文字的内边距
    textView.contentEdgeInsets = UIEdgeInsetsMake(20, 20, 20, 20);
    
    [self.contentView addSubview:textView];
    self.textView = textView;

    
   
}
- (void)setMessage:(JYJ_Message *)message {
    _message = message;
    
    // 间隙
    CGFloat padding = 10;
    
    // 1.发送时间
    if ( message.hideTime == NO) {
        [self.timeLabel mas_makeConstraints:^(MASConstraintMaker *make) {
            make.centerX.mas_equalTo(self.mas_centerX);
            make.top.equalTo(self.mas_top).offset(0);
        }];
        self.timeLabel.text = message.time;
    }
    
    // 2.头像
    CGFloat iconWidth = 40;
    CGFloat iconHeight = 40;
    
    // 2.1 根据信息的发送方调整头像位置
    CGFloat iconX;
    if ( message.type ==JYJMeessageTyMe) {
        // 我方,放在右边
        iconX = [UIScreen mainScreen].bounds.size.width - padding - iconWidth;
        self.iconView.image = [UIImage imageNamed:@"me"];
    } else {
        // 对方,放在左边
        iconX = padding;
        self.iconView.image = [UIImage imageNamed:@"other"];
    }
    
    CGFloat iconY = CGRectGetMaxY(_timeLabel.frame) + padding;
    _iconView.frame = CGRectMake(iconX, iconY, iconWidth, iconHeight);
    
    // 3.信息,尺寸可变
    CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width;
    // 3.1 设置文本最大尺寸
    CGSize textMaxSize = CGSizeMake(screenWidth - iconWidth - padding * 10, MAXFLOAT);
    // 3.2 计算文本真实尺寸
    CGSize textRealSize = [message.text sizeWithFont:MESSAGE_TEXT_FONT maxSize:textMaxSize];
    
    // 3.3 按钮尺寸
    CGSize btnSize = CGSizeMake(textRealSize.width + TEXT_INSET*2, textRealSize.height + TEXT_INSET*2);
    
    // 3.4 调整信息的位置
    //  设置聊天框
    NSString *chatImageNormalName;
    NSString *chatImageHighlightedName;

    CGFloat textX;
    if (message.type == JYJMeessageTyMe) {
        // 我方,放在靠右
        textX = CGRectGetMinX(_iconView.frame) - btnSize.width - padding;
        chatImageNormalName = @"chat_send_nor";
        chatImageHighlightedName = @"chat_send_press_pic";
    } else {
        // 对方,放在靠左
        textX = CGRectGetMaxX(_iconView.frame) + padding;
        chatImageNormalName = @"chat_recive_nor";
        chatImageHighlightedName = @"chat_receive_press_pic";
    }
    UIImage *chatImageNormal = [UIImage resizableImage:chatImageNormalName];
    UIImage *chatImageHighlighted = [UIImage resizableImage:chatImageHighlightedName];
    [self.textView setBackgroundImage:chatImageNormal forState:UIControlStateNormal];
    [self.textView setBackgroundImage:chatImageHighlighted forState:UIControlStateHighlighted];
    CGFloat textY = iconY;
    _textView.frame = CGRectMake(textX, textY, btnSize.width, btnSize.height);
    [self.textView setTitle:message.text forState:UIControlStateNormal];
    // 4.cell的高度
    CGFloat iconMaxY = CGRectGetMaxY(_iconView.frame);
    CGFloat textMaxY = CGRectGetMaxY(_textView.frame);
    message.cellHeight = MAX(iconMaxY, textMaxY) + padding;
}

好了所有的处理基本完毕。我写了一个本地的数据用plist文件存储的,当然也是看网上那么写的我们copy了过来。

屏幕快照 2017-03-06 下午4.01.07.png

其实自己写一条就好,不用往里面写那么多。
在VC中处理数据

- (void)handale {
    NSArray *dictArray = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"messages.plist" ofType:nil]];
    
    NSMutableArray *mdictArray = [NSMutableArray array];
    for (NSDictionary *dict in dictArray) {
        JYJ_Message *message = [JYJ_Message messageWithDictionary:dict];
        
        // 判断是否发送时间与上一条信息的发送时间相同,若是则不用显示了
        
        if ([mdictArray lastObject]&&[message.time isEqualToString:[self.messages lastObject]]) {
            message.hideTime = YES;
        }
        
        
        [mdictArray addObject:message];
    }
    
    _messages = mdictArray;
    [self.tableView reloadData];

}

处理返回cell的高度

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    JYJ_Message *message = self.messages[indexPath.row];
    return message.cellHeight;
}

下面是处理点击回车自己发送信息的处理 textFiled别忘了签代理

// TextFiled代理方法
//回车响应事件
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    if ([self.bottomView.inPutTextField.text isEqualToString:@""]) {
        NSLog(@".....");
    }
    else {
        //我方发出信息
        [self sendMessage:textField.text andType:JYJMeessageTyMe];
        //自动回复
        [self sendMessage:[NSString stringWithFormat:@"%@\n%@",textField.text,@"你妹!"] andType:JYJ_MessageTyOther];
        
        //消息框清除
        self.bottomView.inPutTextField.text = nil;
        [self.tableView reloadData];
        //滚动到最新信息
        NSIndexPath *lastIndePath = [NSIndexPath indexPathForRow:self.messages.count - 1 inSection:0];
        [self.tableView scrollToRowAtIndexPath:lastIndePath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
    }
    return YES;
}

- (void)sendMessage:(NSString *)text andType:(JYJ_MessageType)type {
    //获取当前时间
    NSDate *date = [NSDate date];
    NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
    formatter.dateFormat = @"yyyy-MMM-dd hh:mm:ss";
    NSString *dateStr = [formatter stringFromDate:date];
        // 我方发出信息
    NSDictionary *dic = @{@"text":text,
                           @"time":dateStr,
                           @"type":[NSString stringWithFormat:@"%d",type]};
    
    JYJ_Message *message = [[JYJ_Message alloc]init];
    [message setValuesForKeysWithDictionary:dic];
    [self.messages addObject:message];
}

还有VC最下面的View自己创建吧 ,不用我说了。
希望对大家有帮助吧,大家一起学习,一起进步。有不明白的或者我写的不好的地方,大家可以给我评论呦!!!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,340评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,762评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,329评论 0 329
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,678评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,583评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,995评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,493评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,145评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,293评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,250评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,267评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,973评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,556评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,648评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,873评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,257评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,809评论 2 339

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,251评论 25 707
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 11,975评论 4 60
  • 同是过路,同做过梦 本应是一对 人在少年,梦中不觉 醒后要归去 三餐一宿,也共一双 到底会是谁 但凡未得到 但凡是...
    新城旧梦似水流年阅读 689评论 3 2
  • 说话并不是一件容易事。一生说了那么多的话,今天明白得看人去,生人若不注意分际,诚意太多了也会丢了品性。 一位青年先...
    MrZhong005阅读 197评论 0 1
  • hello world 如何?知道我是做什么的了吧?
    清风小牛阅读 201评论 0 0