공식문서

A view that presents data using rows in a single column.

⇒ 단일 열에 배열된 행을 표시하는 뷰

  • 단일 열에 수직 스크롤을 제공하는 콘텐츠 행을 표시
  • 예를 들어 연락처 앱과 설정 앱이 있음
  • 연락처 앱은 일반적인 TableView 를 표시하며, 설정 앱은 Group화 된 TableView를 표시
  • 여러개의 행은 하나의 섹션으로 포함할수 있으며, 섹션은 헤더 와 푸터로 구성

 

구현해보기

1. Storyboard 에서 TableView와 TableViewCell 을 ViewController에 끌어다 놓자

 

2. 이렇게 끌어다 놓아 ViewController에 포함시키고 Cell에 대한 고유 값을 설정해 준다

 

3. cell을 선택한 상태로 오른쪽의 인스펙터 창에서 identifier에 구분할수 있는 이름으로 셀이름을 설정한다

( 예시에서는 "myCell" )

 

4. 해당 viewController 코드 파일에 TableView를 연결한다 ( IBOutlet )

[ storyboard 파일에서 control 을 누르고 코드쪽으로 끌어 당기면 연결된다 ]

 

5. datasource 프로토콜을 채택하고 내용을 구현해 준다

//
//  ViewController.swift
//  tableViewPrac
//
//  Created by Hong jeongmin on 2022/05/19.
//

import UIKit

struct myTableCell {
    var name: String
}

var nameArr = [
    myTableCell(name: "홍길동"),
    myTableCell(name: "이선비"),
    myTableCell(name: "개똥이"),
    myTableCell(name: "새이름"),
    myTableCell(name: "김하나"),
]

class ViewController: UIViewController {
    @IBOutlet weak var myTable: UITableView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        // 위임
        myTable.dataSource = self
    }
}

// DataSource => 각 테이블 행의 어떤 내용을 표시할지
extension ViewController: UITableViewDataSource {
    // 몇개의 행을 리턴할지
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return nameArr.count
    }
    
    // 각 행에는 어떤 내용을 포함 할지
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard let cell = tableView.dequeueReusableCell(withIdentifier: "mycell") else {
            fatalError("셀이 존재하지 않습니다.")
        }
        
        cell.textLabel?.text = nameArr[indexPath.row].name
        return cell
    }
    
    // 헤더의 이름 표시
    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return "헤더입니다"
    }
    
    // 푸터의 이름 표시
    func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? {
        return "푸터입니다"
    }
    
    // 몇개의 섹션을 구성할 것인지 표시
    func numberOfSections(in tableView: UITableView) -> Int {
        return 2
    }
}

6. 결과확인

 

datasource 를 반드시 설정해 주어야 해당 내용이 나타나니 코드를 잘 살펴보자~!

 

테이블뷰 기초 끝!

TableView를 기준으로 설명 , (아마도) 동일한 프로토콜이 있다면 같은 기능을 수행할 것입니다.

Delegate

  • TableCell을 탭(클릭) 했을때 어떠한 기능을 수행하는 권한을 위임하는 프로토콜
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: IndexPath) 
func tableView(tableView: UITableView, willBeginEditingRowAtIndexPath indexPath: IndexPath)
  • 외울필요? X 자동완성을 사용하자 ( 우리 신세대임..ㅋ )
  • 메서드의 인자만 봐도 어떤 기능을 수행 할 지 짐작이 가능하다
  • didSelectRowAtIndexPath → 이름부터가 선택 됐을때, 어떠한 동작을 수행할 것인지 에 대한 정의를 내리면 될것 같다
  • willBeginEditingRowAtIndexPath ⇒ 공식문서 의 내용을 보니 행의 삭제와 같은 기능을 수행 할 때 어떤 동작을 결정할 지를 정의하면 된다

⇒ 물론 Delegate의 func들은 Optional이기 때문에 반드시 정의 할 필요는 없다.

 

DataSource

  • TableView의 Cell을 어떻게 보여줄가 에 대한 권한을 위임(?) 하는 프로토콜
  • 몇개의 행을 표시할 것인지? 각 행에는 어떤 내용을 보여줄 것인지등등 간단히 말해 View를 그리는 역할을 수행한다고 생각하면 된다
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: IndexPath) -> UITableViewCell
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
  • 위 두가지 메서드는 Datasource 프로토콜을 채택 할 때 반드시 정의해 줘야 하는 메서드!
  • 외우지 말자.. ( Datasource 채택하면 빨간줄 뜨면서 자동으로 채워진다! )
  • numberOfRowsInSection ⇒ 이름만 봐도 몇개의 섹션을 나눌것 인지 정의하면 된다. 말 그대로 몇개의 행을 테이블 뷰에 표시 해 줄것인지 정의해 주면 된다 ( 정수를 반환하면 반환된 값 만큼 테이블뷰의 행이 생성된다 )
  • cellForRowAtIndexPath ⇒ 각 행(cell)에 어떤 내용을 보여 줄 것인지 정의해 주면 된다. 말 그대로 어떤 내용을 표시해 줄지에 대한 정의를 내리면 되고, indecPath 를 통해 각 행이 for 구문 처럼 순차적으로 정의된다 ( 이해가 안가면 직접 구현해 보자 )
  • 두개의 메서드 말고 추가적인 메서드들도 있으나, 모두 외울 필요없다, 필요하면 그때 그때 찾아 사용하자

⇒ 한줄 정리 : Delegate는 어떠한 동작 을 수행, DataSource는 어떠한 내용 을 표시

개요 :

A control that displays one or more buttons in a tab bar for selecting between different subtasks, views, or modes in an app.

→ 앱의 각자 다른 뷰 또는 모드 중 하나를 선택하기 위해 탭 표시줄에 하나 이상의 버튼을 표시하는 컨트롤.

정의

@MainActor class UITabBar : UIView

→ UIView를 상속받는 클래스로 정의되어 있다

StoryBoard 사용하여 TabBar 구성하기

  1. TabBar 로 표현할 View를 선택한후, 상단의 Editor - Embed In - Tab Bar Controller 를 선택한다

2. TabBar 구성 확인 : TabBar가 연결됨을 확인한다 ( segue 에 대해서 더 깊은 공부 필요 )

3. 연결된 화면에서 Tab을 선택하여, 인스펙터 창에서 Tab Item을 수정한다 ( Title 에는 Tab Item의 이름을, Image 에서 Tab Item의 기호를 수정한다 → HIG를 참고하여 SF Symbol 활용 )

4. [ Shift + Command + L ] 단축키를 이용해 컴포넌트 창을 열어 새로 추가할 ViewController를 추가

5. Tab Bar Controller 를 선택한후, control 키를 누른 상태로 방금 생성한 뷰 컨트롤러랑 연결한다

→ 이때, Relationship Segue view controllers 를 선택하면 탭바와 연결됨을 확인할 수 있다

6. 새로 생성한 ViewController를 UIViewController 를 상속받는 ViewController class와 연결

→ 인스펙터 창에서 class를 선택하여 지정한 ViewController와 연결한다

  • 위 순서대로 설정하고 앱을 실행하면 TabBar가 정상적으로 적용됨을 확인 할 수 있다!

 

⇒ 여기 까지, Storyboard 를 사용하여 TabBar를 적용하는 방법을 알아 봤다

CodeBase 로도 구현하는 방법이 있다, 이 방법을 쓰면 스토리보드를 사용하지 않고 오직 코드로만 구성할 수 있지만 아직은 공부하는 단계이므로 스토리보드 기반으로 적용을 한후, 시간이 남으면 프로젝트 자체를 모두 코드로만 구현해보자!

iOS의 ViewControlle의 생명주기는 개발함에 있어 굉장히 중요하다.

해당 View에 컨텐츠가 언제 나타나야 하는지, 컨텐츠의 내용은 무엇인지, 해당 컨텐츠의 내용이 뷰가 사라지면 어떻게 되야하는지 등등 개발함에 있어 반드시 알아야 하는 중요한 사항들이있다.

ViewController의 생명주기에 대해 알아보자!

1. ViewDidLoad()

공식문서에 의하면 뷰 컨트롤러가 메모리에 로드된후 호출되는 메소드이다.

다시말해 뷰가 메모리에 로딩이 완료되면 시스템에 의해 자동으로 호출되는 메소드로, 화면이 처음 생성될때 딱 한번 실행된다.

2. ViewWillAppear()

공식문서에 의하면 뷰가 뷰 계층에 추가될 것임을 뷰 컨트롤러 알려주는 메소드이다.

다시말해 뷰가 화면에 나타나기 직전! 해당 메서드가 호출된다!

그럼, ViewDidLoad 도 화면에 나타나기전, 수행되는데 이 둘의 차이는 무엇일까?

직접 구현해보면 차이를 파악알수 있다.

처음 View를 표시할때 ViewDidLoad() 가 호출되고, 그다음에 ViewWillApear() 가 호출된다,

그리고 다른 뷰로 넘어갈때, 마찬가지로 둘다 호출이 되지만 다시 이전화면으로 돌아갈때

ViewWillAppear() 메소드만 호출됨을 알수있다.

즉, ViewDidLoad() 는 메모리가 해제되기 전까지는 무조건 1번만 호출되며, ViewWillAppear() 메소드는 메모리와 관계없이 해당 뷰를 표시할때 무조건 호출되는 차이가 있다!

3. ViewDidAppear()

공식문서에 의하면 뷰가 뷰 계층에 추가되었음을 뷰 컨트롤러에 알려주는 메소드이다.

다시 말해 ViewWillAppear() 는 뷰가 표시되기 직전 호출되는 메소드라면,

ViewDidAppear() 는 뷰가 표시된 직후!!! 호출되는 메소드이다!

4. ViewWillDisappear()

공식문서에 의하면 뷰가 뷰 계층에서 제거될 것임을 뷰 컨트롤러에 알려주는 메소드이다.

다시말해 뷰가 사라지기 직전 호출되는 메소드 이다!

5. ViewDidDisappear()

공식문서에 의하면 뷰가 뷰 계층에서 제거되었음을 뷰 컨트롤러에 알려주는 메소드이다.

마찬가지로 ViewWillDisappear() 가 사라지기 직전 호출되는 메소드라면, ViewDidDisappear()는 사라진 직후 호출되는 메소드이다.

이와 같이 ViewController의 생명주기는 메소드의 이름만으로도 충분히 어떤일을 수행하는 메소드인지 짐작할수 있다!

이를 직접 구현하여 실제로 어떤 순서로 호출되는지 파악해 보자!

확실히 호출되는 순서를 보면 더욱더 이해하기 쉽다!

이 생명주기를 잘 기억하여 

View 에 표시되는 데이터나 저장해야하는 시점 등등을 적절한 메소드에 적절하게 사용하면 된다!

아주 기본적이면서 아주 중요한 내용이다!

+ Recent posts