1
\$\begingroup\$

I am building this pet project with UIKit. The App's main goal is to keep track of my daily expenses.

The AddExpenseViewController is responsible for capturing user input, parse it into a Expense instance, and send it back to the UIViewController containing all my expenses using the delegate pattern.

To capture user input I am using a UITableView with two custom cells containing UITextFields: ExpenseTitleTableViewCell and ExpenseValueTableViewCell. As this is supposed to work as a form, it's not possible to add new cells (i.e fields) to the UITableView.

Currently, I instantiate the cells in the tableView(_ tableView:, cellForRowAt:) -> UITableViewCell method using helper functions, like so:

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 2
}
   
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    switch indexPath.row {
    case 0: return configureTitleCell()
    case 1: return configureValueCell()
    default: return UITableViewCell()
}

func configureTitleCell() -> UITableViewCell {
    let cell = ExpenseTitleTableViewCell(style: .value1, reuseIdentifier: ExpenseTitleTableViewCell.reuseIdentifier)
    cell.configureCell()
    return cell
}

func configureValueCell() -> UITableViewCell {
    let cell = ExpenseValueTableViewCell(style: .value1, reuseIdentifier: ExpenseValueTableViewCell.reuseIdentifier)
    cell.configureCell()
    return cell
}

A few things look off to me:

  • First: the view controller is responsible for instantiating the cells, and this generates duplicate code on configureTitleCell and configureValueCell. Should I use a pattern like Factory to split responsibilities?

  • Second: having the constant 2 in numberOfRowsInSection also looks unsafe to me

\$\endgroup\$
2
  • \$\begingroup\$ Avoid repetition by using polymorphism \$\endgroup\$
    – ielyamani
    Mar 30 at 19:35
  • \$\begingroup\$ The problem is not that you have a constant number of rows in a table view. We do that all the time. But we do it because we want other table behaviors (e.g. scrolling, consistent look and view for a whole bunch of entries, etc.). But this does not seem remotely like a reasonable table view use-case. Maybe you can explain why you wanted to use a table view… \$\endgroup\$
    – Rob
    Nov 15 at 2:05

1 Answer 1

0
\$\begingroup\$

Using a table view for this sort of thing is inappropriate IMO. A UITableView is designed for displaying an array of items, not bits and pieces of a single item. That's why having the constant in numberOfRowsInSection looks wrong.

Instead, you should have an ExpenseTitleView and ExpenseValueView that are both derived from UIView. Whatever is going on in the respective configure() methods can be put in the init of those two views.

If you are using Interface Builder to create the UI, you can just put instances of the two views directly in the xib or storyboard file. If you are building your UI programmatically, then override the loadView method of your view controller and call view.addSubview() passing an instance of each subview.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.