[SWIFT] UIViewController code standardization

Introduction

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
}

I was allowed to reference

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.

Finally (dumb)

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

All chords

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)
    
  }
}


Recommended Posts

UIViewController code standardization
Testable code