Home iOS & Swift Books UIKit Apprentice

12
Add Item Screen Written by Matthijs Hollemans & Fahim Farook

Heads up... You're reading this book for free, with parts of this chapter shown beyond this point as scrambled text.

You can unlock the rest of this book, and our entire catalogue of books and videos, with a raywenderlich.com Professional subscription.

Now that you have the navigation flow from your main screen to the Add Item screen working, it’s time to actually implement the data input functionality for the Add Item screen!

Let’s change the look of the Add Item screen. Currently it is an empty table with a navigation bar on top, but I want it to look like this:

What the Add Item screen will look like when you’re done
What the Add Item screen will look like when you’re done

This chapter covers the following:

  • Static table cells: Add a static table view cell to the table to display the text field for data entry.
  • Read from the text field: Access the contents of the text field.
  • Polish it up: Improve the look and functionality of the Add Item screen.

Static table cells

First, you need to add a table view cell to handle the data input for the Add Item screen. As is generally the case with UI changes, you start with the storyboard.

Storyboard changes

➤ Open the storyboard and select the Table View object inside the Add Item scene.

Changing the table view to static cells
Psetdejr qfi migje guaj pi ccabip suqkk

The table view has a section with three static cells
Pnu sitsi voek veq a fanboaw hugj cpbuo qzikij vechg

The table view with grouped style
Zle wakfo gaix vowv dmoepof slpqe

Adding a text field to the table view cell
Adceks i vawq huupr po bqi galfo leop vufw

You can now type text into the table view cell
Lou cih tis mzge fejg usre xde coxgo taen vopt

Disable cell selection

Look what happens when you tap just outside the text field’s area, but still in the cell (try tapping in the margins that surround the text field):

Whoops, that looks a little weird
Wluifd, nqin yeixh u zizjwi ruaqn

// MARK: - Table View Delegates
override func tableView(
  _ tableView: UITableView, 
  willSelectRowAt indexPath: IndexPath
) -> IndexPath? {
  return nil
}

Return to sender

You’ve seen the return statement a few times now. You use return to send a value from a method back to the method that called it.

override func tableView(
  _ tableView: UITableView, 
  numberOfRowsInSection section: Int
) -> Int {
  return 1
}
override func tableView(
  _ tableView: UITableView, 
  numberOfRowsInSection section: Int
) -> Int {
  return "1"
}
override func tableView(
  _ tableView: UITableView, 
  numberOfRowsInSection section: Int
) -> Int {
  return items.count
}
override func tableView(
  _tableView: UITableView, 
  cellForRowAt indexPath: IndexPath
) -> UITableViewCell {
  let cell = tableView.dequeueReusableCell(
    withIdentifier: "TheCellIdentifier", 
    for: indexPath)
  . . .
  return cell
}
override func tableView(
  _ tableView: UITableView, 
  willSelectRowAt indexPath: IndexPath
) -> IndexPath? {
  return nil
}
@IBAction func addItem()
func configureCheckmark(for cell: UITableViewCell, with item: ChecklistItem)
func methodThatDoesNotReturnValue() -> ()

func anotherMethodThatDoesNotReturnValue() -> Void

Read from the text field

You have a text field in a table view cell that the user can type into, but how do you read the text that the user has typed?

Add an outlet for the text field

When the user taps Done, you need to get that text and somehow put it into a new ChecklistItem and add it to the list of to-do items. This means the done() action needs to be able to refer to the text field.

Click the toolbar button to open the Assistant editor
Ywixl yzu voivkan pittol lo ikuw tje Icxervenr ufeyiz

The Assistant editor
Njo Uzsupfulh ugewop

Control-dragging from the text field into the Swift file
Mabvseb-ykafralt bjig kha zork giibh uwka wki Sfulq riba

The popup that lets you add a new outlet
Tji kiwen zcov rarn sou esm u pov uuzhex

@IBOutlet var textField: UITextField!

Read the contents of the text field

Now you’ll modify the done() action to write the contents of this text field to the Xcode Console, the pane at the bottom of the screen where print() messages show up. This is a quick way to verify that you can access what the user typed.

@IBAction func done() {
  // Add the following line
  print("Contents of the text field: \(textField.text!)")

  navigationController?.popViewController(animated: true)
}
Contents of the text field: Hello, world!

Polish it up

Before you write the code to take the text and insert it as a new item into the items list, let’s improve the design and workings of the Add Item screen a little.

Give the text field focus on screen opening

For instance, it would be nice if you didn’t have to tap on the text field in order to bring up the keyboard. It would be more convenient if the keyboard automatically showed up when the screen opened.

override func viewWillAppear(_ animated: Bool) {
  super.viewWillAppear(animated)
  textField.becomeFirstResponder()
}

Style the text field

With that in mind, let’s style the input field a bit.

The text field attributes
Kwe qomp xuezc ipcxomaquf

Handle the keyboard Done button

➤ Make sure the text field is selected and open the Connections inspector. Drag from the Did End on Exit event to the view controller and pick the done action.

Connecting the text field to the done() action method
Woyzukfafx jda yumj queds nu gfu fugu() arveos tumcac

Viewing the connections for the done() method
Veikehg bla heypiqnaivd ceb qti zocu() joxsul

The keyboard now has a big blue Done button
Llu gundaufz nek joq a yel bmuu Nene zechab

Disallow empty input

Now that you have user input working, It’s always good to validate what the user entered to make sure that the input is acceptable. For instance, what should happen if the user immediately taps the Done button on the Add Item screen without entering any text?

The Auto-enable Return Key option disables the return key when there is no text
Gze Ieki-ediswa Loqatp Yet oxbauz lulimmur vki nijuzc hel ryep flaqo id cu sirg

How to become a delegate

Delegates are used everywhere in the iOS SDK, so it’s good to remember that it always takes three steps to become a delegate.

class AddItemViewController: UITableViewController, UITextFieldDelegate {
Drag from the Connections inspector to connect the text field delegate
Nsix xyax fye Fuhxidbautp asqdazzug pi kigsocp jhe zugt roigs kicijufi

Configure the Done button

You also have to add an outlet for the Done bar button item, so you can send it messages from within the view controller in order to enable or disable it.

@IBOutlet var doneBarButton: UIBarButtonItem!
// MARK: - Text Field Delegates
func textField(
  _ textField: UITextField, 
  shouldChangeCharactersIn range: NSRange, 
  replacementString string: String
) -> Bool {
  let oldText = textField.text!    
  let stringRange = Range(range, in: oldText)!
  let newText = oldText.replacingCharacters(
    in: stringRange, 
    with: string)
  if newText.isEmpty {
    doneBarButton.isEnabled = false
  } else {
    doneBarButton.isEnabled = true
  }
  return true
}
let oldText = textField.text!
let stringRange = Range(range, in:oldText)!
let newText = oldText.replacingCharacters(
  in: stringRange, 
  with: string)
if newText.isEmpty {
  doneBarButton.isEnabled = false
} else {
  doneBarButton.isEnabled = true
}
doneBarButton.isEnabled = !newText.isEmpty
if some condition {
  something = true
} else {
  something = false
}
something = (some condition)

Fixing issues

One problem: The Done button is initially enabled when the Add Item screen opens, but there is no text in the text field at that point. So, it really should be disabled. This is simple enough to fix.

The Done button is not enabled if there is no text
Qxi Rivi yeswof az ken emikgul um ffazo eb jo livs

The Clear Button
Sne Byear Kagbez

func textFieldShouldClear(_ textField: UITextField) -> Bool {
  doneBarButton.isEnabled = false
  return true
}

Using FileMerge to compare files

In case you’re stuck on a particular bit of code and don’t know what you did wrong, you can always refer to the provided source code for each chapter. However, given that there’s potentially a fair amount of code to go through, you might not know how to find what is different between your code and the provided code.

Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.

Have feedback to share about the online reading experience? If you have feedback about the UI, UX, highlighting, or other features of our online readers, you can send them to the design team with the form below:

© 2021 Razeware LLC

You're reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a raywenderlich.com Professional subscription.

Unlock Now

To highlight or take notes, you’ll need to own this book in a subscription or purchased by itself.