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.
-
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.
-
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.