I think each person has their own way of writing code that is easy to understand. If you write it differently every time, it will not be easy to maintain, so I want to standardize the view controller code in my own way.
ViewController.swift
import UIKit
class ViewController: UIViewController {
//Here, the UI is integrated.
override func viewDidLoad() {
super.viewDidLoad()
//Called only once after view is loaded into memory
//Since it is called only once in the display cycle, it is suitable for initializing objects used in the class.
//Additional initialization processing for view
//Network communication
//Processing to be performed only once
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
//Called just before the view is displayed (in addition to the initial display, background return, tab switching, etc.)
//The process of hiding or deactivating the UI
//Update view according to the state of the app
//Since the view has not been finalized yet, avoid processing with high calculation cost.
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
//Called just before the superView bounds change (device orientation changes, etc.)
//safe Area is the timing when viewWillLayoutSubviews can be taken earliest
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
//Called when the layout of the subView is completed (view bounds are confirmed)
//Processing using the size of view
//Execution of view placement method
setupViews()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
//Called immediately after view is displayed on the screen(Called multiple times, such as when returning to the background or switching tabs)
//Since the UI display is complete, it is suitable for executing processing that is not related to the UI display (such as sending logs).
//Writing data to Core Data
//Play animations and videos
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
//Called just before the view is removed(Modal,Push transition)
//Saving changes in ViewController, etc.
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
//Called immediately after the view is removed(Modal,Push transition)
//Cancellation of notifications, etc.(Automatic cancellation after iOS 9)
}
func setupViews(){
//view placement method (executed by viewDidLayoutSubviews)
//Obtaining a safe area
let safeArea = view.safeAreaInsets
//Here, the size and position of the UI are set.
}
}
// MARK: -delegate method
extension ViewController : UITextFieldDelegate{
//Set by separating each delegate with extension
}
Understand UIKit's View display lifecycle https://qiita.com/shtnkgm/items/f133f73baaa71172efb2
ViewController life cycle https://medium.com/@shiba1014/view controller life cycle-37151427bda5
【swift】viewDidLayoutSubviews、layoutSubviews https://scleapt.com/swift_viewdidlayoutsubviews/
If you have any questions about the content of this article, please contact us.
In the case of a personally developed amateur like me, I have no choice but to code so that it works while referring to books and the Internet. After all, even if the same thing is explained depending on the books and articles that I refer to, the way of thinking of the code is different, and I feel that it is one of the reasons why the programming threshold is high that it causes confusion. I wondered if the foundation was important to minimize the confusion.
Advice is welcome
ViewController.swift
import UIKit
class LineViewController: UIViewController {
let lineNoLabel = UILabel()
let lineNoTF = UITextField()
let doneButton = UIButton()
//Called only once after view is loaded into memory
override func viewDidLoad() {
super.viewDidLoad()
//Use: Suitable for initializing objects used in the class because it is called only once in the view controller display cycle.
//-Additional initialization processing for view
//・ Network communication
//・ Processing performed only once
//lineNoLabel settings
lineNoLabel.text = "Line No"
view.addSubview(lineNoLabel)
//lineNoTF setting
lineNoTF.delegate = self
lineNoTF.borderStyle = .roundedRect
view.addSubview(lineNoTF)
//setting of doneButton
doneButton.backgroundColor = .magenta
doneButton.setTitle("Done", for: .normal)
doneButton.addTarget(self, action: #selector(doneTaped), for: .touchUpInside)
view.addSubview(doneButton)
}
//Called just before the view is displayed (in addition to the initial display, background return, tab switching, etc.)
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
//The process of hiding or deactivating the UI
//Update view according to the state of the app
//Since the view has not been finalized yet, avoid processing with high calculation cost.
}
//Called just before the superView bounds change (device orientation changes, etc.)
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
//safe Area is the timing when viewWillLayoutSubviews can be taken earliest
print("SafeArea=",view.safeAreaInsets)
}
//Called when the layout of the subView is completed (view bounds are confirmed)
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
//Processing using the size of view
//Execution of view placement method
setupViews()
}
//Called immediately after view is displayed on the screen(Called multiple times, such as when returning to the background or switching tabs)
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
print("viewDidAppear")
//Since the UI display is complete, it is suitable for executing processing that is not related to the UI display (such as sending logs).
//Writing data to Core Data
//Play animations and videos
}
//Called just before the view is removed(Modal,Push transition)
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
//Saving changes in ViewController, etc.
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
//Cancellation of notifications, etc.(Automatic cancellation after iOS 9)
}
func setupViews(){
//Obtaining a safe area
let safeArea = view.safeAreaInsets
//Size of UI part placement area
let partsArea_W = view.frame.width - safeArea.left - safeArea.right
let partsArea_H = view.frame.height - safeArea.top - safeArea.bottom
//Spacing between UI parts
let margin_X = round(partsArea_W * 0.05)
let margin_Y = round(partsArea_H * 0.05)
//Height width of parts used in common, etc.
let partsHeight = round(partsArea_H * 0.05)
let partsWidth = partsArea_W - margin_X * 2
let buttonHeight = round(partsArea_H * 0.05)
//LineNoLabel size and position settings
let lineNoLabel_W = partsWidth
let lineNoLabel_H = partsHeight
let lineNoLabel_X = safeArea.left + margin_X
let lineNoLabel_Y = safeArea.top + margin_Y
lineNoLabel.frame.size = CGSize(width: lineNoLabel_W, height: lineNoLabel_H)
lineNoLabel.frame.origin = CGPoint(x: lineNoLabel_X, y: lineNoLabel_Y)
//lineNoTF size and position settings
let lineNoTF_W = partsArea_W - margin_X * 2
let lineNoTF_H = partsHeight
let lineNoTF_X = safeArea.left + margin_X
let lineNoTF_Y = lineNoLabel.frame.maxY
lineNoTF.frame.size = CGSize(width: lineNoTF_W, height: lineNoTF_H)
lineNoTF.frame.origin = CGPoint(x: lineNoTF_X, y: lineNoTF_Y)
let doneButton_W = partsArea_W - margin_X * 2
let doneButton_H = buttonHeight
let doneButton_X = safeArea.left + margin_X
let doneButton_Y = view.bounds.height - safeArea.bottom - doneButton_H - margin_Y
doneButton.layer.cornerRadius = doneButton_H / 2
doneButton.frame.size = CGSize(width: doneButton_W, height: doneButton_H)
doneButton.frame.origin = CGPoint(x: doneButton_X, y: doneButton_Y)
}
//Method called when doneButton is pressed
@objc func doneTaped(){
print("done")
//Screen transition
performSegue(withIdentifier: "goInput", sender: nil)
}
}
// MARK: - UITextFieldDelegate
extension LineViewController : UITextFieldDelegate{
//Called when Return is pressed in the textField
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
//Close keyboard
textField.resignFirstResponder()
}
//Called when the textField has been edited
func textFieldDidEndEditing(_ textField: UITextField) {
guard let text = textField.text else { return }
print(text)
}
}