zoukankan      html  css  js  c++  java
  • 即使通讯聊天界面搭建----iOS

    一直想把即使聊天的界面搭建做个总结 写在博客上,没抽出时间,今天有点时间 先写一部分,估计也不会写太多,会随时更新。

    首先确定需求。项目中聊天只涉及到 纯文本、纯图片、语音消息的功能,所以在聊天的界面中会存在这么个消息类型的结构体

    typedef enum {
     
        kImageContent = 0, //代表收到的或者是发出的图片
        kAudioContent = 1, //代表语音
        kTextContent = 2,   //代表文字
    
    /*
    以下类型是根据项目需求来的
    */
        kNotice = 3,  //通知
        kQuestion = 4,//问题
        kReQuestion = 5,//回答问题
        kVideo = 6//视频分享
        
    }ChatMessageContentType;

    当然还要区分消息的发送者和接收者

    typedef enum {
     
        kMessageFrom = 0, //表示收到的
        kMessageTo = 1    //表示发出的 
    }ChatMessageType;

    首先从最基础的界面开始分析。首先聊天界面用tableview来做最好不过了,很多方法我们都可以那系统提供的来用,省去不少代码量。用tablview来做最重要的界面当然是cell

    初始化cell,初始确定cell两端各有一个头像,判断是收到的消息还是发送的消息来确定显示还是隐藏,中间部分显示一个时间,中间是聊天的具体内容。那么大体的架子出来了 我比较习惯手写代码,下面给出的代码:

    -(void)initBaseView{
     
        _timelabel = [[UILabel alloc] initWithFrame:CGRectMake((SCREEN_WITH -100)/2, 5, 100, 20)];
        _timelabel.text = @"刚刚";
        _timelabel.textColor = [UIColor lightGrayColor];
        _timelabel.textAlignment = NSTextAlignmentCenter;
        _timelabel.font = [UIFont systemFontOfSize:11];
        [self addSubview:_timelabel];
        
        _headIcon = [[UIImageView alloc] initWithFrame:CGRectMake(5, 25, 40, 40)];
        _headIcon.image = [UIImage imageNamed:@"1.jpeg"];
        NSString *userid = [[BaseInfo shareBaseInfo]getUserId];
        _headIcon.image = [MyController getImageWithUserId:userid];
        _headIcon.layer.cornerRadius = 5;
        _headIcon.clipsToBounds = YES;
        [self addSubview:_headIcon];
        
        _chatMessageView = [[ChatContentView alloc] initWithFrame:CGRectMake(50, 25, SCREEN_WITH-100, 40)];
        [self addSubview:_chatMessageView];
    }

    上面代码中ChatContentView是自定义的一个聊天内容视图

    #import <UIKit/UIKit.h>
    
    #import "ChatMessageModel.h"
    @interface ChatContentView : UIView
    
    @property (nonatomic,copy) ChatMessageModel *message;
    @property (nonatomic,assign) CGFloat cellHeight;//cell的高度
    @property (nonatomic,strong) UILabel *contentLabel;//文字消息内容
    @property (nonatomic,strong) UIImageView *chatMessageBgView;//聊天背景图
    //图片消息
    @property (nonatomic,strong)UIImageView *messageImage;
    //聊天内容背景图片
    @property (nonatomic,copy)   NSString *bgImageStr;
    
    -(CGRect)refreshContentViewWithModel:(ChatMessageModel *)content;
    //回答问题
    @property (nonatomic,retain)UIButton *answerBtn;
    @end

    注:关于里面的方法 除了 语音消息添加了回调,其他都没有添加

            _chatMessageBgView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)];
    //        _chatMessageBgView.backgroundColor = [UIColor greenColor];
            [self addSubview:_chatMessageBgView];
            _contentLabel = [[UILabel alloc] initWithFrame:CGRectMake(3, 5, frame.size.width-6, frame.size.height-10)];
    //        _contentLabel.backgroundColor = [UIColor redColor];
            _contentLabel.font = [UIFont fontWithName:@"HelveticaNeue" size:13];
            _contentLabel.numberOfLines = 0;
            [self addSubview:_contentLabel];
            
            _answerBtn = [UIButton buttonWithType:UIButtonTypeCustom];
            _answerBtn.frame = CGRectMake(5, _contentLabel.frame.origin.y+_contentLabel.frame.size.height, frame.size.width-30, 40);
            _answerBtn.backgroundColor = [MyController colorWithHexString:@"8fd06a"];
            _answerBtn.hidden = YES;
            [_answerBtn setTitle:@"马上回答" forState:UIControlStateNormal];
            [_answerBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
            _answerBtn.layer.cornerRadius = 5;
            [self addSubview:_answerBtn];
            
            _messageImage = [[UIImageView alloc] initWithFrame:_contentLabel.frame];
    //        _messageImage.backgroundColor = [UIColor orangeColor];
            [self addSubview:_messageImage];

    上面这是chatview的基本布局 最重要的方法是h文件中的

    -(CGRect)refreshContentViewWithModel:(ChatMessageModel *)content;因为我们是根据聊天的具体内容来做视图的自适应的。

    然后来说下 聊天内容的model重要的部分刚开始已经说过了,要确定消息的来源和消息的类型

    typedef enum {
     
        kMessageFrom = 0, //表示收到的
        kMessageTo = 1    //表示发出的 
    }ChatMessageType;
    typedef enum {
     
        kImageContent = 0, //代表收到的或者是发出的图片
        kAudioContent = 1, //代表语音
        kTextContent = 2,   //代表文字
        kNotice = 3,  //通知
        kQuestion = 4,//问题
        kReQuestion = 5,//回答问题
        kVideo = 6//视频分享
        
    }ChatMessageContentType;
    #import <UIKit/UIKit.h>
    #import <Foundation/Foundation.h>
    
    @interface ChatMessageModel : NSObject
    @property (nonatomic,strong) UIImage *messageImage;
    @property (nonatomic,assign) ChatMessageType messageType;
    @property (nonatomic,assign) ChatMessageContentType contentType;
    @property (nonatomic,copy)   NSString *contentStr;
    @property (nonatomic,copy) NSString *audioPath;
    
    @property (nonatomic,retain)NSMutableArray *cellImageArr;
    @end

    最重要的部分来了 ,收到消息后要对界面进行处理 满足适应界面 不管是文字还是图片或者语音,大同小异,都是要计算出合适的高度去适应视图

    以图片为例,我这是把图片固定位一个固定的宽高

    -(CGRect)refreshContentViewWithModel:(ChatMessageModel *)content{
     
        CGRect rect;
        if(content.contentType == kImageContent){
            //图片
            _messageImage.alpha = 1;
            _contentLabel.alpha = 0;
            if(content.messageType == kMessageFrom){
                rect = CGRectMake(50, 25, 100, 150);
                _chatMessageBgView.frame = CGRectMake(0, 0, rect.size.width, rect.size.height);
                _messageImage.frame = CGRectMake(20, 10, rect.size.width-30, rect.size.height-30);
            }else{
                rect = CGRectMake(SCREEN_WITH-50-80, 25, 80, 100);
                _chatMessageBgView.frame = CGRectMake(0, 0, rect.size.width, rect.size.height);
                _messageImage.frame = CGRectMake(10, 5, rect.size.width-30, rect.size.height-20);
            }
                _chatMessageBgView.image = [UIImage strethBgImageWith:self.bgImageStr];
                _messageImage.image = content.messageImage;
            return rect;
        }

    其他的内容与之类似 就不用多说了 代码写的简单粗暴 见谅吧各位

    cell中有如下这个方法是用来确定聊天内容的

    -(CGRect)cofigCellWithChatMessage:(ChatMessageModel *)chatModel{
     
        //这是我收到的
        if(chatModel.messageType == kMessageFrom){
            _chatMessageView.bgImageStr = @"chatfrom_bg_normal";
        }else{
            //这是我发的
            _chatMessageView.bgImageStr = @"chatto_bg_normal";
            _headIcon.frame = CGRectMake(SCREEN_WITH-45, 25, 40, 40);
            _headIcon.image = [MyController getImageWithUserId:[[BaseInfo shareBaseInfo]getUserId]];
        }
        if(chatModel.contentType == kAudioContent){
         
            UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(playAudio)];
            path = chatModel.audioPath;
            [_chatMessageView addGestureRecognizer:tap];
        }else if (chatModel.contentType == kQuestion){
          
            
        }
        CGRect chatRect = [_chatMessageView refreshContentViewWithModel:chatModel];
        _chatMessageView.frame = chatRect;
        CGRect cellFrame = CGRectMake(0, 0, SCREEN_WITH, 30+chatRect.size.height);
        
        //任务
        if(chatModel.contentType == kNotice){
        //布置任务
        _chatMessageView.frame = CGRectMake(15, 25, SCREEN_WIDTH-30, 30);
        _chatMessageView.contentLabel.frame = CGRectMake(5, 5, _chatMessageView.frame.size.width-10, 30);
        _chatMessageView.contentLabel.layer.cornerRadius = 5;
        _chatMessageView.contentLabel.layer.borderWidth = 0.5;
        _chatMessageView.contentLabel.layer.borderColor = [UIColor lightGrayColor].CGColor;
            _headIcon.alpha = 0;
        cellFrame = CGRectMake(0, 0, SCREEN_WIDTH, 55);
        }
        return cellFrame;
    }

    至于主界面 就是cell的显示 数据的显示 另外一点就是 发送完消息,视图要滑动到当前的行数

    -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
        
        MicroVideoCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ID"];
        if(!cell){
            cell = [[MicroVideoCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"ID"];
        }
        if(dataArr.count!=0){
            
            [cell configWithModel:[dataArr objectAtIndex:indexPath.row]];
        }
        return cell;
    }
    -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
        VideoDetailViewController *detail = [[VideoDetailViewController alloc] init];
        [self.navigationController pushViewController:detail animated:YES];
    }

    发送消息的时候如下传值 以发送文本消息为例子

        
        ChatMessageModel *model = [[ChatMessageModel alloc] init];
        model.messageType = kMessageTo;
        model.contentStr = message;
        model.contentType =kTextContent;
        [cellArr addObject:model];
        [chatList reloadData];
        [self tableViewScrollCurrentIndexPath];

    基本效果如下

    由于代码集成到项目里了 没有demo可以提供。。。

    说的简单点了,我觉得有必要说的部分已经写上了 有不明白了再小窗吧,今天先说到这了。。。慢慢补充和改进

    聊天学习来源于http://code4app.com/ios/%E4%BB%BFQQ%E8%81%8A%E5%A4%A9%E5%B8%83%E5%B1%80/52bb03bfcb7e8434288b4a38

     

  • 相关阅读:
    游戏开发之路小结(二):关于第一人称射击游戏开发实战小结
    游戏开发之路小结(一):关于太空射击游戏开发实战小结
    游戏开发要涉及的几个方面
    短短几行代码实现让摄像机跟随着物体效果
    关于移动设备几种屏幕输入方式的小结
    软件的体系架构摘要
    jQuery入门笔记之(一)选择器引擎-【转】
    ASCII码对照表
    将数字转出大写如:100转换后结果为一佰
    google搜索技巧总结
  • 原文地址:https://www.cnblogs.com/machealking/p/4665280.html
Copyright © 2011-2022 走看看