首页 > 代码库 > 聊天界面的优化

聊天界面的优化

#import <UIKit/UIKit.h>

 

@class ChatMessage;

@interface ChatViewController : UIViewController<UITextFieldDelegate,UITableViewDataSource,UIImagePickerControllerDelegate,UINavigationControllerDelegate,UIScrollViewDelegate>

 

- (IBAction)inputClick:(id)sender;

- (IBAction)sendMessage:(id)sender;

@property (weak, nonatomic) IBOutlet UITableView *tableChat;

@property (weak, nonatomic) NSString *strMessage;

@property (weak, nonatomic) IBOutlet UITextField *messageField;

@property (weak, nonatomic) IBOutlet UIView *bottomBar;

//@property (weak, nonatomic) NSString *chatto;

@property (strong, nonatomic) ChatMessage *msg;

@property (weak, nonatomic) UISwipeGestureRecognizer *leftSwipeGestutrReconiger;

//- (IBAction)pickerView:(id)sender;

//- (IBAction)moodViewShow:(id)sender;

 

//- (IBAction)deleteMessage:(UIButton *)sender;

@end

 

#import "ChatViewController.h"

#import "ChatMessage.h"

#import "EGODatabase.h"

#import "MessageCell.h"

#import "MessageFrame.h"

#import "IQKeyboardManager.h"

#define ScreenHeight [[UIScreen mainScreen]bounds].size.height

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

@interface ChatViewController ()

{

    NSMutableArray *arrayChatMessage;

    NSMutableArray* arrayMessagesFrame;

}

//@property (strong, nonatomic) IBOutlet UIScrollView *scroll;

@property(nonatomic,strong)NSArray* emos;

@end

 

@implementation ChatViewController

#pragma mark - View lifecycle

 

 

- (void)setTitle:(NSString *)title

{

    [super setTitle:title];

    UILabel *titleView = (UILabel *)self.navigationItem.titleView;

    if (!titleView) {

        titleView = [[UILabel alloc] initWithFrame:CGRectMake(100, 0, self.view.frame.size.width*2/5, 44)];

        titleView.backgroundColor = [UIColor clearColor];

        titleView.font = [UIFont fontWithName:@"HelveticaNeue" size:16];

        titleView.textColor = [UIColor whiteColor];

        titleView.textAlignment = UITextAlignmentCenter;

        

        self.navigationItem.titleView = titleView;

    }

    titleView.text = title;

    [titleView sizeToFit];

}

 

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil

{

    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];

    if (self) {

        // Custom initialization

    }

    

    return self;

}

 

- (void)viewDidLoad

{

    [super viewDidLoad];

    

    [self setTitle:self.msg.strContactName];

    //表情窗口初始化

//    self.scroll.frame = CGRectMake(0, 0 - 200, ScreenWidth, 200);

    

    CGSize viewSize = [[UIScreen mainScreen] bounds].size;

    UIImageView *image = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"bg2.png"]];

    [image setFrame:CGRectMake(0, 0, viewSize.width, viewSize.height)];

    [self.view addSubview:image];

    [self.view sendSubviewToBack:image];

    

    [self.navigationController.navigationBar setBackgroundImage:[UIImage new]

                                                  forBarMetrics:UIBarMetricsDefault];

    self.navigationController.navigationBar.shadowImage = [UIImage new];

    self.navigationController.navigationBar.translucent = YES;

    

    self.tableChat.backgroundColor = [UIColor clearColor];

// Do any additional setup after loading the view.

    if (!arrayMessagesFrame) {

        arrayMessagesFrame = [[NSMutableArray alloc]init];

    }

    

    //载入本地历史消息

    [self loadChatMessage];

    

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyBoardWillShow:) name:UIKeyboardWillShowNotification object:nil];

    

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyBoardWillHide:) name:UIKeyboardWillHideNotification object:nil];

    

    //设置textField输入起始位置

    self.messageField.leftView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 0)];

    self.messageField.leftViewMode = UITextFieldViewModeAlways;

    

    self.messageField.delegate = self;

    

    [self registerEvents];

    

    CGRect frame = self.bottomBar.frame;

    frame.origin.y = self.view.frame.size.height - 44;

    [self.bottomBar setFrame:frame];

    

    //self.messageField.text = [NSString stringWithFormat:@"\t/微笑\t"];

    if (arrayMessagesFrame.count > 0) {

        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:arrayMessagesFrame.count - 1 inSection:0];

        [self.tableChat scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];

    }

    

#ifdef __IPHONE_5_0

    float version = [[[UIDevice currentDevice] systemVersion] floatValue];

    if (version >= 5.0) {

        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyBoardFrameDidChange:) name:UIKeyboardDidChangeFrameNotification object:nil];

    }

#endif

    

    //表情列表解析

//    NSString* path=[[NSBundle mainBundle]pathForResource:@"emoticons" ofType:@"plist"];

//    self.emos=[NSArray arrayWithContentsOfFile:path];

//    for (int i=0; i<self.emos.count; i++) {

//        NSDictionary* dic=self.emos[i];

//        NSString* emoName=[dic objectForKey:@"png"];

//        UIImage* image=[UIImage imageNamed:emoName];

//        UIButton* btn=[[UIButton alloc]initWithFrame:CGRectMake(i%8*40, i/8*40, 40, 40)];

//        btn.tag=i;

//        [btn setImage:image forState:UIControlStateNormal];

//        [btn addTarget:self action:@selector(showName:) forControlEvents:UIControlEventTouchUpInside];

//        [self.scroll addSubview:btn];

//    }

//    self.scroll.contentSize=CGSizeMake(self.view.bounds.size.width, self.emos.count/8*40);

 

}

//自定义表情方法

//-(void)showName:(UIButton*)sender{

//    NSDictionary* emoDic=[self.emos objectAtIndex:sender.tag];

//    NSString* text=[emoDic objectForKey:@"chs"];

//    

//    self.messageField.text = [NSString stringWithFormat:@"%@%@",self.messageField.text,text];

//    

//}

 

 

 

#pragma mark - 键盘处理

#pragma mark 键盘即将显示

-(void)keyBoardFrameDidChange:(NSNotification *)note

{

//    NSDictionary *userInfo = [notification userInfo];

//    NSValue *aValue = http://www.mamicode.com/[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];

//    CGRect keyboardRect = [aValue CGRectValue];

//    NSValue *animationDurationValue = http://www.mamicode.com/[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey];

//    NSTimeInterval animationDuration;

//    [animationDurationValue getValue:&animationDuration];

    

    CGSize size = [[UIScreen mainScreen] bounds].size;//获取屏幕的尺寸;

    CGRect rect = [note.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];//得到键盘的高度;

    CGFloat ty = size.height - rect.size.height;//

    

    

    [UIView animateWithDuration:[note.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue] animations:^{

        

        //frame.size.height -= rect.size.height;

       

        if (rect.origin.y != size.height) {

            CGRect frame = self.tableChat.frame;

            frame.size.height = size.height - rect.size.height - 105;//屏幕高度减去键盘高度减去输入框高度,就是新的table的高度,再赋给table,

              [self.bottomBar setFrame:CGRectMake(0, ty-40, 320, 40)];

             [self.tableChat setFrame:frame];

        }

        else{

            CGRect frame = self.tableChat.frame;

            frame.size.height = size.height - 40;

            [self.bottomBar setFrame:CGRectMake(0, size.height-40, ScreenWidth, 40)];

        }

        

//        if (self.bottomBar.frame.origin.y == size.height - 40) {

//            [self.bottomBar setFrame:CGRectMake(0, ty-40, 320, 40)];

//        }

//        else{

//            [self.bottomBar setFrame:CGRectMake(0, size.height - 40, ScreenWidth, 40)];

//        }

       

        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:arrayMessagesFrame.count - 1 inSection:0];

        if (arrayMessagesFrame.count== 0) {

            return ;

        }

        else

        {

            [self.tableChat scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];

        }

    }];

 

}

 

- (void)keyBoardWillShow:(NSNotification *)note{

    

    CGSize size = [[UIScreen mainScreen] bounds].size;

    CGRect rect = [note.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];

    CGFloat ty = size.height - rect.size.height;

   

    [UIView animateWithDuration:[note.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue] animations:^{

        CGRect frame = self.tableChat.frame;

        //frame.size.height -= rect.size.height;

        //frame.size.height = size.height - rect.size.height -40;

        frame.size.height = size.height - rect.size.height - 105;

        [self.tableChat setFrame:frame];

        

        [self.bottomBar setFrame:CGRectMake(0, ty-40, 320, 40)];

        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:arrayMessagesFrame.count - 1 inSection:0];

        if (arrayMessagesFrame.count== 0) {

            return ;

        }

        else

        {

            [self.tableChat scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];

        }

    }];

    

 

    //[self.navigationController.navigationBar setHidden:YES];

}

#pragma mark 键盘即将退出

- (void)keyBoardWillHide:(NSNotification *)note{

    

    CGSize size = [[UIScreen mainScreen] bounds].size;

    CGRect rect = [note.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];

    CGFloat ty = size.height - rect.size.height;

    

    [UIView animateWithDuration:[note.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue] animations:^{

        CGRect frame = self.tableChat.frame;

        frame.size.height += rect.size.height - 60;

       

        [self.tableChat setFrame:frame];

        

        [self.bottomBar setFrame:CGRectMake(0, size.height-40, 320, 40)];

        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:arrayMessagesFrame.count - 1 inSection:0];

        if (arrayMessagesFrame.count== 0) {

            return ;

        }

        else

        {

            [self.tableChat scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];

        }

    }];

    

}

#pragma mark - 文本框代理方法

#pragma mark 点击textField键盘的回车按钮

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

    

    NSString *content = textField.text;

    if ([content isEqualToString:@""]) {

        return NO;

    }

 

    [self addMessageWithContent:content type:MessageTypeMe];

    

    NSUserDefaults *pref = [NSUserDefaults standardUserDefaults];

    NSString* strUid = [pref stringForKey:@"uid"];

    

   //NSString *strFrom = @"andy";

   // NSString *strTo   = @"andy";

    NSString *strMsg = [NSString stringWithFormat:@"{\"type\":\"chat\",\"from\":\"%@\",\"to\":\"%@\",\"msg\":\"%@\"}",strUid,self.msg.strContact,content];

    

    NSLog(@"input message:%@",strMsg);

 

    [[NSNotificationCenter defaultCenter] postNotificationName:@"AppSendMessage" object:strMsg];

    

    [self.tableChat reloadData];

    

    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:arrayMessagesFrame.count - 1 inSection:0];

    [self.tableChat scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];

 

    self.messageField.text = nil;

    

    return YES;

}

 

#pragma mark 给数据源增加内容

- (void)addMessageWithContent:(NSString *)content type:(MessageType)type{

    

    MessageFrame *mf = [[MessageFrame alloc] init];

    ChatMessage *message = [[ChatMessage alloc] init];

    message.strMessage = content;

    message.strContact = self.msg.strContact;

    message.strContactName = self.msg.strContactName;

    message.strTimeStamp = [self generateTimeStamp];

    message.type = type;

    if (message.type == MessageTypeOther)

    {

        message.strContactIcon = [self getContactIconByTelephone:message.strContact];

    }

    else

    {

        NSUserDefaults *pref = [NSUserDefaults standardUserDefaults];

        NSString* strUid = [pref stringForKey:@"uid"];

 

        message.strContactIcon = [self getContactIconByTelephone:strUid];

    }

    

    mf.message = message;

    mf.showTime = YES;

    

    [arrayMessagesFrame addObject:mf];

}

 

- (NSString*)getContactAvatar:(NSString*)contactId

{

    return @"defaultAvatar";

    

/*    if ([contact.strAvatar isEqualToString:@""]) {

        cell.imageView.image = [UIImage imageNamed:@"defaultAvatar"];

    }

    else

    {

        NSString *filePath = [NSHomeDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"Documents/%@",contact.strAvatar]];

        

        BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:filePath];

        if(!fileExists)

        {

            cell.imageView.image = [UIImage imageNamed:@"defaultAvatar"];

            

            [self downloadAvatar:contact];

        }

        else

        {

            cell.imageView.image = [UIImage imageWithContentsOfFile:filePath];

        }

    }*/

 

}

 

- (void)loadChatMessage

{

    if (!arrayChatMessage) {

        arrayChatMessage = [[NSMutableArray alloc]init];

    }

    

    EGODatabase* database = [EGODatabase databaseWithPath:[NSHomeDirectory() stringByAppendingPathComponent:@"Documents/database.db"]];

    

    //查询最新的消息,展示在首页聊天中,点击某一个聊天再查询该聊天下的所有历史消息

    NSString *sqlQuery = [[NSString alloc]initWithFormat:@"select * from chatmessage where contact = ‘%@‘  order by timestamp",self.msg.strContact];

    NSLog(@"%@",sqlQuery);

    

    int i = 1;

    

    NSUserDefaults *pref = [NSUserDefaults standardUserDefaults];

    NSString* strUid = [pref stringForKey:@"uid"];

    

    EGODatabaseResult *result = [database executeQuery:sqlQuery];

    for(EGODatabaseRow* row in result) {

        MessageFrame *messageFrame = [[MessageFrame alloc] init];

 

        ChatMessage *msg = [[ChatMessage alloc]init];

        

        msg.strContact = [row stringForColumn:@"contact"];

        

        msg.strContactIcon = [self getContactIconByTelephone:msg.strContact];

        msg.strMessage = [row stringForColumn:@"message"];

        msg.strTimeStamp = [row stringForColumn:@"timestamp"];

        msg.type         = [row intForColumn:@"type"];

        if (msg.type == MessageTypeOther)

        {

            msg.strContactIcon = [self getContactIconByTelephone:msg.strContact];

        }

        else

        {

            msg.strContactIcon = [self getContactIconByTelephone:strUid];

        }

        [arrayChatMessage insertObject:msg atIndex:0];

        

        messageFrame.message = msg;

        messageFrame.showTime = YES;

        

        [arrayMessagesFrame addObject:messageFrame];

        

        i = !i;

        

        NSLog(@"chatview::load message:%@",msg.strMessage);

    }

    

    [database close];

}

 

- (NSString*)getContactIconByTelephone:(NSString*)tel

{

    EGODatabase* database = [EGODatabase databaseWithPath:[NSHomeDirectory() stringByAppendingPathComponent:@"Documents/database.db"]];

    

    //查询所有联系人

    NSString *sqlQuery = [[NSString alloc]initWithFormat:@"select avatar from contact  where tel=‘%@‘",tel];

    //NSLog(@"%@",sqlQuery);

    

    NSString* strIcon = @"";

    EGODatabaseResult *result = [database executeQuery:sqlQuery];

    for(EGODatabaseRow* row in result) {

        strIcon = [row stringForColumn:@"avatar"];

    }

    

    [database close];

    

    return strIcon;

}

 

- (void)registerEvents {

    // Register the analytics event that are going to be tracked by Baker.

    

    NSArray *analyticEvents = [NSArray arrayWithObjects:

                               @"AppReceiveNewMessage",

                               nil];

    

    for (NSString *eventName in analyticEvents) {

        [[NSNotificationCenter defaultCenter] addObserver:self

                                                 selector:@selector(receiveEvent:)

                                                     name:eventName

                                                   object:nil];

    }

}

 

- (void)receiveEvent:(NSNotification *)notification {

    // If you want, you can handle differently the various events

    if ([[notification name] isEqualToString:@"AppReceiveNewMessage"]) {

        

        NSLog(@"%@",notification.name);

        NSLog(@"%@",notification.object);

        

        NSDateFormatter *fmt = [[NSDateFormatter alloc] init];

        NSDate *date = [NSDate date];

        fmt.dateFormat = @"MM-dd"; // @"yyyy-MM-dd HH:mm:ss"

        NSString *time = [fmt stringFromDate:date];

        

        //保存到数据库,更新首页聊天记录

        NSString *receiveData = http://www.mamicode.com/(NSString *)notification.object;

        

        NSError *error = nil;

        NSData *jsonData = http://www.mamicode.com/[receiveData dataUsingEncoding:NSUTF8StringEncoding];

        NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&error];

        NSString* msgType = [dict objectForKey:@"type"];

        NSLog(@"msgtype is %@",msgType);

        

        //检查收到的消息是否是当前正在聊天的联系人发来的,是就更新聊天窗口,否就丢弃。主窗口会保存聊天记录。

        NSUserDefaults *pref = [NSUserDefaults standardUserDefaults];

        NSString* strCurrentChat = [pref stringForKey:@"CurrentChatContact"];

        NSString* chatFrom = [dict objectForKey:@"from"];

        if ([strCurrentChat isEqualToString:chatFrom]) {

            NSString* chatTo = [dict objectForKey:@"to"];

            NSString* msg = [dict objectForKey:@"msg"];

            

            if (![msg isEqualToString:@""]) {

                [self addMessageWithContent:msg type:MessageTypeOther];

                

                [self.tableChat reloadData];

                

                NSIndexPath *indexPath = [NSIndexPath indexPathForRow:arrayMessagesFrame.count - 1 inSection:0];

                [self.tableChat scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];

            }

        }

    }

}

 

- (NSString*)generateTimeStamp

{

    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];

    [dateFormatter setDateStyle:NSDateFormatterMediumStyle];

    [dateFormatter setTimeStyle:NSDateFormatterMediumStyle];

    [dateFormatter setDateFormat:@"yyyyMMddhhmmss"];

    NSString *timerid = [dateFormatter stringFromDate:[NSDate date]];

    

    return timerid;

}

 

- (void)viewDidAppear:(BOOL)animated

{

    NSUserDefaults *pref = [NSUserDefaults standardUserDefaults];

    [pref setValue:self.msg.strContact forKey:@"CurrentChatContact"];

}

 

- (void)viewDidDisappear:(BOOL)animated

{

    NSUserDefaults *pref = [NSUserDefaults standardUserDefaults];

    [pref setValue:@"" forKey:@"CurrentChatContact"];

}

 

- (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

{

    return [arrayMessagesFrame count];

}

 

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

{

    return [arrayMessagesFrame[indexPath.row] cellHeight];

}

 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

{

    static NSString *simpleTableIdentifier = @"MessageCell";

    

    MessageCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];

    

    if (cell == nil) {

        cell = [[MessageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];

    }

    

    // 设置数据

    cell.messageFrame = [arrayMessagesFrame objectAtIndex:indexPath.row];

    cell.contentView.backgroundColor = [UIColor clearColor];

    

    return cell;

}

 

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

{

    [tableView deselectRowAtIndexPath:indexPath animated:NO];

    

    [self.messageField resignFirstResponder];

}

 

- (IBAction)sendMessage:(id)sender {

    self.strMessage = @"发吧";

    

   // [[NSNotificationCenter defaultCenter] postNotificationName:@"AppSendMessage" object:self.strMessage];

}

- (IBAction)inputClick:(id)sender {

}

 

 

@end