您的位置:首页 > 移动开发 > IOS开发

iOS——tableview高度自适应(简单的聊天界面)

2019-08-09 17:12 1671 查看

难点

  • UITableView的高度自适应
  • 发送消息后,在最后添加一行新的cell,并更新tableView

具体实现

(iPhone8 plus)

  • 首先建立起主要的页面框架,就是tableView,和输入框等。
//创建一个tableaView
_tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, WIDTH, HEIGHT - 60) style:UITableViewStylePlain];
_tableView.backgroundColor  = [UIColor whiteColor];
//设置分割线的style
_tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
//设置代理
_tableView.delegate = self;
_tableView.dataSource = self;
//注册
[_tableView registerClass:[ZWYTableViewCell class] forCellReuseIdentifier:cellInIdentifier];
[self.view addSubview:_tableView];

//输入框的设置
_messgeTextField = [[UITextField alloc] init];
_messgeTextField.frame = CGRectMake(0, 0, WIDTH - 20, 45);
_messgeTextField.borderStyle = UITextBorderStyleRoundedRect;
_messgeTextField.layer.borderWidth = 2;
_messgeTextField.layer.borderColor = [UIColor blackColor].CGColor;
_messgeTextField.delegate = self;
[self.view addSubview:_messgeTextField];

//设置发送Button
UIButton *sendButton = [[UIButton alloc] init];
sendButton.frame = CGRectMake(0, 0,  50, 45);
[sendButton setTitle:@"发送" forState:UIControlStateNormal];
[sendButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
sendButton.backgroundColor = [UIColor orangeColor];
[sendButton addTarget:self action:@selector(send) forControlEvents:UIControlEventTouchUpInside];
_messgeTextField.rightViewMode = UITextFieldViewModeAlways;
_messgeTextField.rightView = sendButton;

//将输入框和发送Button添加在一个cell上
UIView *bottomView = [[UIView alloc] initWithFrame:CGRectMake(0, HEIGHT - 60, WIDTH, 60)];
bottomView.backgroundColor = [UIColor colorWithRed:243/255.0 green:243/255.0 blue:243/255.0 alpha:1];
[self.view addSubview:bottomView];
[bottomView addSubview:_messgeTextField];
  • 创建数据源,里面是,文字,就是很简单的文字内容
//创建各项数据
-(void)creatData :(NSMutableArray *)messageArray {
for (NSString *str  in messageArray) {
//定义一个字典
NSMutableDictionary *dic = [[NSMutableDictionary alloc] init];
//获取label的高度
CGFloat labheight = [self getWidth:WIDTH / 2 title:str font:[UIFont systemFontOfSize:30]];
//在字典中加入label的高度
[dic setValue:[NSString stringWithFormat:@"%f", labheight] forKey:@"labheight"];
//设置cell的高度(因为头每个聊天信息,都有一个头像,头像大小时已经确定的为50*50)
CGFloat height;
if (labheight  > 30) {
height = labheight + 30 ;
} else {
height = 50.0;
}
//cell高度
[dic setValue:[NSString stringWithFormat:@"%f", height] forKey:@"cellheight"];
//在字典中加入label中的文字
[dic setValue:str forKey:@"info"];
//将每个label对应的字典加入在数组中
[_dataArray addObject:dic];
}
//数据创建完成
}

最好,我们在数据源中就要完成cell的高度的计算

  • UILabel的高度计算
//label获取高度的方法
-(CGFloat)getWidth:(CGFloat)width title:(NSString *)title font:(UIFont *)font {
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, width, 0)];
label.text = title;
label.font = font;
//自适应
label.numberOfLines = 0;
[label sizeToFit];
//经过自适应之后的label,已经有新的高度
CGFloat height = label.frame.size.height;

return height;
}
  • 实现TableView的协议

返回数据源中数组的个数

//根据数组中的字典个数,返回row
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

return  _dataArray.count;
}

section默认为1,所以可以不用设置

实现cell
Tips:一般不要在复用池内创建UI类的东西,会影响TableView的性能

//设置cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
ZWYTableViewCell *cell = [_tableView dequeueReusableCellWithIdentifier:cellInIdentifier forIndexPath:indexPath];
//这是自己的对话信息
if (indexPath.row % 2 == 0) {
[cell getImageName:@"非正2.jpg" getLabelInfo:[[_dataArray objectAtIndex:indexPath.row] objectForKey: @"info"] getHeight:[[_dataArray objectAtIndex:indexPath.row] objectForKey:@"labheight"]  andIndexpath:indexPath];
} else {
[cell getImageName:@"非正4.jpg" getLabelInfo:[[_dataArray objectAtIndex:indexPath.row] objectForKey: @"info"] getHeight:[[_dataArray objectAtIndex:indexPath.row] objectForKey:@"labheight"]  andIndexpath:indexPath];
}//对方的对话信息
return cell;
}
  • 自定义的cell
    在TableViewCell.h文件里面,定义好我们需要的控件
@interface ZWYTableViewCell : UITableViewCell
//文字label的位置y,因为不同的消息发送者,label的位置是不同的
@property CGFloat labelleft;
//头像的位置y,与文字同理
@property CGFloat imageleft;
//label的高度
@property CGFloat labelHeight;
@property UIImageView *touimageView;
@property UILabel *messageLabel;
//是一个方法,get 到一些高度等一些数据。
-(void)getImageName:(NSString *)name getLabelInfo:(NSString *)Info  getHeight:(NSString *)labelHeight andIndexpath:(NSIndexPath *)indexPath;
@end

高度

//根据数组中字典里cellheight的数值返回cell的高度
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return [[[_dataArray objectAtIndex:indexPath.row] objectForKey:@"cellheight"]floatValue];
}

TableViewCell.m文件里面

//初始化方法
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];

self.messageLabel = [[UILabel alloc] init];
[self.contentView addSubview:_messageLabel];

self.touimageView = [[UIImageView alloc] init];
[self.contentView addSubview:_touimageView];

return self;
}

//get方法
- (void)getImageName:(NSString *)name getLabelInfo:(NSString *)Info getHeight:(NSString *)labelHeight andIndexpath:(NSIndexPath *)indexPath  {

//设置图像
self.touimageView.image = [UIImage imageNamed:name];
self.messageLabel.text = Info;
self.messageLabel.numberOfLines = 0;
//得到label的高度
_labelHeight = [labelHeight floatValue];
if (indexPath.row % 2 == 0) {
_labelleft = [UIScreen mainScreen].bounds.size.width / 2;
_imageleft = [UIScreen mainScreen].bounds.size.width - 50;
_messageLabel.backgroundColor = [UIColor colorWithRed:236/255.0 green:236/255.0 blue:236/255.0 alpha:1.0];
} else {
_labelleft = 60;
_imageleft = 0;

}

}
//视图方法
- (void)layoutSubviews {
[super layoutSubviews];

_messageLabel.frame = CGRectMake(_labelleft, 10, ([UIScreen mainScreen].bounds.size.width - 150 )/ 2, _labelHeight);
_messageLabel.layer.borderColor = [UIColor blackColor].CGColor;
_messageLabel.layer.borderWidth = 1;
_messageLabel.layer.cornerRadius = 10;
_messageLabel.textAlignment = NSTextAlignmentCenter;

_touimageView.frame = CGRectMake(_imageleft, 10, 50, 50);
}

以上就是tableView的高度自适应中所要用到的东西,
下面就是ViewControll中要实现聊天功能的东西
viewController.m

//在ViewDidLaod中,紧接上面的代码
//初始的聊天信息
_messageArray = [NSMutableArray arrayWithObjects:@"你拍的真不错!", @"谢谢,已关注你", @"好专业的照片,非常喜欢", @"nice", nil];
_dataArray = [NSMutableArray array];
//进行数据的初始化
[self creatData:_messageArray];

//键盘回收事件
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];

发送信息,进行数据的更新

//发送信息
-(void)send {
//建立一个可变数组,用来存储,发送的信息
NSMutableArray *array = [NSMutableArray array];
//将输入框的信息加入两次,是要让对方返回一样的信息
[array addObject:_messgeTextField.text];
//继续在数组中加入数据
[self creatData:array];
//数据更新
[_tableView reloadData];
//清空输入框
_messgeTextField.text = @"";
//设置滚动到底部,
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:(_dataArray.count - 1) inSection:0];
[self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:NO];
}

键盘的相关,及细节方面

//键盘出现
-(void)keyboardWillShow : (NSNotification *)notify {
//计算键盘高度
CGFloat kbHeight = [[notify.userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size.height;

CGFloat offset = kbHeight;

double duration = [[notify.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];

//视图上移
if (offset > 0) {
[UIView animateWithDuration:duration animations:^{
self.view.frame = CGRectMake(0.0f, -offset, self.view.frame.size.width, self.view.frame.size.height);
}];
}
}

//键盘回收,视图下移
-(void)keyboardWillHide: (NSNotification *)notify {
double duration = [[notify.userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] doubleValue];
[UIView animateWithDuration:duration animations:^{
self.view.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
}];
}

//选择cell取消阴影
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:NO];
}

这样一个简单的聊天界面就做好了
看下效果图
初始时的对话

这是键盘弹出后,视图上移的效果

然后这是,我发送几句话后的效果


会发现,当键盘快要挡住消息时,视图会自动上移。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: