简单的聊天页面
本來公司一直想寫商城的項目,可是后臺又在做催收系統(tǒng),這個做完才能開始這個項目。看了一下商城的里面有個簡單的和客服聊天的頁面。結合環(huán)信自己做了一個簡單的IM聊天頁面。
利用了環(huán)信的框架,寫了個登錄注冊添加好友的功能。環(huán)信還是很好用的,他有自己封裝好的IM連天界面,自己處理一下就好了。但是再好的東西也是有不足。有些東西還是滿足不了客戶的需求。以前也沒做過聊天的功能。先學習了簡單的頁面開始。廢話不多說,開始吧! 今天我們主要講聊天的頁面是怎么實現(xiàn)的。也就是這個界面。看是簡單,好了 我們開始吧!!! 大家都知道這是用tableView實現(xiàn)的,首先你要先寫個tableView,然后自定個tableViewCell,上面的一些控件需要我們自己根據(jù)數(shù)據(jù)的類型我們來判斷。這些大致的思路,上代碼。
這是聊天頁面需要的一些類。兩個類目分別封裝了處理聊天字體的自適應和處理氣泡的方法。 處理字體自適應的方法NSStrin+Extension .h //測量文本的尺寸 - (CGSize)sizeWithFont:(UIFont *)font maxSize:(CGSize)maxSize; 復制代碼.m
-(CGSize)sizeWithFont:(UIFont *)font maxSize:(CGSize)maxSize {CGSize size = [self boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:font} context:nil].size;return size; }復制代碼處理氣泡拉伸的方法UIImage+Extension .h
+ (UIImage *)resizableImage:(NSString *)imageName; 復制代碼.m
+(UIImage *)resizableImage:(NSString *)imageName {UIImage *imge = [UIImage imageNamed:imageName];//取圖片部分的1 × 1拉伸UIEdgeInsets insets = UIEdgeInsetsMake(imge.size.height / 2, imge.size.width / 2, imge.size.height / 2 + 1, imge.size.width / 2 + 1);return [imge resizableImageWithCapInsets:insets]; }復制代碼自定義cell .h
@class JYJ_Message; #define MESSAGE_TIME_FONT [UIFont systemFontOfSize:13] #define MESSAGE_TEXT_FONT [UIFont systemFontOfSize:15] #define TEXT_INSET 20 @interface JYJ_CustomChatTableViewCell : UITableViewCell @property (nonatomic, strong) JYJ_Message *message;//我們需要處理的數(shù)據(jù) 復制代碼既然我們自定義的cell里面出現(xiàn)了數(shù)據(jù),我們先說一下數(shù)據(jù) .h
//枚舉類型 typedef enum {JYJMeessageTyMe = 0,JYJ_MessageTyOther = 1, } JYJ_MessageType; @interface JYJ_Message : NSObject /**內容 */ @property (nonatomic, strong) NSString *text;/** 時間 */ @property (nonatomic, strong) NSString *time;/** 類型 */ @property (nonatomic, assign) JYJ_MessageType type;/** <cellHeight> */ @property (nonatomic, assign) CGFloat cellHeight; /** 是否隱藏時間 */@property (nonatomic, assign) BOOL hideTime;- (instancetype) initWithDictionary:(NSDictionary *) dictionary; + (instancetype) messageWithDictionary:(NSDictionary *) dictionary; + (instancetype) message;復制代碼.m
- (instancetype) initWithDictionary:(NSDictionary *) dictionary {if (self = [super init]) {[self setValuesForKeysWithDictionary:dictionary];}return self; }+ (instancetype) messageWithDictionary:(NSDictionary *) dictionary {return [[self alloc] initWithDictionary:dictionary]; }+ (instancetype) message {return [self messageWithDictionary:nil]; } - (void)setValue:(id)value forUndefinedKey:(NSString *)key {}復制代碼其實大部分的代碼都是我們自定義的cell里面,里面的一些判斷和計算。不要忘記把我們自己封裝的方法引進來
#import "NSString+Extension.h" #import "UIImage+Extension.h" 復制代碼cell的.m 我們在延展中寫的一些屬性
@interface JYJ_CustomChatTableViewCell () //時間 @property (nonatomic, strong) UILabel *timeLabel; /** 頭像 */ @property(nonatomic, weak) UIImageView *iconView;/** 信息 */ @property(nonatomic, weak) UIButton *textView;@end復制代碼下面開始了長篇大論
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {[self createSubViews];}return self; } - (void)createSubViews {self.timeLabel = [[UILabel alloc]init];[self.contentView addSubview:_timeLabel];self.timeLabel.textColor = [UIColor whiteColor];// 2.頭像UIImageView *iconView = [[UIImageView alloc] init];[self.contentView addSubview:iconView];self.iconView = iconView;// 3.信息UIButton *textView = [UIButton buttonWithType:UIButtonTypeCustom];[textView setTitle:@"text" forState:UIControlStateNormal];textView.titleLabel.font = [UIFont systemFontOfSize:13];// 3.1 如果是淺色背景,記得設置字體顏色,因為按鈕的字體顏色默認是白色[textView setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];[textView.titleLabel setNumberOfLines:0]; // 設置自動換行// 3.2 調整文字的內邊距textView.contentEdgeInsets = UIEdgeInsetsMake(20, 20, 20, 20);[self.contentView addSubview:textView];self.textView = textView;} - (void)setMessage:(JYJ_Message *)message {_message = message;// 間隙CGFloat padding = 10;// 1.發(fā)送時間if ( message.hideTime == NO) {[self.timeLabel mas_makeConstraints:^(MASConstraintMaker *make) {make.centerX.mas_equalTo(self.mas_centerX);make.top.equalTo(self.mas_top).offset(0);}];self.timeLabel.text = message.time;}// 2.頭像CGFloat iconWidth = 40;CGFloat iconHeight = 40;// 2.1 根據(jù)信息的發(fā)送方調整頭像位置CGFloat iconX;if ( message.type ==JYJMeessageTyMe) {// 我方,放在右邊iconX = [UIScreen mainScreen].bounds.size.width - padding - iconWidth;self.iconView.image = [UIImage imageNamed:@"me"];} else {// 對方,放在左邊iconX = padding;self.iconView.image = [UIImage imageNamed:@"other"];}CGFloat iconY = CGRectGetMaxY(_timeLabel.frame) + padding;_iconView.frame = CGRectMake(iconX, iconY, iconWidth, iconHeight);// 3.信息,尺寸可變CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width;// 3.1 設置文本最大尺寸CGSize textMaxSize = CGSizeMake(screenWidth - iconWidth - padding * 10, MAXFLOAT);// 3.2 計算文本真實尺寸CGSize textRealSize = [message.text sizeWithFont:MESSAGE_TEXT_FONT maxSize:textMaxSize];// 3.3 按鈕尺寸CGSize btnSize = CGSizeMake(textRealSize.width + TEXT_INSET*2, textRealSize.height + TEXT_INSET*2);// 3.4 調整信息的位置// 設置聊天框NSString *chatImageNormalName;NSString *chatImageHighlightedName;CGFloat textX;if (message.type == JYJMeessageTyMe) {// 我方,放在靠右textX = CGRectGetMinX(_iconView.frame) - btnSize.width - padding;chatImageNormalName = @"chat_send_nor";chatImageHighlightedName = @"chat_send_press_pic";} else {// 對方,放在靠左textX = CGRectGetMaxX(_iconView.frame) + padding;chatImageNormalName = @"chat_recive_nor";chatImageHighlightedName = @"chat_receive_press_pic";}UIImage *chatImageNormal = [UIImage resizableImage:chatImageNormalName];UIImage *chatImageHighlighted = [UIImage resizableImage:chatImageHighlightedName];[self.textView setBackgroundImage:chatImageNormal forState:UIControlStateNormal];[self.textView setBackgroundImage:chatImageHighlighted forState:UIControlStateHighlighted];CGFloat textY = iconY;_textView.frame = CGRectMake(textX, textY, btnSize.width, btnSize.height);[self.textView setTitle:message.text forState:UIControlStateNormal];// 4.cell的高度CGFloat iconMaxY = CGRectGetMaxY(_iconView.frame);CGFloat textMaxY = CGRectGetMaxY(_textView.frame);message.cellHeight = MAX(iconMaxY, textMaxY) + padding; }復制代碼好了所有的處理基本完畢。我寫了一個本地的數(shù)據(jù)用plist文件存儲的,當然也是看網(wǎng)上那么寫的我們copy了過來。
其實自己寫一條就好,不用往里面寫那么多。 在VC中處理數(shù)據(jù) - (void)handale {NSArray *dictArray = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"messages.plist" ofType:nil]];NSMutableArray *mdictArray = [NSMutableArray array];for (NSDictionary *dict in dictArray) {JYJ_Message *message = [JYJ_Message messageWithDictionary:dict];// 判斷是否發(fā)送時間與上一條信息的發(fā)送時間相同,若是則不用顯示了if ([mdictArray lastObject]&&[message.time isEqualToString:[self.messages lastObject]]) {message.hideTime = YES;}[mdictArray addObject:message];}_messages = mdictArray;[self.tableView reloadData];}復制代碼處理返回cell的高度
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {JYJ_Message *message = self.messages[indexPath.row];return message.cellHeight; } 復制代碼下面是處理點擊回車自己發(fā)送信息的處理 textFiled別忘了簽代理
// TextFiled代理方法 //回車響應事件 - (BOOL)textFieldShouldReturn:(UITextField *)textField {if ([self.bottomView.inPutTextField.text isEqualToString:@""]) {NSLog(@".....");}else {//我方發(fā)出信息[self sendMessage:textField.text andType:JYJMeessageTyMe];//自動回復[self sendMessage:[NSString stringWithFormat:@"%@\n%@",textField.text,@"你妹!"] andType:JYJ_MessageTyOther];//消息框清除self.bottomView.inPutTextField.text = nil;[self.tableView reloadData];//滾動到最新信息NSIndexPath *lastIndePath = [NSIndexPath indexPathForRow:self.messages.count - 1 inSection:0];[self.tableView scrollToRowAtIndexPath:lastIndePath atScrollPosition:UITableViewScrollPositionBottom animated:YES];}return YES; }- (void)sendMessage:(NSString *)text andType:(JYJ_MessageType)type {//獲取當前時間NSDate *date = [NSDate date];NSDateFormatter *formatter = [[NSDateFormatter alloc]init];formatter.dateFormat = @"yyyy-MMM-dd hh:mm:ss";NSString *dateStr = [formatter stringFromDate:date];// 我方發(fā)出信息NSDictionary *dic = @{@"text":text,@"time":dateStr,@"type":[NSString stringWithFormat:@"%d",type]};JYJ_Message *message = [[JYJ_Message alloc]init];[message setValuesForKeysWithDictionary:dic];[self.messages addObject:message]; }復制代碼還有VC最下面的View自己創(chuàng)建吧 ,不用我說了。 希望對大家有幫助吧,大家一起學習,一起進步。有不明白的或者我寫的不好的地方,大家可以給我評論呦!!!
總結
- 上一篇: Android NDK开发之旅14 J
- 下一篇: .NET Core 使用 nlog 进行