6

I need to create a simple chat view in which i can show messages from two ends (sender and receiver) like any Message App .

What i have done till now is , created a UITableView , A UIButton and a UITextField. And on that UIButton tap , i am adding UITextField text to array , Now I need the second end also like in ours Messaging app (sender side).

Left side is receiver and Right side is sender.

My app till now looks like

enter image description here

Here is my code:

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

static NSString *CellIdentifier = @"Cell";

messageLabel = nil;

UITableViewCell *cell = [tableView
                         dequeueReusableCellWithIdentifier:CellIdentifier];

if (cell == nil) {

    cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];

    messageLabel = [[UILabel alloc] init];
    messageLabel.tag = 101;
    [cell.contentView addSubview: messageLabel];

      } else {


    messageLabel = (UILabel*)[cell.contentView viewWithTag: 101];

      }    //---calculate the height for the label---
int labelHeight = [self labelHeight:[listOfMessages objectAtIndex:indexPath.row]];
labelHeight -= bubbleFragment_height;
if (labelHeight<0) labelHeight = 0;

messageLabel.frame =
CGRectMake(bubble_x + 10, bubble_y + 5,
           (bubbleFragment_width * 3) - 25,
           (bubbleFragment_height * 2) + labelHeight - 10);

messageLabel.font = [UIFont systemFontOfSize:15];
messageLabel.textAlignment = NSTextAlignmentCenter;
messageLabel.textColor = [UIColor darkTextColor];
messageLabel.backgroundColor = [UIColor greenColor];
messageLabel.numberOfLines = 0;
messageLabel.layer.cornerRadius = 8;
messageLabel.layer.masksToBounds = YES;

messageLabel.text = [listOfMessages objectAtIndex:indexPath.row];
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];

return cell;
}

-(void) sendAction:(id) sender {
[listOfMessages addObject:field.text];

[chatTable reloadData];
field.text = @"";

[field resignFirstResponder];
 }
JAY RAPARKA
  • 1,353
  • 2
  • 13
  • 33
ios
  • 955
  • 1
  • 12
  • 35

2 Answers2

7

You can take two different custom cells one for the sender and one for the receiver like this:

for sender

  1. for Sender

for receiver

  1. for Receiver

Now, in your app, there must be login and sign-up process as it is a chat app and there will be server associated with your app to save data.

What you can do is that, when you send the message, also send the name of the receiver with it and store it in your database.

Now, in your chat view, fetch all the message data, along with the receiver names.

Fetch the userName who is currently logged in during the Login process.

You can do something like this in your cellForRowAtIndexPath:

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

    NSString *myArrayElement = [arr_receiverUserName objectAtIndex:indexPath.row];

    //do something useful with myArrayElement

    if(![myArrayElement isEqualToString:userName])
    {
         /// These are my messages.
         //// Pop up 'mycell' here 

            UILabel *lbl_myText = [[UILabel alloc]initWithFrame:CGRectZero];
            [lbl_myText setLineBreakMode:NSLineBreakByWordWrapping];
            lbl_myText.minimumScaleFactor = FONT_SIZE;
            [lbl_myText setNumberOfLines:0];
            lbl_myText.textAlignment = NSTextAlignmentRight;
            [lbl_myText setFont:[UIFont systemFontOfSize:FONT_SIZE]];

            NSString *text = [arr_text objectAtIndex:indexPath.row];

            CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE]];

            // Checks if text is multi-line
            if (size.width > lbl_myText.bounds.size.width)
            {
                CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);

                CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:NSLineBreakByWordWrapping];

                [lbl_myText setText:text];
                [lbl_myText setFrame:CGRectMake(CELL_CONTENT_MARGIN, CELL_CONTENT_MARGIN, CELL_CONTENT_WIDTH - cell.imgv_myImage.frame.size.width -(CELL_CONTENT_MARGIN * 2), MAX(size.height, 44.0f))];
            }

            else
            {
                lbl_myText.frame = CGRectMake(10, 0, cell.frame.size.width - cell.imgv_myImage.frame.size.width - 18,18);
                lbl_myText.textAlignment = NSTextAlignmentRight;
                [lbl_myText setText:text];
            }

            //lbl_myText.backgroundColor = [UIColor greenColor];

            [cell.contentView addSubview:lbl_myText];

    }

    else
    {
        //// These are the messages sent by some one else

       /// Pop up `someonecell` here

        UILabel *lbl_myText = [[UILabel alloc]initWithFrame:CGRectZero];
        [lbl_myText setLineBreakMode:NSLineBreakByWordWrapping];
        lbl_myText.minimumScaleFactor = FONT_SIZE;
        [lbl_myText setNumberOfLines:0];
        lbl_myText.textAlignment = NSTextAlignmentLeft;
        [lbl_myText setFont:[UIFont systemFontOfSize:FONT_SIZE]];

        NSString *text = [arr_text objectAtIndex:indexPath.row];

        CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE]];

        // Checks if text is multi-line
        if (size.width > lbl_myText.bounds.size.width)
        {
            CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);

            CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:NSLineBreakByWordWrapping];

            [lbl_myText setText:text];
            [lbl_myText setFrame:CGRectMake(cell.imgv_someoneImage.frame.size.width+8, CELL_CONTENT_MARGIN, CELL_CONTENT_WIDTH - cell.imgv_someoneImage.frame.size.width -(CELL_CONTENT_MARGIN * 2), MAX(size.height, 44.0f))];
        }

        else
        {
            lbl_myText.frame = CGRectMake(10, 0, cell.frame.size.width - cell.imgv_someoneImage.frame.size.width - 18,18);
            lbl_myText.textAlignment = NSTextAlignmentLeft;
            [lbl_myText setText:text];
        }

        //lbl_myText.backgroundColor = [UIColor greenColor];

        [cell.contentView addSubview:lbl_myText];

    }

You can do similar things for images and audios.


For Dynamic Height Of The Cell:

To make to the height of your cell according to your UILabels, refer to Increase the main tableview row height according to the custom cell

Community
  • 1
  • 1
Rumin
  • 3,787
  • 3
  • 27
  • 30
  • I am not using nibs or storyboard , Can you tell me by code How to implement it – ios Oct 07 '15 at 06:23
  • I have updated the answer... But why you want to make things difficult for yourself... if you can do it using nibs or storyboard? – Rumin Oct 07 '15 at 06:30
  • I have never used nib files. So, I was asking .. But i ll try to use nibs alos – ios Oct 07 '15 at 06:37
  • I have added both the things in the answer. You will need both. – Rumin Oct 07 '15 at 06:38
  • Ok ,, Ill try n come back ... Thanks Rumin – ios Oct 07 '15 at 06:41
  • Hi Rumin , I have been able to implement this with two custom cells on two different nib files . How to set labels frame , So that it will become equivalent to the text size . – ios Oct 08 '15 at 07:17
  • Hello @Ammy I have already answered that thing here: http://stackoverflow.com/questions/26210816/increase-the-main-tableview-row-height-according-to-the-custom-cell/33006937#33006937... Let me know if you have any problem, implementing it. – Rumin Oct 08 '15 at 07:20
  • Thanks but the my labels frames are not updating . I dont know whats wrong .? I have added two nibs and just dragged two labels on it and make their OutLet – ios Oct 08 '15 at 07:35
  • Create those label programmatically as I have done. You will be through with it. I was also stuck with the same problem earlier as you are facing now. I ended up doing it programmatically and it works. Moreover, the text will be dynamic so it is better to do it in that way. – Rumin Oct 08 '15 at 07:38
  • Glad to help you Ammy.. if the answer in the link was also helpful to you, you can vote it as useful there also! :) – Rumin Oct 08 '15 at 07:53
  • @RoOmin hi have u have any sample project for settign chat left and right – ChenSmile Apr 06 '17 at 12:32
  • @SaurabhDutta...Hi I'm also implementing same feature...Please provide sample code if u implemented. thanks in advance – Priya Jun 11 '18 at 04:13
  • @Rumin...I'm also implementing same chat feature...Please provide sample code if possible for above explanation...thanks in advance – Priya Jun 11 '18 at 04:33
  • @Priya Here are the links [Chat Demo](https://github.com/rumin26/chatDemoAppplication) and [Tinder Demo](https://github.com/rumin26/Marvel-DC-Tinder). The first one may be outdated because of Parse dependency but you can refer the code and get the idea. – Rumin Jun 11 '18 at 19:31
  • @Rumin...Thank you so much. – Priya Jun 13 '18 at 07:23
3

You need to create multiple cell with different CellIdentifier For Example. Cell For sender and receiver. And you can subdivide it in categories like text,audio,video,image.

Download sample ChatUI Demo (Objective-C & Swift) from here

Lets have example for the text chat.

First of all you need to create 2 cell prototypes in your Storyboard or XIB with different CellIdentifier for example "cellSender" and "cellReceiver".

Take UILabel or UITextView inside cell and for cellSender make left alignment and for cellReceiver make the alignment right for making different layout for sender and receiver.

Then You can do with following with your code...

  - (UITableViewCell *)tableView:(UITableView *)tableView
         cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    BOOL sender = NO;

// Check for the sender or receiver 
    <code for checking message is from sender or receiver>

    static NSString *CellIdentifier = sender?@"cellSender":@"cellReceiver";

    messageLabel = nil;

    UITableViewCell *cell = [tableView
                             dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {

        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];

        messageLabel = [[UILabel alloc] init];
        messageLabel.tag = 101;
        [cell.contentView addSubview: messageLabel];

          } else {


        messageLabel = (UILabel*)[cell.contentView viewWithTag: 101];

          }    //---calculate the height for the label---
    int labelHeight = [self labelHeight:[listOfMessages objectAtIndex:indexPath.row]];
    labelHeight -= bubbleFragment_height;
    if (labelHeight<0) labelHeight = 0;

    messageLabel.frame =
    CGRectMake(bubble_x + 10, bubble_y + 5,
               (bubbleFragment_width * 3) - 25,
               (bubbleFragment_height * 2) + labelHeight - 10);

    messageLabel.font = [UIFont systemFontOfSize:15];
    messageLabel.textAlignment = NSTextAlignmentLeft;
    messageLabel.textColor = [UIColor darkTextColor];
    messageLabel.backgroundColor = sender? [UIColor greenColor]: [UIColor lightGrayColor];
    messageLabel.numberOfLines = 0;
    messageLabel.layer.cornerRadius = 8;
    messageLabel.layer.masksToBounds = YES;

    messageLabel.text = [listOfMessages objectAtIndex:indexPath.row];
    [cell setSelectionStyle:UITableViewCellSelectionStyleNone];

    return cell;
    }

EDIT

Screen 1 Screen 2

mrunal thanki
  • 753
  • 6
  • 16
  • How to create 2 cell prototypes . As i am not using StoryBoard or Xibs – ios Oct 07 '15 at 06:15
  • Hi mural , I have been able to implement this with two custom cells on two different nib files . How to set labels frame , So that it will become equivalent to the text size . – ios Oct 08 '15 at 07:18
  • 1
    @mrunal thanki....Please provide sample code for above explanation...i'm also required same feature – Priya Jun 11 '18 at 04:14
  • Hi @Priya, You can find demo for simple chat UI from my above edits. – mrunal thanki Jun 12 '18 at 06:11
  • @mrunalthanki...please update in Objective-C.Thanks in advance – Priya Jun 13 '18 at 01:37
  • @Priya I have added Objective-C code in same link. You can download it from above link. – mrunal thanki Jun 13 '18 at 18:43
  • @mrunalthanki...Thank you so much...Must appreciate for quick reply – Priya Jun 14 '18 at 08:16
  • @mrunalthanki...How to display the receiver message at left side (Response from server like :: success - true / success - false. if success -true show in collection view / If success - false display in tableview cell at left side) – Priya Jun 18 '18 at 07:25
  • @Priya added UICollectionView in UITableViewCell..Please download demo and check it. – mrunal thanki Jun 20 '18 at 17:40
  • @mrunalthanki...How can i Updated the UI with a Text field sir – Priya Jun 25 '18 at 05:24