美文网首页
简单的聊天页面

简单的聊天页面

作者: 其实你懂De | 来源:发表于2017-03-06 16:13 被阅读104次

    本来公司一直想写商城的项目,可是后台又在做催收系统,这个做完才能开始这个项目。看了一下商城的里面有个简单的和客服聊天的页面。结合环信自己做了一个简单的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自己创建吧 ,不用我说了。
    希望对大家有帮助吧,大家一起学习,一起进步。有不明白的或者我写的不好的地方,大家可以给我评论呦!!!

    相关文章

      网友评论

          本文标题:简单的聊天页面

          本文链接:https://www.haomeiwen.com/subject/unkugttx.html