IOS第九天(2:QQ聊天界面键盘优化 和自动回复)

***********controller.m

#import "HMViewController.h"
#import "HMMessageModel.h"
#import "HMMessageCell.h"
#import "HMMessageFrameModel.h"
@interface HMViewController ()<UITableViewDataSource,UITableViewDelegate,UITextFieldDelegate>
@property (weak, nonatomic) IBOutlet UITextField *inputView;

@property (nonatomic, strong)NSMutableArray *messages;

//自动回复数组
@property (nonatomic, strong)NSDictionary *autoReplay;

@property (weak, nonatomic) IBOutlet UITableView *tableView;
@end

@implementation HMViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    //cell 不可选中
    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 = UITableViewCellSeparatorStyleNone;

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidChangeFrame:) name:UIKeyboardWillChangeFrameNotification object:nil];

    //设置做边距
    self.inputView.leftView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 8, 0)];
    //一直显示
    self.inputView.leftViewMode = UITextFieldViewModeAlways;
}

//懒加载自动回复
- (NSDictionary *)autoReplay
{
    if (_autoReplay == nil) {
        _autoReplay  = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"autoReplay.plist" ofType:nil]];
    }

    return _autoReplay;
}

//点击右下角的send 按钮
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    NSLog(@"-------%@",textField.text);

    //1. 发送一条数据
    [self addmessage:textField.text type:HMMessageModelGatsby];
    //自动回复
    NSString *autoStr = [self autoReplayWithText:textField.text];
    //将自动回复添加成一天聊天信息
    [self addmessage:autoStr type:HMMessageModelJobs];
    //4. 清空表格

    self.inputView.text = @"";//nil

    //直接return yes  即可
    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]) {// 不是空,返回plist对应的数据
            return  self.autoReplay[subStr];
        }
    }

    return @"滚蛋吗0";
}

//添加一条聊天信息

- (void)addmessage:(NSString *)text type:(HMMessageModelType)type
{
    //1. 添加模型数据
    HMMessageModel *msg = [[HMMessageModel alloc]init];

    //设置数据的值
    msg.time = @"16:88";
    msg.text = text;
    msg.type = type;

    //设置内容的frame
    HMMessageFrameModel *fm = [[HMMessageFrameModel alloc]init];
    //将msg 赋值给 fm 中的message
    fm.message = msg;
    [self.messages addObject:fm];

    //2.刷新表格
    [self.tableView reloadData];

    //3. 自动上移
    //移动的位置
    NSIndexPath *path = [NSIndexPath indexPathForRow:self.messages.count - 1 inSection:0];
    //真正去是位置 atSrcollPosition :  滚到位置
    [self.tableView scrollToRowAtIndexPath:path atScrollPosition:UITableViewScrollPositionBottom animated:YES];

}

//    UIKeyboardAnimationCurveUserInfoKey = 7;  动画曲线动画
//    UIKeyboardAnimationDurationUserInfoKey = "0.25"; 动画时间
//    UIKeyboardBoundsUserInfoKey = "NSRect: {{0, 0}, {320, 216}}"; 键盘bounds
//    UIKeyboardCenterBeginUserInfoKey = "NSPoint: {160, 588}";  开始键盘的居中位置
//    UIKeyboardCenterEndUserInfoKey = "NSPoint: {160, 372}";结束键盘的居中位置
//    UIKeyboardFrameBeginUserInfoKey = "NSRect: {{0, 480}, {320, 216}}"; 键盘开始弹出的frame
//    UIKeyboardFrameChangedByUserInteraction = 0;   键盘改变frame
//    UIKeyboardFrameEndUserInfoKey = "NSRect: {{0, 264}, {320, 216}}"; 退出键盘的frame

//    UIKeyboardAnimationCurveUserInfoKey = 7;
//    UIKeyboardAnimationDurationUserInfoKey = "0.25";
//    UIKeyboardBoundsUserInfoKey = "NSRect: {{0, 0}, {320, 216}}";
//    UIKeyboardCenterBeginUserInfoKey = "NSPoint: {160, 372}";
//    UIKeyboardCenterEndUserInfoKey = "NSPoint: {160, 588}";
//    UIKeyboardFrameBeginUserInfoKey = "NSRect: {{0, 264}, {320, 216}}";
//    UIKeyboardFrameChangedByUserInteraction = 0;
//    UIKeyboardFrameEndUserInfoKey = "NSRect: {{0, 480}, {320, 216}}";

//当键盘frame 发生改变的时候调用
- (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];
}

- (NSMutableArray *)messages
{
    if (_messages == nil) {

        NSArray * array = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"messages.plist" ofType:nil]];

        NSMutableArray *messageArr = [NSMutableArray array];
        for (NSDictionary *dict in array) {
            HMMessageModel *messga = [HMMessageModel messageWithDict:dict];

            //取出上一个模型
            HMMessageFrameModel *lastFm = [messageArr lastObject];

            //隐藏时间
            messga.hideTime = [messga.time isEqualToString:lastFm.message.time];

            HMMessageFrameModel *fm = [[HMMessageFrameModel alloc]init];
            fm.message = messga;

            [messageArr addObject:fm];
        }

        _messages = messageArr;
    }

    return _messages;
}
//隐藏状态栏
- (BOOL)prefersStatusBarHidden
{
    return YES;
}

#pragma mark tableview数据源方法
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.messages.count;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    HMMessageFrameModel *model = self.messages[indexPath.row];
    return model.cellH;//cell 的高度
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    //初始化cell
    HMMessageCell *cell = [HMMessageCell messageCellWithTableView:tableView];
    //取出model
    HMMessageFrameModel *model = self.messages[indexPath.row];
    //设置model
    cell.frameMessage = model;

    return cell;
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end
#import <UIKit/UIKit.h>

@interface HMViewController : UIViewController

@end

***cell.h

#import <UIKit/UIKit.h>
@class HMMessageFrameModel;
@interface HMMessageCell : UITableViewCell

+ (instancetype)messageCellWithTableView:(UITableView *)tableview;

//frame 的模型
@property (nonatomic, strong)HMMessageFrameModel *frameMessage;

@end

*****cell.m

#import "HMMessageCell.h"
#import "HMMessageFrameModel.h"
#import "HMMessageModel.h"
#import "Constant.h"
#import "UIImage+ResizImage.h"
@interface HMMessageCell()
//时间
@property (nonatomic, weak)UILabel *time;
//正文
@property (nonatomic, weak)UIButton *textView;
//用户头像
@property (nonatomic, weak)UIImageView *icon;

@end

@implementation HMMessageCell
+ (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;
}

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
       //1.时间
        UILabel *time = [[UILabel alloc]init];
        time.textAlignment = NSTextAlignmentCenter;
        time.font = [UIFont systemFontOfSize:13.0f];
        [self.contentView addSubview:time];
        self.time = time;

        //1.正文
        UIButton *textView = [[UIButton alloc]init];
        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];
        self.textView = textView;

        //1.头像
        UIImageView *icon = [[UIImageView alloc]init];
        [self.contentView addSubview:icon];
        self.icon = icon;

        self.backgroundColor = [UIColor clearColor];

    }
    return self;
}

//设置内容和frame
- (void)setFrameMessage:(HMMessageFrameModel *)frameMessage
{
    _frameMessage = frameMessage;

    HMMessageModel *model = frameMessage.message;

    //1.时间
    self.time.frame = frameMessage.timeF;
    self.time.text = model.time;

    //2.头像
    self.icon.frame = frameMessage.iconF;
    if (model.type == HMMessageModelGatsby) {
        self.icon.image = [UIImage imageNamed:@"Gatsby"];
    }else{
        self.icon.image = [UIImage imageNamed:@"Jobs"];
    }

    //3.正文
    self.textView.frame = frameMessage.textViewF;
    [self.textView setTitle:model.text forState:UIControlStateNormal];

    if (model.type == HMMessageModelGatsby) {
//        [self.textView setBackgroundImage:[self resizeWithImageName:@"chat_send_nor"] forState:UIControlStateNormal];

        [self.textView setBackgroundImage:[UIImage resizeWithImageName:@"chat_send_nor"] forState:UIControlStateNormal];
    }else{
        [self.textView setBackgroundImage:[UIImage resizeWithImageName:@"chat_recive_nor"] forState:UIControlStateNormal];
    }

}

//返回一个可拉伸的图片

@end

medel.h

#import <Foundation/Foundation.h>
typedef enum {
    HMMessageModelGatsby = 0,//Gatsby
    HMMessageModelJobs//Jobs
}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;

@end

model.m

#import "HMMessageModel.h"

@implementation HMMessageModel

- (instancetype)initWithDict:(NSDictionary *)dict
{
    if (self = [super init]) {
        [self setValuesForKeysWithDictionary:dict];
    }

    return self;
}

+ (instancetype)messageWithDict:(NSDictionary *)dict
{
    return [[self alloc] initWithDict:dict];
}

@end

**modelFrame.h

#import <Foundation/Foundation.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,readonly)CGFloat cellH;

//数据模型
@property (nonatomic, strong)HMMessageModel *message;
@end

****modelFrame.m

#import "HMMessageFrameModel.h"
#import "Constant.h"
#import "HMMessageModel.h"
@implementation HMMessageFrameModel

- (void)setMessage:(HMMessageModel *)message
{
    _message = message;

    CGFloat padding = 10;
    //1. 时间
    if (message.hideTime == NO) {
        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);

}

@end

附录:

#define bScreenWidth [[UIScreen mainScreen] bounds].size.width

#define bNormalH 44

#define bIconW 50

#define bIconH 50

#define bBtnFont [UIFont systemFontOfSize:15.0f]

#define bBtnPadding 20

//缩放

#import "UIImage+ResizImage.h"

@implementation UIImage (ResizImage)

+ (UIImage *)resizeWithImageName:(NSString *)name
{
    UIImage *normal = [UIImage imageNamed:name];

    //    CGFloat w = normal.size.width * 0.5f ;
    //    CGFloat h = normal.size.height *0.5f ;

    CGFloat w = normal.size.width*0.5;
    CGFloat h = normal.size.height*0.5;
    //传入上下左右不需要拉升的边距,只拉伸/填铺中间部分
    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
时间: 2024-10-14 08:39:13

IOS第九天(2:QQ聊天界面键盘优化 和自动回复)的相关文章

【iOS开发-65】QQ聊天界面案例:自定义cell、图片拉伸处理、NSNotification通知、键盘与视图移动以及输入框左边缩进处理

(1)案例 (2)源代码于素材下载 http://pan.baidu.com/s/1bnpiBCz (3)总结 --还是代码封装.控制器.视图.模型分别独立.里面还有很多代码可以独立出来整一个类. --如果某一个值只有特定的几个数字,那么可以用枚举来定义,注意命名规范 typedef enum{ WPMessageTypeMe=0, WPMessageTypeOther=1 }WPMessageType; --依然是计算一段文字所占据的宽和高 CGSize textMaxSize=CGSizeM

IOS第九天(1:QQ聊天界面frame模型)

///  控制层 #import "HMViewController.h" #import "HMMessageModel.h" #import "HMMessageCell.h" #import "HMMessageFrameModel.h" @interface HMViewController ()<UITableViewDataSource,UITableViewDelegate> @property (n

IOS第九天(3:QQ聊天界面通知的使用)

#import <Foundation/Foundation.h> #import "Person.h" #import "XQCompany.h" int main(int argc, const char * argv[]) { @autoreleasepool { //初始化两个机构 XQCompany *za = [[XQCompany alloc]init]; za.name = @"珍爱网"; XQCompany *sj

Objective-c——UI基础开发第八天(QQ聊天界面)

一.知识点: QQ聊天界面 双模型的使用(dataModel和frameModel) UITextField的使用 通知的使用 拉伸图片的两种方法(slicing/image对象的resizeableImageWithCapInsets属性) 枚举 方法的抽取(相同的拿出,不同的部分作为参数) 二.设置tableview的基本格式 1)定义tableview基本 numberOfSectionsInTableView:设置块 numberOfRowsInSection:设置每块对应的行数 cel

QQ聊天界面的输入法顶起界面底部输入框效果的实现

转载请注明:http://www.cnblogs.com/frank-zouxu/p/4127115.html 今天在公司做项目的时候遇到一个需求:需要做一个界面,效果类似QQ聊天界面,如图1,当我们点击内容输入框准备输入内容的时候,底部的表情框的那一栏会被输入法的软键盘给顶起来,默认状态下,输入法会覆盖掉我们的表情输入框.起初,百思不得解的我费尽了心思,未果,偶然看到此篇博客http://blog.csdn.net/twoicewoo/article/details/7384398.其实,欲达

亲身体验用Java写的仿qq聊天界面

Java开发工具有许多种,新手用记事本写Java程序,有些人用NetBean,jbuilder,高手用eclipse,下面介绍用eclipse开发qq聊天界面. 代码如下: package Myjava_QQ; import java.awt.*; import javax.swing.*; import Myjava_QQ.truess; import java.awt.event.*; import java.applet.*; import java.io.BufferedReader;

【3】QQ 聊天界面

1.说明 稍微修改了下QQ示例里面的聊天界面界面,然后把代码扣过来完成了QQ聊天界面部分,效果还可以. 2.代码部分 // QQTalk.h文件 #ifndef __QQ_TALK_H__ #define __QQ_TALK_H__ #include <DuiLib/DuiLibEnv.h> #include <DuiLib/UIlib.h> using namespace DuiLib; #define QQ_TALK_XML _T("chatbox.xml"

简单模仿QQ聊天界面

首先看一下最终的效果,显示了消息时间,用户昵称,用户头像. 大致实现方法: 用最简单的ListView显示消息内容. 不同的用户使用不同的消息布局文件,例子有2个用户"Tony","Hill". 代码文件清单: 主布局文件activity_main.xml: 1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools=&

IOS开发学习笔记043-QQ聊天界面实现

QQ聊天界面实现 效果如下: ? ?实现过程: ?1.首先实现基本界面 ? ? ? ? 头像使用 UIImageView : ? ? ? ? 文字消息使用 UIButton ? ? ? ? 标签使用 UILable :水平居中 ? ? ? ? 所有元素在一个cell中,在加载cell时进行判断显示和隐藏. ? ? ? ??合理设置各个控件之间的约束关系.主要是UIIimageVIew和UIButton顶部对齐,间距为10.UIButton的宽度设置一个约束范围,比如说 (>=60 &&