본문 바로가기
iOS 프로그래밍 실무

iOS 프로그래밍 실무 5주차

by 노아입니다 2025. 4. 3.

Delegate와 DataSource를 사용하는 UI 컴포넌트 개념 정리

iOS 개발에서 DelegateDataSource 패턴은 UI 컴포넌트가 유연하게 동작할 수 있도록 도와주는 중요한 개념입니다. UITableView, UICollectionView, UIPickerView 같은 여러 UI 컴포넌트에서 활용되며, 데이터 관리와 사용자 인터랙션 처리를 분리할 수 있도록 해줍니다.


1. Delegate와 DataSource란?

🔹 Delegate (위임자)

Delegate는 UI 컴포넌트의 특정 이벤트(사용자 인터랙션 등)에 대한 처리를 위임하는 역할을 합니다.
예를 들어, UITableView에서 특정 셀이 선택되었을 때 어떤 동작을 할지 결정하는 역할을 Delegate가 수행합니다.

Delegate의 핵심 역할

  • 이벤트 응답 처리 (예: 셀 선택, 편집 등)
  • UI 동작을 커스터마이징 (예: 스와이프 삭제, 높이 조절 등)

예시: UITableViewDelegate

extension ViewController: UITableViewDelegate {
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        print("\(indexPath.row)번째 셀이 선택됨")
    }
}

🔹 DataSource (데이터 소스)

DataSource는 UI 컴포넌트에 데이터를 제공하는 역할을 합니다.
예를 들어, UITableView에서 몇 개의 셀이 표시될지, 각 셀에 어떤 데이터를 넣을지 결정하는 역할을 합니다.

DataSource의 핵심 역할

  • UI에 표시할 데이터 제공
  • 셀 개수 및 구성 관리

예시: UITableViewDataSource

extension ViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 10 // 10개의 셀을 표시
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        cell.textLabel?.text = "셀 \(indexPath.row)"
        return cell
    }
}

2. Delegate & DataSource를 사용하는 UI 컴포넌트

다음은 iOS에서 DelegateDataSource 패턴을 활용하는 대표적인 UI 컴포넌트입니다.

UI 컴포넌트 Delegate DataSource
UITableView UITableViewDelegate UITableViewDataSource
UICollectionView UICollectionViewDelegate UICollectionViewDataSource
UIPickerView UIPickerViewDelegate UIPickerViewDataSource
UITextField UITextFieldDelegate X
UIScrollView UIScrollViewDelegate X

📌 특이사항:

  • UITextFieldUIScrollViewDelegate만 존재하고, DataSource는 필요하지 않음.
  • UICollectionViewUITableView와 유사하지만, UICollectionViewDelegateFlowLayout을 추가적으로 활용할 수 있음.

3. Delegate & DataSource 적용 방식

Delegate와 DataSource를 적용하는 방식에는 3가지 방법이 있습니다.

1) 뷰 컨트롤러에서 직접 구현 (가장 일반적)

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.delegate = self
        tableView.dataSource = self
    }
}

2) 별도의 클래스로 분리 (대형 프로젝트에서 선호)

class TableViewDelegate: NSObject, UITableViewDelegate {
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        print("\(indexPath.row) 번째 셀이 선택됨")
    }
}
let delegate = TableViewDelegate()
tableView.delegate = delegate

3) 클로저(Combine 등과 함께 활용 가능)

class CustomTableViewDataSource: NSObject, UITableViewDataSource {
    var data: [String] = []

    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
    }
}
let dataSource = CustomTableViewDataSource()
dataSource.data = ["Apple", "Banana", "Cherry"]
tableView.dataSource = dataSource

4. Delegate와 DataSource를 사용할 때의 장점

뷰 컨트롤러와 UI 컴포넌트의 역할을 분리하여 코드가 깔끔해짐
다양한 방식으로 데이터와 UI 동작을 커스터마이징 가능
여러 화면에서 같은 Delegate & DataSource 로직을 재사용 가능


5. 마무리

iOS에서 DelegateDataSource 패턴은 UI 컴포넌트의 확장성과 유지보수성을 높이는 중요한 개념입니다. UITableView, UICollectionView, UIPickerView 등 다양한 UI 요소에서 활용되며, 이벤트 처리와 데이터 관리를 분리할 수 있도록 돕습니다.

이해를 돕기 위해 정리하자면:

  • Delegate → UI 이벤트 처리 (사용자 액션)
  • DataSource → 데이터 제공 (셀 개수, 내용 설정)

Swift 상속과 프로토콜 채택 개념 정리

Swift에서 코드의 재사용성과 확장성을 높이기 위해 클래스 상속(Inheritance)프로토콜 채택(Protocol Conformance) 을 활용합니다. 이 두 가지 개념은 비슷해 보일 수 있지만, 사용 목적과 동작 방식이 다릅니다. 이번 포스팅에서는 상속과 프로토콜의 차이점과 활용 방법을 정리해보겠습니다.


1. Swift에서 상속(Inheritance)이란?

🔹 상속이란?

Swift에서 클래스(Class)는 상속을 통해 다른 클래스로부터 속성과 메서드를 물려받을 수 있습니다. 즉, 기존 클래스를 확장하고, 추가적인 기능을 정의할 수 있습니다.

상속의 특징

  • Swift에서 클래스(Class)만 상속 가능 (구조체와 열거형은 상속 불가)
  • super 키워드를 사용하여 부모 클래스의 메서드를 호출 가능
  • 메서드, 속성, 서브스크립트를 오버라이딩(재정의) 가능
  • 다중 상속은 지원하지 않음 (하나의 클래스만 상속 가능)

🔹 상속 사용 예제

// 부모 클래스 (슈퍼클래스)
class Animal {
    var name: String

    init(name: String) {
        self.name = name
    }

    func makeSound() {
        print("Some generic sound")
    }
}

// 자식 클래스 (서브클래스)
class Dog: Animal {
    func wagTail() {
        print("\(name) is wagging its tail!")
    }

    override func makeSound() {
        print("Bark! Bark!")
    }
}

let myDog = Dog(name: "Buddy")
myDog.makeSound() // "Bark! Bark!"
myDog.wagTail()   // "Buddy is wagging its tail!"

🔹 요점 정리:

  • Dog 클래스가 Animal 클래스를 상속받아 name 속성과 makeSound() 메서드를 사용할 수 있음.
  • makeSound() 메서드를 오버라이딩(재정의) 하여 강아지만의 소리를 낼 수 있도록 변경.

🔹 super 키워드 사용

부모 클래스의 메서드를 자식 클래스에서 활용하려면 super 키워드를 사용할 수 있습니다.

class Cat: Animal {
    override func makeSound() {
        super.makeSound() // 부모 클래스의 메서드 실행
        print("Meow! Meow!")
    }
}

let myCat = Cat(name: "Kitty")
myCat.makeSound()
// 출력: 
// Some generic sound
// Meow! Meow!

super를 사용하면 부모 클래스의 메서드를 실행한 후, 추가적인 동작을 수행할 수 있습니다.


2. Swift 프로토콜(Protocol) 채택이란?

🔹 프로토콜(Protocol)이란?

Protocol은 특정 기능을 정의하는 청사진(Interface) 입니다.
구조체, 클래스, 열거형이 프로토콜을 채택(Adopt) 하여 해당 기능을 구현할 수 있습니다.

프로토콜의 특징

  • 클래스뿐만 아니라 구조체(Struct), 열거형(Enum)도 채택 가능
  • 다중 프로토콜 채택 가능 (다중 상속 대신 사용)
  • 프로토콜에 메서드, 속성 요구사항을 정의할 수 있음

🔹 프로토콜 선언과 채택 예제

// 프로토콜 정의
protocol SoundMaking {
    func makeSound() // 구현을 강제하는 메서드
}

// 클래스에서 프로토콜 채택
class Bird: SoundMaking {
    func makeSound() {
        print("Chirp! Chirp!")
    }
}

// 구조체에서도 프로토콜 채택 가능
struct Car: SoundMaking {
    func makeSound() {
        print("Vroom! Vroom!")
    }
}

let parrot = Bird()
parrot.makeSound() // "Chirp! Chirp!"

let sportsCar = Car()
sportsCar.makeSound() // "Vroom! Vroom!"

🔹 요점 정리:

  • SoundMaking 프로토콜을 정의하고, Bird 클래스와 Car 구조체에서 채택하여 구현.
  • Bird는 동물이고, Car는 탈것이지만 둘 다 makeSound() 기능을 가질 수 있음 → 유연한 설계 가능!

🔹 다중 프로토콜 채택 가능

protocol Flyable {
    func fly()
}

protocol Swimmable {
    func swim()
}

class Duck: Flyable, Swimmable {
    func fly() {
        print("The duck is flying!")
    }

    func swim() {
        print("The duck is swimming!")
    }
}

let duck = Duck()
duck.fly()  // "The duck is flying!"
duck.swim() // "The duck is swimming!"

다중 프로토콜을 채택하여 다양한 기능을 가질 수 있음.
상속은 하나의 클래스만 가능하지만, 프로토콜은 여러 개를 채택할 수 있음.


3. 상속 vs 프로토콜 차이점

비교 항목 상속(Inheritance) 프로토콜(Protocol)
사용 대상 클래스(Class)만 가능 클래스, 구조체, 열거형 모두 가능
다중 적용 가능 여부 ❌ 다중 상속 불가능 ✅ 다중 프로토콜 채택 가능
기능 확장 방식 기존 클래스의 기능을 상속 후 수정 특정 기능을 정의하고 필요한 곳에서 구현
메서드 구현 여부 상속받으면 기본 구현을 자동으로 사용 프로토콜을 채택하면 반드시 구현해야 함 (옵셔널 제외)
재사용성 부모-자식 관계로 기능을 확장 독립적으로 다양한 곳에서 사용 가능

정리하자면…

  • 상속 → 기존 클래스를 확장하고 싶을 때 사용
  • 프로토콜 → 특정 기능을 여러 타입에서 공유하고 싶을 때 사용

4. 프로토콜과 상속을 함께 사용하기

상속과 프로토콜을 함께 활용하면 강력한 코드 재사용이 가능합니다.

// 프로토콜 정의
protocol Runnable {
    func run()
}

// 부모 클래스
class Animal {
    var name: String

    init(name: String) {
        self.name = name
    }
}

// 자식 클래스 + 프로토콜 채택
class Cheetah: Animal, Runnable {
    func run() {
        print("\(name) is running fast!")
    }
}

let cheetah = Cheetah(name: "Speedy")
cheetah.run() // "Speedy is running fast!"

CheetahAnimal을 상속받고, Runnable 프로토콜을 채택하여 기능을 확장


5. 결론

Swift에서 상속(Inheritance)프로토콜(Protocol) 은 각각 다른 목적을 가지고 있으며, 상황에 맞게 적절히 활용하는 것이 중요 합니다.

📌 상속은 언제 사용할까?

  • 기존 클래스의 속성과 메서드를 물려받아 확장할 때
  • 공통된 기능을 가진 클래스들을 그룹화할 때

📌 프로토콜은 언제 사용할까?

  • 특정 기능을 여러 타입(클래스, 구조체, 열거형)에서 구현해야 할 때
  • 다중 상속이 필요할 때 (Swift는 다중 상속을 지원하지 않으므로, 프로토콜로 해결)

💡 최적의 설계는 상속과 프로토콜을 적절히 조합하여 활용하는 것입니다! 🚀

UITableViewDataSource 프로토콜 개념 정리

UITableViewDataSourceUITableView가 데이터를 표시하는 데 필요한 정보를 제공하는 프로토콜입니다. 즉, 테이블 뷰가 몇 개의 셀을 표시할지, 각 셀에 어떤 데이터를 넣을지 등을 정의하는 역할을 합니다.

UITableViewDataSource반드시 구현해야 하는 필수 메서드 2개가 있습니다.
✅ 데이터 제공에만 집중하며, 셀 선택 등의 UI 이벤트 처리는 UITableViewDelegate가 담당합니다.


1. UITableViewDataSource 프로토콜 필수 메서드

🔹 1) tableView(_:numberOfRowsInSection:)

각 섹션에 표시할 행(Row)의 개수를 반환하는 메서드입니다.

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
  • section → 현재 섹션의 인덱스
  • 반환값 → 해당 섹션에 표시할 셀(행)의 개수

📌 예제:

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 10 // 10개의 행을 표시
}

🔹 2) tableView(_:cellForRowAt:)

각 행(Row)에 표시할 셀 객체를 생성하고 반환하는 메서드입니다.

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
  • indexPath.row → 현재 행(Row)의 인덱스
  • indexPath.section → 현재 섹션의 인덱스
  • 반환값 → UITableViewCell (셀 객체)

📌 예제:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
    cell.textLabel?.text = "행 \(indexPath.row)"
    return cell
}

dequeueReusableCell(withIdentifier:for:)를 사용하여 재사용 가능한 셀을 가져와서 설정해야 메모리 사용을 최적화할 수 있습니다.


2. 선택적으로 구현할 수 있는 메서드

UITableViewDataSource에는 필수 메서드 외에도 선택적으로 구현할 수 있는 메서드가 있습니다.

🔹 1) numberOfSections(in:)

테이블 뷰의 섹션(Section) 개수를 반환하는 메서드입니다.
기본적으로 1개의 섹션이 존재하므로 구현하지 않으면 기본값 1이 적용됩니다.

func numberOfSections(in tableView: UITableView) -> Int {
    return 2 // 두 개의 섹션
}

🔹 2) tableView(_:titleForHeaderInSection:) / tableView(_:titleForFooterInSection:)

각 섹션의 헤더(Header)와 푸터(Footer)에 표시할 텍스트를 지정할 수 있습니다.

func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    return "섹션 \(section) 헤더"
}

func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? {
    return "섹션 \(section) 푸터"
}

🔹 3) tableView(_:canEditRowAt:)

각 셀을 편집(삭제, 삽입)할 수 있는지 여부를 반환하는 메서드입니다.

func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
    return true // 모든 행을 편집 가능하게 설정
}

🔹 4) tableView(_:commit:forRowAt:)

셀을 삭제하거나 추가할 때 호출되는 메서드입니다.

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
    if editingStyle == .delete {
        print("\(indexPath.row)번째 행 삭제됨")
        // 실제 데이터 삭제 코드 작성 가능
    }
}

3. UITableViewDataSource 적용 예제

UITableViewDataSource를 활용하여 간단한 테이블 뷰를 구현하는 방법을 알아보겠습니다.

🔹 1) 스토리보드에서 TableView 연결

  1. 스토리보드에서 UITableView를 추가하고, ViewController에 연결
  2. UITableViewdelegatedataSourceViewController에 연결

🔹 2) 코드 구현

import UIKit

class ViewController: UIViewController, UITableViewDataSource {
    @IBOutlet weak var tableView: UITableView!

    let items = ["Apple", "Banana", "Cherry", "Date", "Elderberry"]

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.dataSource = self
    }

    // 1. 섹션당 행 개수
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return items.count
    }

    // 2. 각 행에 대한 셀 설정
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        cell.textLabel?.text = items[indexPath.row]
        return cell
    }
}

코드 설명

  • tableView.dataSource = self를 설정하여 ViewController가 데이터 소스를 제공
  • numberOfRowsInSection에서 데이터 개수만큼 행을 표시
  • cellForRowAt에서 items 배열의 데이터를 각 셀에 넣어 표시

4. UITableViewDataSource와 UITableViewDelegate 차이점

비교 항목 UITableViewDataSource UITableViewDelegate
역할 데이터를 테이블 뷰에 제공 사용자 인터랙션 처리
필수 구현 메서드 ✅ 있음 (numberOfRowsInSection, cellForRowAt) ❌ 없음 (선택 사항)
주요 기능 셀 개수, 데이터 제공 셀 선택, 높이 조절, 편집 기능 등
예제 메서드 numberOfRowsInSection, cellForRowAt didSelectRowAt, heightForRowAt

UITableViewDataSource데이터를 어떻게 표시할지 결정
UITableViewDelegate사용자 입력(셀 선택, 높이 조절 등) 을 처리


📌 핵심 정리

  • UITableViewDataSource는 테이블 뷰에 데이터를 제공하는 역할
  • 필수 메서드 2개
    1. numberOfRowsInSection → 행(Row) 개수 반환
    2. cellForRowAt → 각 셀을 생성 및 데이터 설정
  • 선택적 메서드로 섹션 개수, 헤더/푸터 설정, 셀 삭제 처리 가능
  • UITableViewDelegate와 함께 사용하여 더 다양한 기능 구현 가능

UITableViewDataSource테이블 뷰의 데이터 관리 담당, UITableViewDelegate사용자 인터랙션 담당 → 함께 사용하면 강력한 UI를 만들 수 있음! 🚀

UITableViewDataSource 선택적 메서드 정리

UITableViewDataSource에는 필수 메서드 외에도 선택적으로 구현할 수 있는 메서드가 있습니다.
이 메서드들은 테이블 뷰의 섹션, 헤더, 푸터, 편집 기능 등을 추가할 때 유용합니다.


1. 섹션 관련 메서드

🔹 섹션 개수 설정

func numberOfSections(in tableView: UITableView) -> Int {
    return 3 // 3개의 섹션
}

✅ 기본값은 1이며, 여러 개의 섹션을 만들고 싶을 때 사용.

🔹 섹션 헤더 & 푸터 텍스트 설정

func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    return "섹션 \(section) 헤더"
}

func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? {
    return "섹션 \(section) 푸터"
}

헤더/푸터 텍스트를 표시할 때 사용.


2. 편집(삭제, 삽입) 관련 메서드

🔹 특정 행을 편집 가능하게 설정

func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
    return true // 모든 행을 편집 가능
}

삭제/삽입 기능을 활성화할 때 사용.

🔹 삭제 & 삽입 동작 처리

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
    if editingStyle == .delete {
        print("\(indexPath.row) 번째 행 삭제됨")
    }
}

사용자가 셀을 삭제했을 때 데이터와 UI를 업데이트할 때 사용.


3. 행 이동 관련 메서드

🔹 특정 행을 이동 가능하게 설정

func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
    return true // 모든 행 이동 가능
}

🔹 행 이동 처리

func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
    print("\(sourceIndexPath.row) → \(destinationIndexPath.row) 로 이동")
}

셀을 드래그해서 순서를 바꿀 때 사용.


4. 인덱스(목차) 관련 메서드

🔹 A-Z 같은 인덱스 목록 표시

func sectionIndexTitles(for tableView: UITableView) -> [String]? {
    return ["A", "B", "C"]
}

연락처 앱처럼 빠르게 스크롤할 때 사용.

🔹 인덱스 클릭 시 해당 섹션으로 이동

func tableView(_ tableView: UITableView, sectionForSectionIndexTitle title: String, at index: Int) -> Int {
    return index
}

사용자가 인덱스를 눌렀을 때 올바른 섹션으로 이동하도록 설정.


📌 요약

메서드 설명
numberOfSections(in:) 섹션 개수 설정
titleForHeaderInSection 섹션 헤더 제목 설정
titleForFooterInSection 섹션 푸터 제목 설정
canEditRowAt 특정 행 편집 가능 여부 설정
commit editingStyle 행 삭제/삽입 처리
canMoveRowAt 특정 행 이동 가능 여부 설정
moveRowAt 행 이동 처리
sectionIndexTitles 인덱스(A-Z) 목록 표시
sectionForSectionIndexTitle 선택한 인덱스에 해당하는 섹션 이동

필수는 아니지만 기능을 확장할 때 유용한 메서드들!
삭제, 이동, 인덱스 표시 등을 추가할 때 활용하면 좋음!

UITableView & UITableViewCell 요약 정리

1. UITableView란?

UITableView세로 스크롤이 가능한 리스트 형태의 UI 컴포넌트
iOS에서 가장 많이 사용되는 UI 요소 (예: 연락처, 설정 목록 등)
많은 데이터를 효율적으로 표시하고, 셀을 재사용하여 성능 최적화

📌 주요 특징

  • 스크롤 가능한 리스트 UI
  • 데이터 관리UITableViewDataSource
  • 셀 이벤트 처리UITableViewDelegate
  • 셀을 재사용하여 메모리 최적화 (dequeueReusableCell)

📌 기본 사용법

let tableView = UITableView(frame: view.bounds, style: .plain)
tableView.dataSource = self
tableView.delegate = self
view.addSubview(tableView)

2. UITableViewCell이란?

UITableViewCell테이블 뷰의 개별 행(셀)을 나타내는 객체
✅ 기본 스타일을 제공하지만, 커스텀 셀을 만들어 다양한 UI 구성 가능

📌 기본 스타일 종류 (UITableViewCell.CellStyle)

스타일 설명
.default 기본 스타일 (텍스트 하나)
.subtitle 제목 + 부제목
.value1 왼쪽에 제목, 오른쪽에 부제목 (설정 앱 스타일)
.value2 제목과 부제목이 좌우 정렬됨

📌 기본 셀 사용 예제

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
    cell.textLabel?.text = "셀 \(indexPath.row)"
    return cell
}

셀을 재사용(dequeueReusableCell)하여 성능 최적화


3. UITableView + UITableViewCell 사용 예제

import UIKit

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    let tableView = UITableView()
    let items = ["Apple", "Banana", "Cherry"]

    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 items.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        cell.textLabel?.text = items[indexPath.row]
        return cell
    }
}

기본적인 테이블 뷰 구현 코드
UITableViewCell을 사용하여 데이터 표시


4. 커스텀 UITableViewCell 만들기

UITableViewCell을 커스텀하여 이미지, 버튼 등 다양한 UI 요소 추가 가능

📌 커스텀 셀 클래스 생성

class CustomCell: UITableViewCell {
    let iconImageView = UIImageView()
    let titleLabel = UILabel()

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)

        iconImageView.frame = CGRect(x: 10, y: 10, width: 40, height: 40)
        titleLabel.frame = CGRect(x: 60, y: 10, width: 200, height: 40)

        contentView.addSubview(iconImageView)
        contentView.addSubview(titleLabel)
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

📌 커스텀 셀 사용 예제

tableView.register(CustomCell.self, forCellReuseIdentifier: "customCell")

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "customCell", for: indexPath) as! CustomCell
    cell.iconImageView.image = UIImage(named: "icon")
    cell.titleLabel.text = "커스텀 셀 \(indexPath.row)"
    return cell
}

이미지 & 텍스트를 포함한 커스텀 셀 구현
더 복잡한 UI 구성을 하고 싶을 때 유용!


5. UITableView & UITableViewCell 핵심 정리

항목 설명
UITableView 리스트 형태의 UI를 제공하는 UIView
UITableViewCell 테이블 뷰의 개별 행(셀)
데이터 관리 UITableViewDataSource에서 처리 (numberOfRowsInSection, cellForRowAt)
이벤트 처리 UITableViewDelegate에서 처리 (didSelectRowAt)
성능 최적화 dequeueReusableCell(withIdentifier:) 사용하여 셀 재사용
커스텀 셀 UITableViewCell을 서브클래싱하여 UI 구성 가능

기본 스타일 제공, 하지만 필요하면 커스텀 가능!
데이터 & UI를 효율적으로 관리하는 것이 핵심! 🚀


✅ 과제