zoukankan      html  css  js  c++  java
  • iOS-QQ自动聊天机器人

    素材有两个一个消息字典,一个自动回复匹配字典 

    首先字典转模型,位置和数据都是模型里面弄好的 加了一个工具方法resizeImage来调整聊天界面

    然后来写自定义cell

    最后在控制器里面写逻辑

     

    //
    //  UIImage+resizeImage.h
    //  QQ聊天
    //
    //  Created by YaguangZhu on 15/8/28.
    //  Copyright (c) 2015年 YaguangZhu. All rights reserved.
    //
    
    #import <UIKit/UIKit.h>
    
    @interface UIImage (resizeImage)
    
    + (UIImage *)resizeWithImageName:(NSString *)name;
    @end
    
    
    ---------------------------------//
    //  UIImage+resizeImage.m
    //  QQ聊天
    //
    //  Created by YaguangZhu on 15/8/28.
    //  Copyright (c) 2015年 YaguangZhu. All rights reserved.
    //
    
    #import "UIImage+resizeImage.h"
    
    @implementation UIImage (resizeImage)
    
    //返回一个可拉伸的图片
    + (UIImage *)resizeWithImageName:(NSString *)name
    {
        UIImage *normal = [UIImage imageNamed:name];
        
        CGFloat w = normal.size.width * 0.5f -1;
        CGFloat h = normal.size.height *0.5f -1;
        
        //CGFloat w = normal.size.width*0.8;
        // CGFloat h = normal.size.height*0.8;
        //传入上下左右不需要拉升的编剧,只拉伸中间部分
        return [normal resizableImageWithCapInsets:UIEdgeInsetsMake(h, w, h, w)];
        
        //    [normal resizableImageWithCapInsets:UIEdgeInsetsMake(<#CGFloat top#>, <#CGFloat left#>, <#CGFloat bottom#>, <#CGFloat right#>)]
        
        // 1 = width - leftCapWidth  - right
        // 1 = height - topCapHeight  - bottom
        
        //传入上下左右不需要拉升的编剧,只拉伸中间部分,并且传入模式(平铺/拉伸)
        //    [normal :<#(UIEdgeInsets)#> resizingMode:<#(UIImageResizingMode)#>]
        
        //只用传入左边和顶部不需要拉伸的位置,系统会算出右边和底部不需要拉升的位置。并且中间有1X1的点用于拉伸或者平铺
        // 1 = width - leftCapWidth  - right
        // 1 = height - topCapHeight  - bottom
        //    return [normal stretchableImageWithLeftCapWidth:w topCapHeight:h];
    }
    @end
    //
    //  Constant.h
    //  QQ聊天
    //
    //  Created by YaguangZhu on 15/8/27.
    //  Copyright (c) 2015年 YaguangZhu. All rights reserved.
    //
    
    #ifndef QQ___Constant_h
    #define QQ___Constant_h
    
    #define bScreenWidth [[UIScreen mainScreen] bounds].size.width
    
    #define bNormalH 44
    
    #define bIconW 50
    
    #define bIconH 50
    
    #define bBtnFont [UIFont systemFontOfSize:15.0f]
    
    #endif
    //
    //  HMMessageModel.h
    //  QQ聊天
    //
    //  Created by YaguangZhu on 15/8/27.
    //  Copyright (c) 2015年 YaguangZhu. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    typedef enum {
        HMMessageModelGatsby =0,
        HMMessageModelJobs
    }HMMessageModeltype;
    
    @interface HMMessageModel : NSObject
    @property(nonatomic,copy) NSString *text;
    @property(nonatomic,copy) NSString *time;
    @property(nonatomic,assign) HMMessageModeltype type;
    
    @property(nonatomic,assign)BOOL hideTime;
    
    - (instancetype)initWithDict:(NSDictionary *)dict;
    
    + (instancetype)messageWithDict:(NSDictionary *)dict;
    
    //+ (NSArray *)Messages;
    
    @end
    
    ---------------------------------//
    //  HMMessageModel.m
    //  QQ聊天
    //
    //  Created by YaguangZhu on 15/8/27.
    //  Copyright (c) 2015年 YaguangZhu. All rights reserved.
    //
    
    #import "HMMessageModel.h"
    
    @implementation HMMessageModel
    - (instancetype)initWithDict:(NSDictionary *)dict
    {
        self = [super init];
        if (self) {
            [self setValuesForKeysWithDictionary:dict];
        }
        return self;
    }
    
    + (instancetype)messageWithDict:(NSDictionary *)dict
    {
        return [[self alloc] initWithDict:dict];
    }
    
    //+ (NSArray *)Messages
    //{
    //    NSArray *array = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"messages.plist" ofType:nil]];
    //    NSMutableArray *arrayM = [NSMutableArray array];
    //    for (NSDictionary *dict in array) {
    //        [arrayM addObject:[self messageWithDict:dict]];
    //    }
    //    
    //    return arrayM;
    //}
    
    @end
    //
    //  HMMessageFrameModel.h
    //  QQ聊天
    //
    //  Created by YaguangZhu on 15/8/27.
    //  Copyright (c) 2015年 YaguangZhu. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    #import <UIKit/UIKit.h>
    @class HMMessageModel;
    @interface HMMessageFrameModel : NSObject
    
    //时间的frame
    @property (nonatomic, assign,readonly)CGRect timeF;
    
    //正文的frame
    @property (nonatomic, assign,readonly)CGRect textViewF;
    
    //图片
    @property (nonatomic, assign,readonly)CGRect iconF;
    
    //cell
    @property (nonatomic, assign)CGFloat cellH;
    
    //数据模型
    @property (nonatomic, strong)HMMessageModel *message;
    
    + (NSArray *)messageFrame;
    
    @end
    
    ---------------------------------
    //
    //  HMMessageFrameModel.m
    //  QQ聊天
    //
    //  Created by YaguangZhu on 15/8/27.
    //  Copyright (c) 2015年 YaguangZhu. All rights reserved.
    //
    
    #import "HMMessageFrameModel.h"
    #import "HMMessageModel.h"
    #import "Constant.h"
    
    @implementation HMMessageFrameModel
    
    - (void)setMessage:(HMMessageModel *)message
    {
        _message = message;
        
        CGFloat padding = 10;
        if (message.hideTime ==NO) {
            //1. 时间
            CGFloat timeX = 0;
            CGFloat timeY = 0;
            CGFloat timeW = bScreenWidth;
            CGFloat timeH = bNormalH;
            
            _timeF = CGRectMake(timeX, timeY, timeW, timeH);
    
        }
        
        //2.头像
        CGFloat iconX;
        CGFloat iconY = CGRectGetMaxY(_timeF);
        CGFloat iconW = bIconW;
        CGFloat iconH = bIconH;
        
        if (message.type == HMMessageModelGatsby) {//自己发的
            
            iconX = bScreenWidth - iconW - padding;
            
        }else{//别人发的
            iconX = padding;
        }
        
        _iconF =  CGRectMake(iconX, iconY, iconW, iconH);
        //3.正文
        
        CGFloat textX;
        CGFloat textY = iconY+padding;
        
        CGSize textMaxSize = CGSizeMake(150, MAXFLOAT);
        CGSize textRealSize = [message.text boundingRectWithSize:textMaxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:bBtnFont} context:nil].size;
        
        CGSize btnSize = CGSizeMake(textRealSize.width+40, textRealSize.height+40);
        if (message.type == HMMessageModelGatsby) {
            textX = bScreenWidth - iconW - padding*2 - btnSize.width;
        }else{
            textX = padding + iconW;
        }
        
        //    _textViewF = CGRectMake(textX, textY, <#CGFloat width#>, <#CGFloat height#>)
        _textViewF = (CGRect){{textX,textY},btnSize};
        
        //4.cell高度
        
        CGFloat iconMaxY = CGRectGetMaxY(_iconF);
        CGFloat textMaxY = CGRectGetMaxY(_textViewF);
        
        _cellH = MAX(iconMaxY, textMaxY);
    }
    
    
    + (NSArray *)messageFrame
    {
        NSArray *array = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"messages.plist" ofType:nil]];
        
        NSMutableArray *arrayM = [NSMutableArray array];
        for (NSDictionary *dict in array) {
            // 要添加statusFrame对象
            HMMessageFrameModel *frameModel = [[HMMessageFrameModel alloc] init];
            
            // 实例化一个新的Status模型
            HMMessageModel *messageModel = [HMMessageModel messageWithDict:dict];
            
            HMMessageFrameModel *lastModel = [arrayM lastObject];
            
            messageModel.hideTime = [messageModel.time isEqualToString:lastModel.message.time];
            
            // 调用自己的setter方法,保存status数据模型,同时计算出所有控件的位置
            frameModel.message = messageModel;
            
            // 将statusFrame添加到数组
            [arrayM addObject:frameModel];
        }
        
        return arrayM;
    }
    @end
    //
    //  HMMessageCell.h
    //  QQ聊天
    //
    //  Created by YaguangZhu on 15/8/27.
    //  Copyright (c) 2015年 YaguangZhu. All rights reserved.
    //
    
    #import <UIKit/UIKit.h>
    //@class HMMessageModel;
    @class HMMessageFrameModel;
    @interface HMMessageCell : UITableViewCell
    
    + (instancetype)messageCellWithTableView:(UITableView *)tableview;
    
    //@property(nonatomic,strong) HMMessageModel *messageModel;
    
    // frame 的模型
    @property(nonatomic,strong) HMMessageFrameModel *frameModel;
    
    
    
    @end
    
    
    ---------------------------------
    //
    //  HMMessageCell.m
    //  QQ聊天
    //
    //  Created by YaguangZhu on 15/8/27.
    //  Copyright (c) 2015年 YaguangZhu. All rights reserved.
    //
    
    #import "HMMessageCell.h"
    #import "HMMessageModel.h"
    #import "HMMessageFrameModel.h"
    #import "Constant.h"
    #import "UIImage+resizeImage.h"
    
    /** 姓名字体 */
    #define kNameFont   [UIFont systemFontOfSize:14]
    /** 正文字体 */
    #define kTextFont   [UIFont systemFontOfSize:16]
    
    @interface HMMessageCell()
    @property(nonatomic,strong)UILabel *time;
    @property(nonatomic,strong)UIButton *textView;
    @property(nonatomic,strong)UIImageView *icon;
    @end
    @implementation HMMessageCell
    
    - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
    {
        self = [super initWithStyle:nil reuseIdentifier:nil];
        self.backgroundColor = [UIColor clearColor];
        
        return self;
    }
    
    + (instancetype)messageCellWithTableView:(UITableView *)tableview
    {
        static NSString *ID = @"messageCell";
        HMMessageCell *cell = [tableview dequeueReusableCellWithIdentifier:ID];
        if (cell == nil) {
            cell = [[self alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
        }
        
        return cell;
    }
    
    - (UILabel *)time
    {
        if (_time ==nil) {
            _time = [[UILabel alloc]init];
            _time.textAlignment = NSTextAlignmentCenter;
            _time.font = [UIFont systemFontOfSize:13.0f];
            [self.contentView addSubview:_time];
        }
        return _time;
    }
    
    - (UIButton *)textView
    {
        if (_textView == nil) {
            _textView = [[UIButton alloc]init];
            //_textView.backgroundColor = [UIColor grayColor];
            _textView.titleLabel.font = bBtnFont;
            _textView.titleLabel.numberOfLines = 0;//自动换行
            _textView.contentEdgeInsets = UIEdgeInsetsMake(20, 20, 20, 20);
            [_textView setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
            [self.contentView addSubview:_textView];
    
        }
        return _textView;
    }
    
    - (UIImageView *)icon
    {
        if (_icon ==nil) {
            _icon = [[UIImageView alloc] init];
            [self.contentView addSubview:_icon];
        }
        return _icon;
    }
    //可以通过数据模型来设置数据和位置,也可以通过位置模型来设置数据和位置
    
    
    - (void)setFrameModel:(HMMessageFrameModel *)frameModel
    {
        _frameModel = frameModel;
        
        HMMessageModel *messageModel = frameModel.message;
        
        //1.时间
        self.time.frame = frameModel.timeF;
        self.time.text = messageModel.time;
        
        //2.头像
        self.icon.frame = frameModel.iconF;
        if (messageModel.type == HMMessageModelGatsby) {
            self.icon.image = [UIImage imageNamed:@"Gatsby"];
        }else{
            self.icon.image = [UIImage imageNamed:@"Jobs"];
        }
        
        //3.正文
        self.textView.frame = frameModel.textViewF;
        [self.textView setTitle:messageModel.text forState:UIControlStateNormal];
        
      
        
        if (messageModel.type == HMMessageModelGatsby) {
            [self.textView setBackgroundImage:[UIImage resizeWithImageName:@"chat_send_nor"] forState:UIControlStateNormal];
        }else
        {
             [self.textView setBackgroundImage:[UIImage resizeWithImageName:@"chat_recive_nor"] forState:UIControlStateNormal];
        }
    }
    
    
    
    
    
    
    
    - (void)awakeFromNib {
        // Initialization code
    }
    
    - (void)setSelected:(BOOL)selected animated:(BOOL)animated {
        [super setSelected:selected animated:animated];
    
        // Configure the view for the selected state
    }
    
    @end
    //
    //  ViewController.h
    //  QQ聊天
    //
    //  Created by YaguangZhu on 15/8/27.
    //  Copyright (c) 2015年 YaguangZhu. All rights reserved.
    //
    
    #import <UIKit/UIKit.h>
    
    @interface ViewController : UIViewController
    
    
    @end
    
    ----------------------------------
    
    //
    //  ViewController.m
    //  QQ聊天
    //
    //  Created by YaguangZhu on 15/8/27.
    //  Copyright (c) 2015年 YaguangZhu. All rights reserved.
    //
    
    #import "ViewController.h"
    #import "HMMessageModel.h"
    #import "HMMessageCell.h"
    #import "HMMessageFrameModel.h"
    
    @interface ViewController ()<UITabBarControllerDelegate,UITableViewDataSource,UITextFieldDelegate>
    //@property(nonatomic,strong) NSArray *messages;
    @property(nonatomic,strong) NSMutableArray *messagesFrame;
    @property (weak, nonatomic) IBOutlet UITextField *inputView;
    
    @property (weak, nonatomic) IBOutlet UITableView *tableView;
    
    //自动回复数组
    @property (nonatomic, strong)NSDictionary *autoReplay;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
        self.tableView.allowsSelection = NO;
        
        self.tableView.backgroundColor = [UIColor colorWithRed:225/255.0 green:225/255.0 blue:225/255.0 alpha:1.0];
        
        self.tableView.separatorStyle =UITableViewCellEditingStyleNone;
        
        
        [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(keyboardDidChangeFrame:) name:UIKeyboardDidChangeFrameNotification object:nil];
        
        //设置做边距
        self.inputView.leftView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 8, 0)];
        //一直显示
        self.inputView.leftViewMode = UITextFieldViewModeAlways;
        
        }
    
    //点击右下角的send 按钮
    - (BOOL)textFieldShouldReturn:(UITextField *)textField
    {
        NSLog(@"-------%@",textField.text);
        [self addMessage:textField.text type:HMMessageModelGatsby];
        
        
        //自动回复
        NSString *autoStr = [self autoReplayWithText:textField.text];
        //将自动回复添加成一天聊天信息
        [self addMessage:autoStr type:HMMessageModelJobs];
        //4. 清空表格
        
        self.inputView.text = @"";//nil
        
        
        
           return YES;
    }
    
    
    //自动回复一条聊天信息
    
    - (NSString *)autoReplayWithText:(NSString *)text
    {
        //3自动回复
        for (int a = 0 ; a < text.length; a++) {
            
            NSString *subStr = [text substringWithRange:NSMakeRange(a, 1)];
            
            if (self.autoReplay[subStr]) {
                return  self.autoReplay[subStr];
            }
        }
        
        return @"滚蛋吗0";
    }
    
    - (void)addMessage:(NSString *)text type:(HMMessageModeltype)type
    {
        HMMessageModel *msg = [[HMMessageModel alloc]init];
        msg.time = @"17:25";
        msg.text = text;
        msg.type = type;
        
        HMMessageFrameModel *fm = [[HMMessageFrameModel alloc]init];
        fm.message =msg;
        [self.messagesFrame addObject:fm];
        
        [self.tableView reloadData];
        //3. 自动上移
        //移动的位置
        NSIndexPath *path = [NSIndexPath indexPathForRow:self.messagesFrame.count - 1 inSection:0];
        //真正去是位置 atSrcollPosition :  滚到位置
        [self.tableView scrollToRowAtIndexPath:path atScrollPosition:UITableViewScrollPositionBottom animated:YES];
        
       
    }
    
    - (void)keyboardDidChangeFrame:(NSNotification *)noti
    {
        NSLog(@"--------%@",noti.userInfo);
        
        //改变window的背景颜色
        self.view.window.backgroundColor = self.tableView.backgroundColor;
        
        //最终键盘的frame
        CGRect frame = [noti.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
        
        //键盘实时y
        CGFloat keyY = frame.origin.y;
        
        //屏幕的高度
        CGFloat screenH = [[UIScreen mainScreen] bounds].size.height;
        
        //动画时间
        CGFloat keyDuration = [noti.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue];
        
        //执行动画
        [UIView animateWithDuration:keyDuration animations:^{
            self.view.transform = CGAffineTransformMakeTranslation(0, keyY - screenH);
        }];
    
    }
    
    //当tableview 滚动的时候 结束编辑事件  (退出键盘)
    - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
    {
        [self.view endEditing:YES];
    }
    
    //-(NSArray *)messages
    //{
    //    if (_messages == nil) {
    //        _messages = [HMMessageModel messages];
    //    }
    //    return _messages;
    //}
    - (NSArray *)messagesFrame
    {
        if (_messagesFrame == nil) {
            _messagesFrame = [HMMessageFrameModel messageFrame];
        }
        return _messagesFrame;
    }
    
    //懒加载自动回复文件
    - (NSDictionary *)autoReplay
    {
        if (_autoReplay == nil) {
            _autoReplay  = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"autoReplay.plist" ofType:nil]];
        }
        return _autoReplay;
    }
    
    //隐藏状态栏
    - (BOOL)prefersStatusBarHidden
    {
        return YES;
    }
    
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
        return self.messagesFrame.count;
    }
    
    - (UITableViewCell * )tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
    //    static NSString *ID =@"cell";
    //    
    //    HMMessageCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    //    
    //    if (cell ==nil) {
    //        cell = [[HMMessageCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
    //        
    //    }
        
        HMMessageCell *cell = [HMMessageCell messageCellWithTableView:tableView];
    
       // cell.messageModel =self.messages[indexPath.row];
        
        HMMessageFrameModel *model = self.messagesFrame[indexPath.row];
        
        cell.frameModel =model;
        
           return cell;
       
        
    }
    
    #pragma mark - 代理方法
    /** 计算单元格行高 */
    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        /**
         计算行高的方法,会在加载表格数据时,有多少行计算多少次 contentSize
         
         问题:此方法执行的时候,cell还没有被实例化!
         但是:行高计算是在实例化cell时,通过设置status属性,计算的=>有了status模型,就可以知道行高!
         
         问题:如何在cell实例化之前,获得行高?
         解决方法:通过status可以计算得到行高!=》再建立一个模型,专门计算所有控件的位置
         */
        
    //    HMMessageFrameModel *messageFrame1 = [[HMMessageFrameModel alloc] init];
    //    messageFrame1.message =self.messagesFrame[indexPath.row];
    //    return messageFrame1.cellH;
        
        HMMessageFrameModel *messageFrame1 = self.messagesFrame[indexPath.row];
           return messageFrame1.cellH;
        
        //return 200;
    }
    
    
    
    
    @end
  • 相关阅读:
    青花瓷Java版
    让Broncho A1支持usbnet
    系统程序员成长计划组合的威力(三)
    【转】多CPU上的原子操作
    c#和javascript交互
    修改代码时有时会出现找不到某个组件
    UML用例建模的慨念和应用
    DJ曲二
    查询数据库里的存储过程的文本中的某个内容
    UML静态建模
  • 原文地址:https://www.cnblogs.com/zhuyaguang/p/4766986.html
Copyright © 2011-2022 走看看