I want to create a chat screen for the Swift chat app!

What you need for the chat screen of the chat app

It's hard to find a job in the corona, so I'd like to write an article about how to make a chat screen for a chat app. What do you think is the minimum required for a chat screen? This time, I will implement it with the minimum necessary items for the chat screen that I think. The required components are as follows

tableView: Used to list messages. MessageCell: Collects profiles and messages. profileImageView: Shows the profile image. messageLabel: Display the message.

What else is the label for displaying the transmission time? You might think that, but this time I will only do this because I do not actually send and receive messages using a database or the like.


First from the view controller

class ViewController: UIViewController {

    private let tableView = UITableView()
    //Array for storing messages
    private var messages = [String]()
    override func viewDidLoad() {

    //tableView settings
    private func initTableView() {
        tableView.tableFooterView = UIView()
        tableView.separatorStyle = .none
        tableView.register(MessageCell.self, forCellReuseIdentifier: MessageCell.id)
        tableView.delegate = self
        tableView.dataSource = self
        tableView.frame = view.bounds
    //Add message to messages
    private func initMessages() {
        messages.append("Do you have a schedule around 12 o'clock today?")
        messages.append("It's free")
        messages.append("Jugemu(Jugemu) Jugemu(Jugemu)Five Kalpa(Let's go)Cream Stew Sea gravel(Kaijari)Water fish(Suigyo)Water line end(Suigyoうまつ)The end of the cloud(Unramatsu)The end of the wind(Furamatsu)Food(Ku)Napping(Hey)Live in a place(Su)Mudokoro Yaburakoji's Burakoji Paipo Paipo Paipo's Shuringan Shulingan's Gourindai Gourindai's Pompo Copy Pompokona's longevity(Chokyumei)Chosuke(ちょうSuけ)")


extension ViewController: UITableViewDelegate, UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return messages.count
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: MessageCell.id, for: indexPath) as! MessageCell
        cell.message = messages[indexPath.row]
        return cell

Let's take a look inside initTableView (). This is because tableFooterView = UIView () erases empty cells that are displayed when there are more than the number of elements. separatorStyle = .none removes the light gray border between cells. register is for displaying custom cells. See here. When I used a custom cell in my code, I missed the register (_: forCellReuseIdentifier :) function That's about all the explanation inside the view controller.

Next, we will create a custom cell.


class MessageCell: UITableViewCell {
    static let id = "MessageCell"
    public var message: String? {
        didSet {
            messageLabel.text = message
    private let profileImageView: UIImageView = {
        let imageView = UIImageView()
        imageView.image = #imageLiteral(resourceName: "image.jpeg ")
        imageView.layer.masksToBounds = true
        imageView.layer.cornerRadius = 25
        return imageView
    private let backView: UIView = {
        let view = UIView()
        view.backgroundColor = .opaqueSeparator
        view.layer.cornerRadius = 20
        view.layer.masksToBounds = true
        return view
    private let messageLabel: UILabel = {
        let label = UILabel()
        label.font = .systemFont(ofSize: 16)
        //Specify the number of label lines
        label.numberOfLines = 0
        return label

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
    private func setupAutoLayout() {
        profileImageView.translatesAutoresizingMaskIntoConstraints = false
        backView.translatesAutoresizingMaskIntoConstraints = false
        messageLabel.translatesAutoresizingMaskIntoConstraints = false
        let constraints = [
            profileImageView.topAnchor.constraint(equalTo: topAnchor, constant: 10),
            profileImageView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 10),
//            profileImageView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -10),
            profileImageView.widthAnchor.constraint(equalToConstant: 50),
            profileImageView.heightAnchor.constraint(equalToConstant: 50),
            backView.topAnchor.constraint(equalTo: profileImageView.topAnchor),
            backView.leadingAnchor.constraint(equalTo: profileImageView.trailingAnchor, constant: 5),
            backView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -10),
            backView.widthAnchor.constraint(lessThanOrEqualToConstant: 250),
            messageLabel.topAnchor.constraint(equalTo: backView.topAnchor, constant: 8),
            messageLabel.leadingAnchor.constraint(equalTo: backView.leadingAnchor, constant: 8),
            messageLabel.bottomAnchor.constraint(equalTo: backView.bottomAnchor, constant: -8),
            messageLabel.trailingAnchor.constraint(equalTo: backView.trailingAnchor, constant: -8),
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")

It declares profileImageView, backView, and messageLabel. It would be nice to put it together in a closure. backView is used to create a nice margin because if you specify the background color directly in messageLabel, there will be no margin between the background and the characters and it will be difficult to see. Let's take a look inside setupAutoLayout. Each view has a description of translatesAutoresizingMaskIntoConstraints = false. If you don't do this, you may not be able to use autolayout. Use Auto Layout from code From constraints, the layout is set with autoLayout. Since it is organized as an array, it can be activated collectively with NSLayoutConstraint.activate (). If you want to change only a part

[variable name of view].topAnchor.constraint(equalTo: topAnchor).isActive = true

You can do it with.

Let's build it. Simulator Screen Shot - iPhone 11 - 2021-01-17 at 22.33.44.png You can display it nicely.


This time it was only the other party, but if you change the restrictions, you can also make your own. Please let me know if there is an easier way. If you find it bothersome to implement it yourself, check out MessageKit.

As I said at the beginning, I am looking for a job. Ah, please give me a job for a kind company!

Recommended Posts

I want to create a chat screen for the Swift chat app!
I want to create a generic annotation for a type
I want to create a form to select the [Rails] category
[Swift5] How to create a splash screen
Implemented a strong API for "I want to display ~~ on the screen" with simple CQRS
I tried to create a LINE clone app
[Android] I want to create a ViewPager that can be used for tutorials
I want to play a GIF image on the Andorid app (Java, Kotlin)
I want to know the answer of the rock-paper-scissors app
I made a chat app.
I want to dark mode with the SWT app
[Azure] I tried to create a Java application for free-Web App creation- [Beginner]
I want to add a delete function to the comment function
I tried to introduce Bootstrap 4 to the Rails 6 app [for beginners]
How to transition from the [Swift5] app to the iPhone settings screen
[Rails] I tried to create a mini app with FullCalendar
I want to use screen sharing on the login screen on Ubuntu 18
I want to call a method and count the number
I want to give a class name to the select attribute
I want to create a Parquet file even in Ruby
I want to transition to the same screen in the saved state
I want to return multiple return values for the input argument
Swift: I want to chain arrays
Try to create a server-client app
Create an Android app for those who don't want to play music on the speaker
I want to recursively search for files under a specific directory
I want to use swipeback on a screen that uses XLPagerTabStrip
I want to return to the previous screen with kotlin and java!
The story of Collectors.groupingBy that I want to keep for posterity
[Swift 5] Processing and precautions for transitioning to the iOS settings app
I want to remove the top margin in Grouped UITableView (swift)
I want to develop a web application!
I want to write a nice build.gradle
I want to make an ios.android app
I want to write a unit test!
How to create a Maven repository for 2020
I want to display the number of orders for today using datetime.
Glassfish tuning list that I want to keep for the time being
[Active Admin] I want to customize the default create and update processing
I want to create a dark web SNS with Jakarta EE 8 with Java 11
I thought about the best way to create a ValueObject in Ruby
I want you to use Enum # name () for the Key of SharedPreference
[For beginners] I want to automatically enter pre-registered data in the input form with a selection command.
How to create a database for H2 Database anywhere
I want to output the day of the week
[Swift] I want to draw grid lines (squares)
[Ruby] I want to do a method jump!
How to create pagination for a "kaminari" array
How to add sound in the app (swift)
I want to var_dump the contents of the intent
[Swift] How to link the app with Firebase
I want to simply write a repeating string
I want to design a structured exception handling
I want to truncate after the decimal point
I want to get the value in Ruby
I want you to use Scala as Better Java for the time being
I want to create the strongest local development environment using VSCode Remote Containers
I want to recursively get the superclass and interface of a certain class
When I wanted to create a method for Premium Friday, it was already in the Java 8 standard API
Rspec: I want to test the post-execution state when I set a method on subject
[Ruby] I want to make a program that displays today's day of the week!