UIView 컴포넌트 중 UITableView, UICollectionView
UITableView : 데이터 목록을 표시하고 사용자와 상호작용할 수 있는 스크롤 가능한 요소 
import UIKit
  
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {  
      
    let tableView = UITableView()  
    let data = ["Item 1", "Item 2", "Item 3"]  
      
    override func viewDidLoad() {  
        super.viewDidLoad()  
          
        tableView.frame = view.bounds  
        tableView.dataSource = self  
        tableView.delegate = self  
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")  
        view.addSubview(tableView)  
    }  
      
    
		
		
		
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {  
        return data.count  
    }  
    
		
		
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {  
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)  
        cell.textLabel?.text = data[indexPath.row]  
        return cell  
    }  
      
    
		
		
		
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {  
        print("Selected: \(data[indexPath.row])")  
        tableView.deselectRow(at: indexPath, animated: true)  
    }  
}
UICollectionView : 유연한 그리드 에이아웃을 사용하여 아이템 목록을 표시하고 사용자와 상호작용할 수 있는 스크롤할 수 있는 UI 요소 
func setUICollectionView() {
    let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewLayout())
    collectionView.delegate = self
    collectionView.dataSource = self
    collectionView.frame = self.view.bounds
    collectionView.backgroundColor = .white
    collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "Cell")
    
    self.view?.addSubview(collectionView)
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return datas.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath)
    cell.backgroundColor = .blue
    return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    print("Selected: \(datas[indexPath.row])")
    collectionView.deselectItem(at: indexPath, animated: true)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    return CGSize(width: 100, height: 100)
}
AutoLayout ?
- 다양한 디바이스 및 화면 방향에 따라 유연하게 요소들의 위치를 지정할 수 있는 기능
 
제약조건(Constraints)
- 뷰와 뷰 사이의 관계, 뷰의 상대적인 위치를 설정
 
- 제약조건 예제코드
 
NSLayoutConstraint.activate([
		
		textLabel.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 0),
		
		textLabel.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: 0),
		
		textLabel.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 0),
		
		textLabel.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: 0),
])
NSLayoutConstraint.activate([
		
		self.textLabel.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
		
		self.textLabel.centerYAnchor.constraint(equalTo: self.view.centerYAnchor),
])
오토레이아웃 엔진(AutoLayout Engine)
- 제약조건을 기반으로 뷰의 최종위치와 크기를 계산
 
Size Classes
- 화면 크기와 방향에 따른 뷰의 레이아웃을 관리하는 기능
 
- Compact, Regular 두 가지 사이즈 클래스가 있으며, 조합을 통해 다양한 조건에 대응할 수 있는 레이아웃 구성 가능
 
Interface Builder(Storyboard)
- AutoLayout을 사용하여 UI를 시각적으로 디자인할 수 있는 툴
 
- 제약 조건을 추가, 수정, 삭제하는 것이 가능하며, 뷰의 레이아웃을 실시간으로 확인 가능
 
LifeCycle ?
1. App Life Cycle

Not Running : 실행되지 않거나 종료된 상태 
InActive : 앱이 Foreground 상태로 돌아가지만, 이벤트는 받지않고 잠시 존재하는 상태(아래에서 위로 스와이프 하는 순간에 InActive 상태로 돌입) 
Active : 일반적으로 앱이 돌아가는 상태(이벤트를 받는 단계) 
Background : 앱이 Suspended 상태로 진입하기 전에 거치는 상태 
Suspended : 앱이 Background 상태에 있지만, 아무 코드도 실행하지 않는 상태(리로스가 해제됨, Not Running 일반적으로 동일) 
2. UIViewController Life Cycle

init : UIViewController 객체가 생성 
loadView() : 컨트롤러의 뷰 계층 구조가 생성 
viewDidLoad() : 뷰 계층 구조가 메모리에 로드되었으며, 초기화 작업을 수행 
viewWillAppear() : 뷰가 화면에 나타나기 직전에 호출, 뷰를 업데이트하거나 애니메이션을 시작 
viewDidAppear() : 뷰가 화면에 나타나면 호출, 애니메이션을 종료하거나 뷰의 상태를 업데이트 
viewWillDisappear() : 뷰가 화면에서 사라지기 전에 호출, 데이터를 저장하거나 애니메이션을 시작 
viewDidDisappear() : 뷰가 화면에서 사라지면 호출, 애니메이션을 종료하거나 뷰의 상태를 업데이트 
deinit : UIViewController 객체가 메모리에서 해제됨 
UIViewController 생명주기 메소드 예제코드
class MyViewController: UIViewController {
    
    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
        
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        
    }
    
    override func loadView() {
        
        self.view = UIView()
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
    }
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        
    }
    
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        
    }
    
    deinit {
        
    }
    
}