第二十五篇:QQ聊天界面


UIImage:

》1.对于一张图片拉伸方法:
   1.1.得先拿到一张图片img;
   1.2.再跟据img的size 分出四根线(top,left,bottom,right)大小,那么四周的图片不会被拉伸,中间的会被拉伸。
   1.3.调用以下的方法,参数:UIEdgeInsetsMake(top,left,bottom,right);  UIImageResizingModeTile
    - (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)
    - (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets) resizingMode:(UIImageResizingMode)
  例如:自定义一个方法

#import "UIImage+Extention.h"

@implementation UIImage (Extention)


+ (UIImage *)resizableImageWithName:(NSString *)imgName{
    UIImage * img = [UIImage imageNamed:imgName];
    CGFloat width = img.size.width *0.5;
    CGFloat height = img.size.height *0.5;
    img = [img resizableImageWithCapInsets:UIEdgeInsetsMake(height, width, height-1, width-1)];
    return img ;
}

@end


NSString:
》1.自定义分类
@implementation NSString (Extention)


/** 返回文字真实的Size */
- (CGSize) sizeWithMaxSize:(CGSize)size font:(UIFont *)font{
    
    NSDictionary * attrib = @{NSFontAttributeName : font};
    return [self boundingRectWithSize:size options:NSStringDrawingUsesLineFragmentOrigin attributes:attrib context:nil].size;
}


@end




UIButton:

》1.设置内边距:在设置button的内边距 contentEdgeInsets 时,要使button内的文字titleLabel的frame不变形,
    那么button.frame.size的width = 文字真实的width + 宽度的内边距  ,height = 文字真实的height + 高度的内边距



NSNotificationCenter:

》通知中心只有一个 与 文件管理 一样。当有发
  [NSNotificationCenter defaultCenter]
》 通知中心 添加 键盘 的 监听器:
    
    监听者 : Observer
    监听者调用的方法:selector
    消息名:name
    消息发布者:object


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




textField:

#pragma mark - textField的 delegate 协议方法
/** 当键盘的return被按下时调用,发送一条消息  */

- (BOOL)textFieldShouldReturn:(UITextField *)textField;


效果图:



代码:

Category:

//
//  NSString+Extention.h
//  10-QQ聊天
//
//  Created by 瞿杰 on 15/10/1.
//  Copyright © 2015年 itcast. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

#define TextFont [UIFont systemFontOfSize:18]

@interface NSString (Extention)

- (CGSize) sizeWithMaxSize:(CGSize)size font:(UIFont *)font;

@end
//
//  NSString+Extention.m
//  10-QQ聊天
//
//  Created by 瞿杰 on 15/10/1.
//  Copyright © 2015年 itcast. All rights reserved.
//

#import "NSString+Extention.h"

@implementation NSString (Extention)

/** 返回文字真实的Size */
- (CGSize) sizeWithMaxSize:(CGSize)size font:(UIFont *)font{
    
    NSDictionary * attrib = @{NSFontAttributeName : font};
    return [self boundingRectWithSize:size options:NSStringDrawingUsesLineFragmentOrigin attributes:attrib context:nil].size;
}

@end


//
//  UIImage+Extention.h
//  10-QQ聊天
//
//  Created by 瞿杰 on 15/10/2.
//  Copyright © 2015年 itcast. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface UIImage (Extention)

+ (UIImage *)resizableImageWithName:(NSString *)imgName;

@end
//
//  UIImage+Extention.m
//  10-QQ聊天
//
//  Created by 瞿杰 on 15/10/2.
//  Copyright © 2015年 itcast. All rights reserved.
//

#import "UIImage+Extention.h"

@implementation UIImage (Extention)

+ (UIImage *)resizableImageWithName:(NSString *)imgName{
    UIImage * img = [UIImage imageNamed:imgName];
    CGFloat width = img.size.width *0.5;
    CGFloat height = img.size.height *0.5;
    img = [img resizableImageWithCapInsets:UIEdgeInsetsMake(height, width, height-1, width-1)];
    return img ;
}

@end





Model:

//
//  QJMessage.h
//  10-QQ聊天
//
//  Created by 瞿杰 on 15/10/1.
//  Copyright © 2015年 itcast. All rights reserved.
//

#import <Foundation/Foundation.h>

typedef enum {
    QJMessageTypeMe = 0,
    QJMessageTypeOther
}QJMessageType;

@interface QJMessage : NSObject

@property (nonatomic , copy)NSString * text;
@property (nonatomic , copy)NSString * time;
@property (nonatomic , assign)QJMessageType type;

+ (instancetype)messageWithDictionary:(NSDictionary *)dic;
- (instancetype)initWithDictionary:(NSDictionary *)dic;

@end
//
//  QJMessage.m
//  10-QQ聊天
//
//  Created by 瞿杰 on 15/10/1.
//  Copyright © 2015年 itcast. All rights reserved.
//

#import "QJMessage.h"

@implementation QJMessage

+ (instancetype)messageWithDictionary:(NSDictionary *)dic{
    return [[self alloc] initWithDictionary:dic];
}
- (instancetype)initWithDictionary:(NSDictionary *)dic{
    if (self = [super init]) {
        self.time = dic[@"time"]; 
        self.text = dic[@"text"];
        NSNumber *type = dic[@"type"];
        self.type = (QJMessageType)[type intValue];
        
    }
    return self ;
}

@end

//
//  QJMessageFrame.h
//  10-QQ聊天
//
//  Created by 瞿杰 on 15/10/1.
//  Copyright © 2015年 itcast. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

@class QJMessage ;

@interface QJMessageFrame : NSObject

@property (strong , nonatomic)QJMessage * message;

/**
 *  隐藏时间
 */
@property (assign , nonatomic)BOOL hiddenTime;
/**
 *  时间的frame
 */
@property (assign , nonatomic)CGRect timeFrame;
/**
 *  头象的frame
 */
@property (assign , nonatomic)CGRect iconFrame;
/**
 *  正文的frame
 */
@property (assign , nonatomic)CGRect textFrame;
/**
 *  Cell的高度
 */
@property (assign , nonatomic)CGFloat cellHieght;


@end

//
//  QJMessageFrame.m
//  10-QQ聊天
//
//  Created by 瞿杰 on 15/10/1.
//  Copyright © 2015年 itcast. All rights reserved.
//

#import "QJMessageFrame.h"
#import "NSString+Extention.h"
#import "QJMessage.h"

@implementation QJMessageFrame

- (void)setMessage:(QJMessage *)message{
    
    _message = message;
    
//    CGSize screenSize = [UIScreen mainScreen].bounds.size;
//    NSLog(@"screenSize ---- %d",screenSize.width);
    CGSize screenSize = CGSizeMake(414, 736);
    
    //间距
    CGFloat padding = 10 ;
    
    // 计算timeLable 的frame
    if (self.hiddenTime == NO) {
        CGFloat timeLableX = 0;
        CGFloat timeLableY = 0;
        CGFloat timeLableW = screenSize.width;
        CGFloat timeLableH = 50;
        self.timeFrame = CGRectMake(timeLableX, timeLableY, timeLableW, timeLableH);
    }
    
    // 计算头象iconImg 的frame
    CGFloat iconImgW = 50;
    CGFloat iconImgH = 50;
    CGFloat iconImgY = CGRectGetMaxY(self.timeFrame)+padding;
    CGFloat iconImgX ;
    if (message.type == QJMessageTypeMe) {
        iconImgX = screenSize.width - padding - iconImgW;
    }
    else{
        iconImgX = padding ;
    }
    self.iconFrame = CGRectMake(iconImgX, iconImgY, iconImgW, iconImgH);
    
    // 计算聊天正文按妞textBtn 的frame
    CGSize textSize = [message.text sizeWithMaxSize:CGSizeMake(200, CGFLOAT_MAX) font:TextFont];
    CGFloat textY = iconImgY;
    CGFloat textX ;
    if (message.type == QJMessageTypeMe) {
        textX = screenSize.width - iconImgW - padding * 2 - textSize.width - 20*2;
    }
    else{
        textX = CGRectGetMaxX(self.iconFrame) + padding ;
    }
    self.textFrame = CGRectMake(textX, textY, textSize.width + 20*2, textSize.height+20*2);
    
    // 计算Cell的高度
    self.cellHieght = MAX(CGRectGetMaxY(self.textFrame), CGRectGetMaxY(self.iconFrame)) + padding;
}

@end

View:

//
//  QJMessageCell.h
//  10-QQ聊天
//
//  Created by 瞿杰 on 15/10/1.
//  Copyright © 2015年 itcast. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "QJMessageFrame.h"

@interface QJMessageCell : UITableViewCell

@property (strong , nonatomic)QJMessageFrame * messageFrame;

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

@end
//
//  QJMessageCell.m
//  10-QQ聊天
//
//  Created by 瞿杰 on 15/10/1.
//  Copyright © 2015年 itcast. All rights reserved.
//

#import "QJMessageCell.h"
#import "QJMessage.h"
#import "NSString+Extention.h"
#import "UIImage+Extention.h"

@interface QJMessageCell ()

@property (weak , nonatomic)UILabel * timeLable;
@property (weak , nonatomic)UIImageView * iconImg;
@property (weak , nonatomic)UIButton * textBtn;

@end

@implementation QJMessageCell

+ (instancetype)messageCellWithTableView:(UITableView *)tableView{
    
    NSString * ID = @"messageCell";
    QJMessageCell * cell = [tableView dequeueReusableCellWithIdentifier:ID];
    if (nil == cell) {
        cell = [[self alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
    }
    cell.backgroundColor = [UIColor colorWithRed:224.0/255 green:224.0/255 blue:224.0/255 alpha:1.0];
    return cell ;
}

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        // 添加timeLable
        UILabel * timeLable = [[UILabel alloc]init];
        timeLable.textAlignment = NSTextAlignmentCenter;
        [self.contentView addSubview:timeLable];
        self.timeLable = timeLable ;
        self.timeLable.textColor = [UIColor grayColor];
        
        // 添加头象iconImg
        UIImageView * iconImg = [[UIImageView alloc]init];
        [self.contentView addSubview:iconImg];
        self.iconImg = iconImg ;
        
        // 添加聊天正文按妞textBtn
        UIButton * textBtn = [[UIButton alloc]init];
        [self.contentView addSubview:textBtn];
        self.textBtn = textBtn ;
        self.textBtn.titleLabel.font = TextFont;
        self.textBtn.titleLabel.numberOfLines = 0;
        [self.textBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
        //设置内边距
        self.textBtn.contentEdgeInsets = UIEdgeInsetsMake(20, 20, 20, 20);
        
    }
    return self;
}

- (void)setMessageFrame:(QJMessageFrame *)messageFrame{
   
    _messageFrame = messageFrame;
    
    // 设置timeLable 的内容与frame
    self.timeLable.frame = messageFrame.timeFrame;
    self.timeLable.text = messageFrame.message.time;
    
    // 设置头象iconImg 的内容与frame
    self.iconImg.image =  [UIImage imageNamed: (messageFrame.message.type == QJMessageTypeMe)?  @"me" : @"other"] ;
    self.iconImg.frame = messageFrame.iconFrame;
    
    // 设置聊天正文按妞textBtn 的内容与frame
    [self.textBtn setTitle:messageFrame.message.text forState:UIControlStateNormal] ;
    self.textBtn.frame = messageFrame.textFrame;

    if (messageFrame.message.type == QJMessageTypeMe) {
        [self.textBtn setBackgroundImage:[UIImage resizableImageWithName:@"chat_send_nor"] forState:UIControlStateNormal];
    }
    else{
        [self.textBtn setBackgroundImage:[UIImage resizableImageWithName: @"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

Controller:

//  ViewController.h
//  10-QQ聊天
//
//  Created by 瞿杰 on 15/10/1.
//  Copyright © 2015年 itcast. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController


@end
//
//  ViewController.m
//  10-QQ聊天
//
//  Created by 瞿杰 on 15/10/1.
//  Copyright © 2015年 itcast. All rights reserved.
//

#import "ViewController.h"
#import "QJMessageCell.h"
#import "QJMessage.h"
#import "QJMessageFrame.h"

@interface ViewController ()<UITableViewDataSource,UITableViewDelegate,UITextFieldDelegate>

@property (weak, nonatomic) IBOutlet UITableView *tableView;
@property (strong, nonatomic)NSMutableArray * messageFrames;
@property (weak, nonatomic) IBOutlet UIView *bottomView;
@property (weak, nonatomic) IBOutlet UITextField *inputTextField;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 设置tableView的数据源,代理和一些属性
    self.tableView.dataSource = self ;
    self.tableView.delegate = self ;
    self.tableView.allowsSelection = NO; // tableView中的cell不允许选中
    self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone; // cell的分隔线类型
    
    //输入文本框
    self.inputTextField.delegate = self;
    // 通知中心 添加 键盘 的 监听器,调用监听器方法
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(KeyboardWillChangeFrameNotification:)  name:UIKeyboardWillChangeFrameNotification object:nil];
}

- (BOOL)prefersStatusBarHidden{
    return YES ;
}

/** 当从通知中心得知键盘frame变动时,调用该方法 */
- (void)KeyboardWillChangeFrameNotification:(NSNotification *)notif{

    //    NSLog(@"%@",notif);
    // 从打卬中要以看出userInfo中的key,取出对应的属性
    CGFloat time = [notif.userInfo[@"UIKeyboardAnimationDurationUserInfoKey"] floatValue];
    CGRect keyboardBeginRect = [notif.userInfo[@"UIKeyboardFrameBeginUserInfoKey"] CGRectValue];
    CGRect keyboardEndRect = [notif.userInfo[@"UIKeyboardFrameEndUserInfoKey"] CGRectValue];
    // 键盘 坐标y 值的变动值
    CGFloat yMinusValu = keyboardBeginRect.origin.y - keyboardEndRect.origin.y;
    
    CGRect tableViewFrame  = self.tableView.frame;
    CGRect bottomViewFrame = self.bottomView.frame;
    
    [UIView animateWithDuration:time animations:^{ // 执行动画
       // 改变 tableView.frame的坐标y值
        CGFloat X = tableViewFrame.origin.x ;
        CGFloat Y = tableViewFrame.origin.y - yMinusValu ;
        CGFloat W = tableViewFrame.size.width;
        CGFloat H = tableViewFrame.size.height;
        self.tableView.frame = CGRectMake(X, Y, W, H);
        
        // 改变 bottomView.frame的坐标y值
        X = bottomViewFrame.origin.x;
        Y = bottomViewFrame.origin.y - yMinusValu;
        W = bottomViewFrame.size.width;
        H = bottomViewFrame.size.height;
        self.bottomView.frame = CGRectMake(X, Y, W, H);
    }];
}

- (NSArray *)messageFrames{
    if (_messageFrames == nil) {
        NSArray * messages = [NSArray arrayWithContentsOfFile: [[NSBundle mainBundle]pathForResource:@"messages.plist" ofType:nil]];
        NSMutableArray * messageFrames = [NSMutableArray array];
        for (NSDictionary * dic in messages){
            QJMessage * message = [QJMessage messageWithDictionary:dic];
            QJMessageFrame * preMessageFrame = [messageFrames lastObject];
            QJMessageFrame * messageFrame = [[QJMessageFrame alloc]init];
            messageFrame.hiddenTime = [preMessageFrame.message.time isEqualToString:message.time];
            messageFrame.message = message ;
            
            [messageFrames addObject:messageFrame];
        }
        _messageFrames = messageFrames;
    }
    return _messageFrames ;
}


#pragma mark - 数据源方法

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return self.messageFrames.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    
    // 1.创建一个Cell
    QJMessageCell * cell = [QJMessageCell messageCellWithTableView:self.tableView];
    
    // 2.设置Cell的数据
    
    cell.messageFrame = self.messageFrames[indexPath.row];
    
    // 3.返回一个Cell
    return cell;
}

#pragma mark - 代理方法
/**  每个Cell 的高度 */
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    QJMessageFrame * cellFrame = self.messageFrames[indexPath.row];
    return cellFrame.cellHieght;
}
/** 当tableView 被拖动地调用 */
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{
    // 隐藏键盘
    [self.view endEditing:YES];
}

#pragma mark - textField的 delegate 协议方法
/** 当键盘的return被按下时调用,发送一条消息  */
- (BOOL)textFieldShouldReturn:(UITextField *)textField{
    // 获取时间
    NSDate * date = [NSDate date];
    NSDateFormatter * dateForm = [[NSDateFormatter alloc]init];
    dateForm.dateFormat = @"HH:mm";
    
    NSDictionary * dic = @{
                           @"text":[NSString stringWithFormat:@"%@",textField.text],
                           @"time":[dateForm stringFromDate:date],
                           @"type":[NSNumber numberWithInt:0]
                           };
    QJMessage * message = [QJMessage messageWithDictionary:dic];
    QJMessageFrame * messageFrame = [[QJMessageFrame alloc]init];
    messageFrame.message = message;
    [self.messageFrames addObject:messageFrame];
    
    [self.tableView reloadData];
    
    return YES;
}


@end








  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值