Ch 14: Silver Challenge

In Main.storyboard set each UITextField’s custom class to CustomTextField

CustomTextFIeld.swift

import UIKit

class CustomTextField: UITextField {
    override func becomeFirstResponder() -> Bool {
        super.becomeFirstResponder()
        layer.borderColor = UIColor.green.cgColor
        layer.borderWidth = 1.0
        layer.cornerRadius = 5.0
        return true
    }
    
    override func resignFirstResponder() -> Bool {
        super.resignFirstResponder()
        layer.borderWidth = 0.0
        return true
    }
}

Step 1

Create the file CustomUITextField.swift

import UIKit

class CustomUITextField: UITextField {
    override func becomeFirstResponder() -> Bool {
        borderStyle = .bezel
        super.becomeFirstResponder()
        return true
    }
    
    override func resignFirstResponder() -> Bool {
        borderStyle = .roundedRect
        super.resignFirstResponder()
        return true
    }
}

Step 2

Set each UITextField’s Custom Class in Main.storyboard as CustomUITextField

Step 3

In DetailViewController.swift, change the types of nameField, serialNumberFiled, valueFiled into CustomUITextField

@IBOutlet weak var nameField: CustomUITextField!
@IBOutlet weak var serialNumberField: CustomUITextField!
@IBOutlet weak var valueField: CustomUITextField!

There’re some issues with your solutions, Joshua.

  1. You must not return true in your methods because calling them is not a guarantee that the object will become / resign the first responder. UIKit asks the current first responder to resign as first responder, which it might not. Therefore you need to check isFirstResponder property.

  2. As the book hints you can just change the borderStyle property which is neat solution.

    override func becomeFirstResponder() -> Bool {

     super.becomeFirstResponder()
     self.borderStyle = .bezel
     return isFirstResponder
    

    }

    override func resignFirstResponder() -> Bool {

     super.resignFirstResponder()
     borderStyle = .roundedRect     // The default style
     return !isFirstResponder
    

    }

In the solution by cyumeng step # 3 is useless as the DetailViewController is not responsible for changing the border style. It’s the view who does.