Здравствуйте, хабражители!

В этой статье я хотел бы поделиться своим опытом создания простого экрана чата, с использованием хвостатых пузырьков.



В одном из моих последних проектов я столкнулся с задачей создания очень специфических ячеек для чата. К сожалению, все готовые решения, которые я находил в свободном доступе, сводились либо к простому отображению текста в ячейках, либо к отображению текста и картинок. А те проекты, которые предлагали кастомизацию ячеек, представляли из себя настолько огромные комбайны, что тратить время и разбираться в них просто небыли ни какого желания, при том, что результат в итоге мог не покрыть мои нужды.

Т.к. на тот момент я не представлял каким образом создаются хвостатые пузырьки, а мне нужны были именно такие, я решил поискать какие-то простые проекты, которые показывали бы каким образом можно создать такую ячейку. К сожалению и этот путь привел меня в никуда, таких проектов я просто не нашел. Поэтому я решил, что придется разобраться в этой задаче с нуля и заодно выложить проект, который облегчит понимание этого вопроса другим людям.

Итак, я пролистал несколько статей на разных сайтах по данной тематике, решений на самом деле оказалось много, но мне показалось наиболее правильным использование растягиваемых изображений. В данном методе используется функция resizableImageWithCapInsets, которая создает картинку, умеющую растягиваться по ширине и высоте, но при этом не растягивать края, что очень важно, т.к. там находится хвост нашего пузырька.

Теперь расскажу поконкретнее и с примерами. Во-первых, нам нужна примерно вот такая картинка:



Назовем ее, например, bubble.

В примере ниже можно увидеть как просто создается растягиваемая картинка:

// помещаем картинку в переменную
UIImage *bubbleImage = [UIImage imageNamed:@«bubble»];
// определяем центр картинки
CGPoint center = CGPointMake(image.size.width / 2.f, image.size.height / 2.f);
// указываем, что картинка должна растягиваться из центра
UIEdgeInsets insets = UIEdgeInsetsMake(center.y, center.x, center.y, center.x);
// создаем растягиваемую картинку
UIImage *bubbleImage = [image resizableImageWithCapInsets:insets resizingMode:UIImageResizingModeStretch];


Т.к. картинка однотонная, проблем с текстурами не будет, и она сможет растягиваться на любую ширину и высоту. В моем случае максимальная ширина будет равна ширине ячейки, а высота равняться высоте текста внутри.

Далее я расскажу о еще одной маленькой проблеме. Т.к. мы тут говорим о чате, то логично, что пузырьки должны быть разными для входящего и исходящего сообщения. Конечно, можно просто использовать две разные картинки, у которых хвосты будут повернуты в разные стороны. Но, есть более элегантный способ. Можно использовать функцию + (UIImage *)imageWithCGImage:(CGImageRef)cgImage scale:(CGFloat)scale orientation:(UIImageOrientation)orientation. Она позволяет просто отразить картинку по горизонтали:
bubbleImage = [UIImage imageWithCGImage:bubbleImage.CGImage scale:bubbleImage.scale orientation:UIImageOrientationUpMirrored];


Естественно, что не плохо было бы раскрасить пузырьки в разные цвета, это очень просто делается с помощью маски. Пожалуй я не буду вставлять тут эту банальную функцию, а приглашу всех желающих ознакомиться с исходным кодом готового проекта: https://github.com/iBlacksus/BSSimpleChatBubbles

Всем спасибо за внимание, на все вопросы постараюсь ответить в комментариях или ЛС.

Комментарии (3)


  1. cher11
    02.10.2015 01:25

    Т.к. на тот момент я не представлял каким образом создаются хвостатые пузырьки, а мне нужны были именно такие, я решил поискать какие-то простые проекты, которые показывали бы каким образом можно создать такую ячейку. К сожалению и этот путь привел меня в никуда, таких проектов я просто не нашел. Поэтому я решил, что придется разобраться в этой задаче с нуля и заодно выложить проект, который облегчит понимание этого вопроса другим людям.

    alexbarinov.github.io/UIBubbleTableView
    Умеет несколько больше, чем ваш пример. Ну и сорцы подсмотреть тоже можно. Поставил бы плюс за готовое решение с поддержкой текста, фото, видео, ссылок, а в вашей статье по факту 4 строчки кода о том, как картинку растянуть. Не серьезно.

    www.cocoacontrols.com/controls/sphchatbubble
    туда же


    1. iBlacksus
      02.10.2015 02:16

      Данная статья и проект не про разухабистое решение с поддержкой «фото, видео, ссылок». Как и написано в названии, я сделал максимально простой проект, который за минимальное время дает концептуальное понятие того, как строятся ячейки чата. Это такой трамплин, который просто направляет в правильную сторону, и не является каким-то готовым решением по своей сути.

      Естественно это статья не для профессионалов, у которых за плечами десятки лет разработки под iOS. Но для людей, которые столкнутся с такой же проблемой как и я. Да, может не серьезно, но написано это все не ради плюсов, просто лично мне подобная статья ранее сэкономила бы много времени.


      1. cher11
        02.10.2015 04:10
        +1

        Посмотрел сам проект, написано очень чисто, спору нет. Основная моя претензия не в том, что Вам надо было сделать «комбайн», а в том, что вы слишком поверхностно описали свое решение. Ну и заявили, что таких проектов нет — а они есть :)
        Вам можно было осветить, например, такие вещи, как правильное размещение текста внутри облачка, способ задания ограничения ячейки по ширине и так далее, это тоже вещи, с первого раза не очень понятные. Ну или еще интересная проблема — сделать нормальный индикатор скрола, у вас нет расчета высоты всех ячеек, из-за этого, если его включить, он будет немного «дрыгаться», т.к. tableView не знает полную высоту.