Search code examples
iosswiftuitableviewarchitecturereusability

Reuse layout code for a UITableViewCell of similar layout


I'm trying to replicate the built-in Apple Reminders app. In it, there are two types of cells: one for displaying a reminder item, and one for adding a new item: Reminders table view cells I don't use Interface Builder, so all the layout code is contained in a UITableViewCell subclass. Here, I created one for the reminder item cell:

class ItemCell: UITableViewCell {
    var leftButton: UIButton!
    var middleLabel: UILabel!

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)

        middleLabel = UILabel()
        middleLabel.translatesAutoresizingMaskIntoConstraints = false

        leftButton = UIButton(type: .custom)
        leftButton.translatesAutoresizingMaskIntoConstraints = false
        leftButton.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)

        contentView.addSubview(middleLabel)
        contentView.addSubview(leftButton)

        NSLayoutConstraint.activate([
            leftButton.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 8.0),
            leftButton.centerYAnchor.constraint(equalTo: contentView.centerYAnchor),
            middleLabel.leadingAnchor.constraint(equalTo: leftButton.trailingAnchor, constant: 8.0),
            middleLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: 8.0),
            middleLabel.centerYAnchor.constraint(equalTo: leftButton.centerYAnchor)
        ])
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

Now if I were to create another UITableViewCell subclass for the add item cell, a lot of its layout code would be the same, except that the subviews would be of different type. The easiest solution of just copying & pasting the code fragments has its obvious flaws of not being clean, reusable, and elegant.

I can assume that better solutions would be something like using inheritance, or factory classes, or protocols, but struggle to find the best practice for this specific task.


Solution

  • Make a function that just takes the UIViews as parameters and creates the layout.

    Then make a base class that derives from table cell and move that function there.

    Finally change this class to derive from the new base class

    Now your new cell can also derive from that class as well.