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

难点

  • 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];
}

这样一个简单的聊天界面就做好了
看下效果图
初始时的对话
在这里插入图片描述
这是键盘弹出后,视图上移的效果
在这里插入图片描述
然后这是,我发送几句话后的效果
在这里插入图片描述
在这里插入图片描述
会发现,当键盘快要挡住消息时,视图会自动上移。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值