Здравствуйте, хабражители!
В этой статье я хотел бы поделиться своим опытом создания простого экрана чата, с использованием хвостатых пузырьков.
В одном из моих последних проектов я столкнулся с задачей создания очень специфических ячеек для чата. К сожалению, все готовые решения, которые я находил в свободном доступе, сводились либо к простому отображению текста в ячейках, либо к отображению текста и картинок. А те проекты, которые предлагали кастомизацию ячеек, представляли из себя настолько огромные комбайны, что тратить время и разбираться в них просто небыли ни какого желания, при том, что результат в итоге мог не покрыть мои нужды.
Т.к. на тот момент я не представлял каким образом создаются хвостатые пузырьки, а мне нужны были именно такие, я решил поискать какие-то простые проекты, которые показывали бы каким образом можно создать такую ячейку. К сожалению и этот путь привел меня в никуда, таких проектов я просто не нашел. Поэтому я решил, что придется разобраться в этой задаче с нуля и заодно выложить проект, который облегчит понимание этого вопроса другим людям.
Итак, я пролистал несколько статей на разных сайтах по данной тематике, решений на самом деле оказалось много, но мне показалось наиболее правильным использование растягиваемых изображений. В данном методе используется функция 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
Всем спасибо за внимание, на все вопросы постараюсь ответить в комментариях или ЛС.
cher11
alexbarinov.github.io/UIBubbleTableView
Умеет несколько больше, чем ваш пример. Ну и сорцы подсмотреть тоже можно. Поставил бы плюс за готовое решение с поддержкой текста, фото, видео, ссылок, а в вашей статье по факту 4 строчки кода о том, как картинку растянуть. Не серьезно.
www.cocoacontrols.com/controls/sphchatbubble
туда же
iBlacksus
Данная статья и проект не про разухабистое решение с поддержкой «фото, видео, ссылок». Как и написано в названии, я сделал максимально простой проект, который за минимальное время дает концептуальное понятие того, как строятся ячейки чата. Это такой трамплин, который просто направляет в правильную сторону, и не является каким-то готовым решением по своей сути.
Естественно это статья не для профессионалов, у которых за плечами десятки лет разработки под iOS. Но для людей, которые столкнутся с такой же проблемой как и я. Да, может не серьезно, но написано это все не ради плюсов, просто лично мне подобная статья ранее сэкономила бы много времени.
cher11
Посмотрел сам проект, написано очень чисто, спору нет. Основная моя претензия не в том, что Вам надо было сделать «комбайн», а в том, что вы слишком поверхностно описали свое решение. Ну и заявили, что таких проектов нет — а они есть :)
Вам можно было осветить, например, такие вещи, как правильное размещение текста внутри облачка, способ задания ограничения ячейки по ширине и так далее, это тоже вещи, с первого раза не очень понятные. Ну или еще интересная проблема — сделать нормальный индикатор скрола, у вас нет расчета высоты всех ячеек, из-за этого, если его включить, он будет немного «дрыгаться», т.к. tableView не знает полную высоту.