zoukankan      html  css  js  c++  java
  • ios 气泡聊天

    最近做的项目里面,有几个模块用到了聊天功能和评论回复的功能,使用的频率还是很高的,所以抽时间做了这个博客,希望能给自己和别人带来方便,

    具体代码如下:

    1,创建model,

    #import <Foundation/Foundation.h>
    
    @interface MessageObj : NSObject
    
    @property(nonatomic,copy)NSString *message;
    @property(nonatomic,assign)BOOL isMe;
    
    @end

    2,自定义cell

    1)声明一个label和imageview

    @property(nonatomic,strong)UIImageView *messageImg;
    @property(nonatomic,strong)UILabel *messageLab;

    2)初始化构造方法

    -(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
    {
        self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
        if (self) {
            //这里只需要初始化,不需要设置具体的坐标
            self.backgroundColor = [UIColor clearColor];
            self.selectionStyle = UITableViewCellSelectionStyleNone;
            _messageImg = [[UIImageView alloc]init];
            [self addSubview:_messageImg];
            _messageLab = [[UILabel alloc]init];
            _messageLab.numberOfLines = 0;
            [self addSubview:_messageLab];
        }
        
        return self;
    }

    3,准备工作已做好,现在进行聊天功能的完善

    1)声明所需的成员变量

    @interface ViewController ()<UITextFieldDelegate,UITableViewDelegate,UITableViewDataSource>
    {
        UITextField *tf;
        UIView *inputView;
        UIButton *rightBtn;
        UITableView *tableViews;
        
        int _count;
        NSMutableArray *_datasArray;
    }

    2)界面的布局,做好适配

    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view.
        _datasArray = [NSMutableArray array];//这里一定要记得初始化
        
        self.title = @"气泡聊天";
        self.view.backgroundColor = [UIColor whiteColor];
        
        tableViews = [[UITableView alloc]initWithFrame:CGRectMake(0, 0, MainScreen_width, self.view.bounds.size.height-60) style:UITableViewStylePlain];
        tableViews.delegate = self;
        tableViews.dataSource = self;
        tableViews.tableFooterView = [[UIView alloc]init];
        tableViews.separatorStyle = UITableViewCellSeparatorStyleNone;
        [self.view addSubview:tableViews];
        
        
        inputView = [[UIView alloc]initWithFrame:CGRectMake(0, MainScreen_height - 50, MainScreen_width, 60)];
        inputView.backgroundColor = RGBAColor(159, 159, 159, 1);
        [self.view addSubview:inputView];
        
        tf = [[UITextField alloc]initWithFrame:CGRectMake(10, 3, MainScreen_width - 60, 50)];
        tf.delegate = self;
        tf.returnKeyType = UIReturnKeyDefault;
        [inputView addSubview:tf];
        
        rightBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        rightBtn.frame = CGRectMake(MainScreen_width - 50-5, 3, MainScreen_width - tf.frame.size.width, 50);
        [rightBtn setTitle:@"发送" forState:UIControlStateNormal];
        [rightBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
        [rightBtn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
        [inputView addSubview:rightBtn];
        
        //增加监听,当键盘改变是发出消息
        [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
        
        //增加监听,当键盘退出时发出消息
        [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
    }

    注:这里最后,声明了两个通知,这样是为了,监听键盘弹出和弹下的高度,

    具体实现如下:

    -(void)keyboardWillShow:(NSNotification *)hNotification
    {
        //获取键盘的高度
        NSDictionary *userInfo = [hNotification userInfo];
        NSValue *aValue = [userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];
        CGRect keyboardRect = [aValue CGRectValue];
        int height = keyboardRect.size.height;//获取到的键盘的高度
        [UIView animateWithDuration:0.1 animations:^{
            CGRect tableFrame = tableViews.frame;
            tableFrame.size.height = MainScreen_height - height - 60;
            tableViews.frame = tableFrame;
            CGRect rect = inputView.frame;
            rect.origin.y = MainScreen_height - height - 60;
            inputView.frame = rect;
        }];
        
    }
    
    -(void)keyboardWillHide:(NSNotification *)hNotification
    {
        [UIView animateWithDuration:0.1 animations:^{
            CGRect tableViewRect = tableViews.frame;
            tableViewRect.size.height = MainScreen_height- 60;
            tableViews.frame = tableViewRect;
            CGRect rect = inputView.frame;
            rect.origin.y = MainScreen_height - 60;
            inputView.frame = rect;
        }];
        
        if (_datasArray.count > 0)
        {
            //让表的最后一行滚动到表的底部
            NSIndexPath * indexPath = [NSIndexPath indexPathForRow:_datasArray.count-1 inSection:0];
            [tableViews scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
        }
    }

    3)发送按钮的点击方法

    -(void)btnClick:(id)sender
    {
        _count ++;//这里声明一个int类型的变量是为了下面区分是否是自己
        
        //这里使用model,会很方便,单独作为对象来使用,方便进行设置
        MessageObj *objets = [[MessageObj alloc]init];
        objets.message = tf.text;
        
        if (objets.message != nil && [objets.message isEqualToString:@""]) {
            UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:@"温馨体香" message:@"不能为空" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:nil, nil];
            [alertView show];
            return;
        }else
        {
            //这里通过第一个发送的顺序,设为自己,其他为别人,然后绑定一个bool值的状态,yes为自己,no为别人
            if (_count%2 == 1) {
                objets.isMe = YES;
            }else
            {
                objets.isMe = NO;
            }
            
            [_datasArray addObject:objets];
            NSLog(@"--%lu",(unsigned long)_datasArray.count);
            [tableViews reloadData];
            
            //让表的最后一行滚动到表的底部
            NSIndexPath * indexPath = [NSIndexPath indexPathForRow:_datasArray.count-1 inSection:0];
            [tableViews scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
            
            tf.text = nil;
        }
    }

    注:这里面有比较重要的地方,代码很详细,我就不一一解释了,大家可以自己看

    4)表的具体展现和自适应

    -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
        return _datasArray.count;
    }
    
    -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        MessageObj *object = _datasArray[indexPath.row];
        
        CGFloat contentW = MainScreen_width - 34;
        
        UIFont *fnt = [UIFont fontWithName:@"HelveticaNeue" size:18.0f];
        
        //ios 7 以后的方法,这里得到自适应的高度,从而动态的设置cell的高度
        CGRect tempRect = [object.message boundingRectWithSize:CGSizeMake(contentW, 1000) options:NSStringDrawingUsesLineFragmentOrigin attributes:[NSDictionary dictionaryWithObjectsAndKeys:fnt,NSFontAttributeName, nil] context:nil];
        CGFloat contenH = tempRect.size.height;
        
        return contenH + 20;
    }
    
    -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        static NSString *cellIdentifiers = @"CELLES";
        EightyTableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
        if (!cell) {
            
            cell = [[EightyTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifiers];
            cell.selectionStyle = UITableViewCellSelectionStyleDefault;
        }
        
        MessageObj *object = _datasArray[indexPath.row];
        /*
         CGFloat contentW = MainScreen_width - 34;
         
         UIFont *fnt = [UIFont fontWithName:@"HelveticaNeue" size:18.0f];
         
         CGRect tempRect = [object.message boundingRectWithSize:CGSizeMake(320, 1000) options:NSStringDrawingUsesLineFragmentOrigin attributes:[NSDictionary dictionaryWithObjectsAndKeys:fnt,NSFontAttributeName, nil] context:nil];
         CGFloat contenH = tempRect.size.height;
         */
        
        //在这里进行宽度和高度的自适应
        UIFont *fnt = [UIFont fontWithName:@"HelveticaNeue" size:18.0f];
        CGSize size = CGSizeMake(MainScreen_width,1000);
        CGSize labSize = [object.message sizeWithFont:fnt constrainedToSize:size lineBreakMode:UILineBreakModeWordWrap];
        
        
        if (object.isMe == YES) {
            
            cell.messageLab.frame = CGRectMake(20, 0, labSize.width, labSize.height);
            cell.messageLab.textAlignment = NSTextAlignmentLeft;
            cell.messageLab.numberOfLines = 0;
            cell.messageImg.frame = CGRectMake(10, 0, labSize.width+20, labSize.height+10);
        }else
        {
            cell.messageLab.frame = CGRectMake(MainScreen_width - 20 - labSize.width, 5, labSize.width, labSize.height);
            cell.messageLab.numberOfLines = 0;
            cell.messageLab.textAlignment = NSTextAlignmentRight;
            cell.messageImg.frame = CGRectMake(MainScreen_width - 30 - labSize.width, 2, labSize.width + 20, labSize.height + 10);
        }
        
        NSString *imageName = object.isMe?@"bubbleSelf.png":@"bubble.png";
        UIImage *oldImage = [UIImage imageNamed:imageName];
        UIImage *newImage = [oldImage stretchableImageWithLeftCapWidth:18 topCapHeight:8];
        cell.messageImg.image = newImage;
        cell.messageLab.font = fnt;
        cell.messageLab.text = object.message;
        
        return  cell;
        
    }

    注:主要就是cellforrow方法里面的lab自适应坐标的设置,还有气泡背景图片的坐标设置,还有heightforrow里面根据lab的高度,动态判定cell的高度

    效果图如下:

    如需源码,可从这里下载:http://code.cocoachina.com/view/131767

  • 相关阅读:
    Python变量常量命名
    代码格式
    Python 输入输出
    数据源
    LaTeX Test
    软件工程
    eclipse-智能提示设置
    java代码里设置指定颜色常值
    命令行中Vim直接打开某行
    Vim里快速替换命令
  • 原文地址:https://www.cnblogs.com/hero11223/p/5627049.html
Copyright © 2011-2022 走看看