020606-07-聊天布局

//  XMGChatingViewController.m
//  07-聊天布局
#import "XMGChatingViewController.h"
#import "XMGMessage.h"
#import "XMGMessageCell.h"
//#import "XMGMeCell.h"
//#import "XMGOtherCell.h"

@interface XMGChatingViewController () <UITableViewDataSource, UITableViewDelegate>
@property (nonatomic, strong) NSArray *messages;
@property (weak, nonatomic) IBOutlet UITextField *messageField;
@end

@implementation XMGChatingViewController

- (NSArray *)messages
{
    if (_messages == nil) {
        // 加载plist中的字典数组
        NSString *path = [[NSBundle mainBundle] pathForResource:@"messages.plist" ofType:nil];
        NSArray *dictArray = [NSArray arrayWithContentsOfFile:path];

        // 字典数组 -> 模型数组
        NSMutableArray *messageArray = [NSMutableArray array];
        // 用来记录上一条消息模型
        XMGMessage *lastMessage = nil;
        for (NSDictionary *dict in dictArray) {
            XMGMessage *message = [XMGMessage messageWithDict:dict];
            message.hideTime = [message.time isEqualToString:lastMessage.time];
            [messageArray addObject:message];

            lastMessage = message;
        }

        _messages = messageArray;
    }
    return _messages;
}

- (void)viewDidLoad {
    [super viewDidLoad];

    // 设置文本框左边的内容
    UIView *leftView = [[UIView alloc] init];
    leftView.frame = CGRectMake(0, 0, 10, 0);
    self.messageField.leftView = leftView;
    self.messageField.leftViewMode = UITextFieldViewModeAlways;

    // 监听键盘通知
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChangeFrame:) name:UIKeyboardWillChangeFrameNotification object:nil];
}

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

#pragma mark - 键盘处理
- (void)keyboardWillChangeFrame:(NSNotification *)note {
    // 取出键盘最终的frame
    CGRect rect = [note.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
    // 取出键盘弹出需要花费的时间
    double duration = [note.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
    // 修改transform
    [UIView animateWithDuration:duration animations:^{
        CGFloat ty = [UIScreen mainScreen].bounds.size.height - rect.origin.y;
        self.view.transform = CGAffineTransformMakeTranslation(0, - ty);
    }];
}

#pragma mark - <UITableViewDataSource>
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.messages.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // 取出模型
    XMGMessage *msg = self.messages[indexPath.row];

    // 重用标识(决定了cell的类型)
    NSString *ID = (msg.type == XMGMessageTypeMe) ? @"me" : @"other";

    // 加载cell
    XMGMessageCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];

    cell.message = msg;

    return cell;

//    if (msg.type == XMGMessageTypeMe) {
//        static NSString *ID = @"me";
//        // 加载cell
//        XMGMeCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
//
//        cell.message = msg;
//
//        return cell;
//    } else {
//        static NSString *ID = @"other";
//        // 加载cell
//        XMGOtherCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
//
//        cell.message = msg;
//
//        return cell;
//    }
}

#pragma mark - <UITableViewDelegate>
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 200;
}

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

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
    // 退出键盘
//    [self.messageField resignFirstResponder];
//    [self.messageField endEditing:YES];
    [self.view endEditing:YES];
}
@end
//  XMGMessageCell.h
//  07-聊天布局
#import <UIKit/UIKit.h>
@class XMGMessage;

@interface XMGMessageCell : UITableViewCell
@property (nonatomic, strong) XMGMessage *message;
@end
//  XMGMessageCell.m
//  07-聊天布局
#import "XMGMessageCell.h"
#import "XMGMessage.h"
//define this constant if you want to use Masonry without the ‘mas_‘ prefix
#define MAS_SHORTHAND
//define this constant if you want to enable auto-boxing for default syntax
#define MAS_SHORTHAND_GLOBALS
#import "Masonry.h"

@interface XMGMessageCell()
@property (weak, nonatomic) IBOutlet UILabel *timeLabel;
@property (weak, nonatomic) IBOutlet UIButton *textButton;
@property (weak, nonatomic) IBOutlet UIImageView *iconView;
@end

@implementation XMGMessageCell

- (void)awakeFromNib
{
    self.textButton.titleLabel.numberOfLines = 0;
}

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

    // 时间处理
    if (message.hideTime) { // 隐藏时间
        self.timeLabel.hidden = YES;
        [self.timeLabel updateConstraints:^(MASConstraintMaker *make) {
            make.height.equalTo(0);
        }];
    } else { // 显示时间
        self.timeLabel.text = message.time;
        self.timeLabel.hidden = NO;
        [self.timeLabel updateConstraints:^(MASConstraintMaker *make) {
            make.height.equalTo(21);
        }];
    }

    // 处理显示的消息文字
    // 设置按钮的文字
    [self.textButton setTitle:self.message.text forState:UIControlStateNormal];

    // 强制更新
    [self layoutIfNeeded];

    // 设置按钮的高度就是titleLabel的高度
    [self.textButton updateConstraints:^(MASConstraintMaker *make) {
        CGFloat buttonH = self.textButton.titleLabel.frame.size.height + 30;
        make.height.equalTo(buttonH);
    }];

    // 强制更新
    [self layoutIfNeeded];

    // 计算当前cell的高度
    CGFloat buttonMaxY = CGRectGetMaxY(self.textButton.frame);
    CGFloat iconMaxY = CGRectGetMaxY(self.iconView.frame);
    self.message.cellHeight = MAX(buttonMaxY, iconMaxY) + 10;
}
@end
//  XMGMeCell.h
//  07-聊天布局
#import <UIKit/UIKit.h>
@class XMGMessage;

@interface XMGMeCell : UITableViewCell
@property (nonatomic, strong) XMGMessage *message;
@end
//  XMGMeCell.m
//  07-聊天布局
#import "XMGMeCell.h"
#import "XMGMessage.h"
//define this constant if you want to use Masonry without the ‘mas_‘ prefix
#define MAS_SHORTHAND
//define this constant if you want to enable auto-boxing for default syntax
#define MAS_SHORTHAND_GLOBALS
#import "Masonry.h"

@interface XMGMeCell()
@property (weak, nonatomic) IBOutlet UILabel *timeLabel;
@property (weak, nonatomic) IBOutlet UIButton *textButton;
@property (weak, nonatomic) IBOutlet UIImageView *iconView;
@end

@implementation XMGMeCell
- (void)awakeFromNib
{
    self.textButton.titleLabel.numberOfLines = 0;
}

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

    // 时间处理
    if (message.hideTime) { // 隐藏时间
        self.timeLabel.hidden = YES;
        [self.timeLabel updateConstraints:^(MASConstraintMaker *make) {
            make.height.equalTo(0);
        }];
    } else { // 显示时间
        self.timeLabel.text = message.time;
        self.timeLabel.hidden = NO;
        [self.timeLabel updateConstraints:^(MASConstraintMaker *make) {
            make.height.equalTo(21);
        }];
    }

    // 处理显示的消息文字
    // 设置按钮的文字
    [self.textButton setTitle:self.message.text forState:UIControlStateNormal];

    // 强制更新
    [self.textButton layoutIfNeeded];

    // 设置按钮的高度就是titleLabel的高度
    [self.textButton updateConstraints:^(MASConstraintMaker *make) {
        CGFloat buttonH = self.textButton.titleLabel.frame.size.height + 30;
        make.height.equalTo(buttonH);
    }];

    // 强制更新
    [self.textButton layoutIfNeeded];

    // 计算当前cell的高度
    CGFloat buttonMaxY = CGRectGetMaxY(self.textButton.frame);
    CGFloat iconMaxY = CGRectGetMaxY(self.iconView.frame);
    self.message.cellHeight = MAX(buttonMaxY, iconMaxY) + 10;
}
@end
//  XMGOtherCell.h
//  07-聊天布局
#import <UIKit/UIKit.h>
@class XMGMessage;

@interface XMGOtherCell : UITableViewCell
@property (nonatomic, strong) XMGMessage *message;
@end
//  XMGOtherCell.m
//  07-聊天布
#import "XMGOtherCell.h"
#import "XMGMessage.h"
//define this constant if you want to use Masonry without the ‘mas_‘ prefix
#define MAS_SHORTHAND
//define this constant if you want to enable auto-boxing for default syntax
#define MAS_SHORTHAND_GLOBALS
#import "Masonry.h"

@interface XMGOtherCell()
@property (weak, nonatomic) IBOutlet UILabel *timeLabel;
@property (weak, nonatomic) IBOutlet UIButton *textButton;
@property (weak, nonatomic) IBOutlet UIImageView *iconView;
@end

@implementation XMGOtherCell
- (void)awakeFromNib
{
    self.textButton.titleLabel.numberOfLines = 0;
}

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

    // 时间处理
    if (message.hideTime) { // 隐藏时间
        self.timeLabel.hidden = YES;
        [self.timeLabel updateConstraints:^(MASConstraintMaker *make) {
            make.height.equalTo(0);
        }];
    } else { // 显示时间
        self.timeLabel.text = message.time;
        self.timeLabel.hidden = NO;
        [self.timeLabel updateConstraints:^(MASConstraintMaker *make) {
            make.height.equalTo(21);
        }];
    }

    // 处理显示的消息文字
    // 设置按钮的文字
    [self.textButton setTitle:self.message.text forState:UIControlStateNormal];

    // 强制更新
    [self.textButton layoutIfNeeded];

    // 设置按钮的高度就是titleLabel的高度
    [self.textButton updateConstraints:^(MASConstraintMaker *make) {
        CGFloat buttonH = self.textButton.titleLabel.frame.size.height + 30;
        make.height.equalTo(buttonH);
    }];

    // 强制更新
    [self.textButton layoutIfNeeded];

    // 计算当前cell的高度
    CGFloat buttonMaxY = CGRectGetMaxY(self.textButton.frame);
    CGFloat iconMaxY = CGRectGetMaxY(self.iconView.frame);
    self.message.cellHeight = MAX(buttonMaxY, iconMaxY) + 10;
}
@end
//  XMGMessage.h
//  07-聊天布局
#import <UIKit/UIKit.h>

typedef enum {
    XMGMessageTypeMe = 0,
    XMGMessageTypeOther = 1
} XMGMessageType;

@interface XMGMessage : NSObject
@property (nonatomic, strong) NSString *text;
@property (nonatomic, strong) NSString *time;
@property (nonatomic, assign) XMGMessageType type;

/** cell的高度 */
@property (nonatomic, assign) CGFloat cellHeight;
/** 是否隐藏时间 */
@property (nonatomic, assign, getter=isHideTime) BOOL hideTime;

+ (instancetype)messageWithDict:(NSDictionary *)dict;
@end
//  XMGMessage.m
//  07-聊天布局
#import "XMGMessage.h"

@implementation XMGMessage

+ (instancetype)messageWithDict:(NSDictionary *)dict
{
    XMGMessage *message = [[self alloc] init];
    [message setValuesForKeysWithDictionary:dict];
    return message;
}
@end
时间: 2024-10-06 04:33:01

020606-07-聊天布局的相关文章

07 LinearLayout 布局

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_hei

qq聊天布局思路

qq聊天布局思路 步骤一.更改控制器继承UITableViewController,然后修改storyboard中的控制器. 步骤二.加载plist文件,创建对应的数据模型 + (instancetype)qqWithDict:(NSDictionary *)dict { return [[self alloc] initWithDict:dict]; } - (instancetype)initWithDict:(NSDictionary *)dict { self = [super init

仿QQ聊天布局--iOS

虽然注册博客园这么久了,但很少在这上面写些东西,一来也是觉得自己能力不够,二来怕误人子弟,所以一直秉着“多看,多做,少说”的原则混迹在各论坛之中.但日子久了,觉着这其实是一种逃避的方法.思来想去,那些牛逼的人其实是那些能把自己心中所想完全表达出来,让人看之舒服,听之认同的人.所以,除了“多看,多做,少说”外,怕要加一条“多总结”,否则恐要淹死在这信息化的浪潮中了. 最近对QQ.微信聊天布局产生兴趣,便搜索资料试着搞搞,趁着空隙,先上效果图,得空再补充说明. 大致思路就是 自定义tableView

泡泡聊天布局

泡泡聊天布局 美轮美奂的泡泡聊天布局,通过简单ListView就可以实现. 下载地址:http://www.devstore.cn/code/info/860.html 运行截图:  

iOS UI-QQ聊天布局

一.Model BWMessage.h #import <Foundation/Foundation.h> typedef enum{ BWMessageMe = 0,//表示自己 BWMessageOther = 1 //表示对方 }BWMessageType; @interface BWMessage : NSObject //消息正文 @property(nonatomic, copy) NSString *text; //消息时间 @property(nonatomic, copy)

iOS UI基础-10.0 QQ聊天布局之键盘及文本使用

要实现的效果:   这里只说用到的几个知识点 1.图片包含文字 在设置文字的Frame的时候,使用背景(按钮)的尺寸,文字使用了内边距 背景图片,使用拉伸 /** * 返回一张可以随意拉伸不变形的图片 * * @param name 图片名字 */ + (UIImage *)resizableImage:(NSString *)name { UIImage *normal = [UIImage imageNamed:name]; CGFloat w = normal.size.width * 0

(素材源码)猫猫学IOS(十八)UI之QQ聊天布局_键盘通知实现自动弹出隐藏_自动回复

猫猫分享,必须精品 素材代码地址:http://download.csdn.net/detail/u013357243/8585703 原文地址:http://blog.csdn.net/u013357243?viewmode=contents 先看图片 第一步完成tableView和Cell的架子的图 完善图片 键盘弹出设置后图片: 自动回复图: 粗狂的架子 tableView和Cell的创建 首相tableView为了学习方便就直接用stroyBoard拖拽了,包括一些学习意义不大的图片等等

猫猫学IOS(十八)UI之QQ聊天布局_键盘通知实现自动弹出隐藏_自动回复

猫猫分享,必须精品 素材代码地址:http://blog.csdn.net/u013357243/article/details/45000699 原文地址:http://blog.csdn.net/u013357243?viewmode=contents 先看图片 第一步完成tableView和Cell的架子的图 完善图片 键盘弹出设置后图片: 自动回复图: 粗狂的架子 tableView和Cell的创建 首相tableView为了学习方便就直接用stroyBoard拖拽了,包括一些学习意义不

安卓智能聊天机器人开发(二)

接上一篇文章<安卓智能聊天机器人开发(一)>,晚上继续写. 在上一篇文章中,已经实现了对网络数据的获取和处理封装,这篇文章来讲下如何嵌入到安卓应用中. 先看下效果图: 从上面两张图我们可以发现,这个聊天布局其实就是一个ListView,只不过它和传统的ListView有些区别,因为它使用了多Item样式布局 首先,先来分析下基础布局: 这个界面是由3个布局文件组成,分别是主布局,发送消息样式布局,接收消息样式布局 先来看下主布局: 这里是对应的主布局代码: 1 <RelativeLayo

Android聊天客户端Demo开源了.基本的聊天功能基本上都有了,数据库也已搭建,服务器用的baiduPush。可以直接拿来用!!。(希望两个手机通信的话,改一下pushid就可以)

Hello: 我是在飞,最近写了个聊天的Android客户端.今天将此demo分享出来.原澳门大家可以到github直接下载.有问题可以联系我. 几点说明: 1:android聊天客户端的demo,包含了im的基本功能. 1.1比如gif动态表情展示.语音.聊天表情.拍照.多图的发送.大图片的处理.listview缓存的处理等. 1.2数据库也已经搭载好,算是个完整项目,可以直接拿来用. 1.3服务器使用的是baidu push服务.(图片暂时没有处理上传服务器,只是上传了本地sdcard的pa