Array / UITableView

hyun·2025년 5월 21일

iOS

목록 보기
37/54

 배열에 요소 추가하기

1. append(_:) – 마지막에 하나 추가하기

배열의 끝에 새 값을 넣을 때 사용함

var numbers = [1, 2, 3]
numbers.append(4)
print(numbers)  // [1, 2, 3, 4]

👉 [1, 2, 3] 뒤에 4를 붙인 것

2. insert(_:at:) – 원하는 위치에 넣기

배열 안에서 내가 정한 자리에 값을 넣을 수 있음

var numbers = [1, 2, 4]
numbers.insert(3, at: 2)
print(numbers)  // [1, 2, 3, 4]

👉 2번째 자리에 3을 끼워 넣은 것 (자리는 0부터 시작)

3. += – 여러 개 한꺼번에 추가하기

배열에 여러 값을 한 번에 더하고 싶을 때 사용함

var numbers = [1, 2, 3]
numbers += [4, 5]
print(numbers)  // [1, 2, 3, 4, 5]

👉 4와 5를 한 번에 추가

 배열에서 요소 삭제하기

1. remove(at:) – 특정 자리의 값을 지우기

var numbers = [1, 2, 3, 4]
numbers.remove(at: 2)
print(numbers)  // [1, 2, 4]

👉 2번째 자리에 있던 3이 없어짐

2. removeFirst() / removeLast() – 처음이나 마지막 값 지우기

배열의 맨 앞이나 맨 뒤 값을 지우고 싶을 때 씀

var numbers = [1, 2, 3, 4]
numbers.removeFirst()
print(numbers)  // [2, 3, 4]

numbers.removeLast()
print(numbers)  // [2, 3]

👉 처음 값(1)과 마지막 값(4)이 지워짐

3. removeAll() – 전부 지우기

배열 안에 있는 걸 전부 지워버리고 싶을 때 사용

var numbers = [1, 2, 3, 4]
numbers.removeAll()
print(numbers)  // []

👉 다 없어져서 빈 배열이 됨

 배열 필터링하기

filter(_:) – 조건에 맞는 것만 골라내기

배열에서 내가 원하는 조건에 맞는 값만 뽑아내는 것

let numbers = [1, 2, 3, 4, 5, 6]
let evenNumbers = numbers.filter { $0 % 2 == 0 }
print(evenNumbers)  // [2, 4, 6]

👉 짝수만 골라낸 것 ($0은 배열 안의 하나하나를 뜻함)

 배열 정렬하기

배열 안의 숫자나 값을 순서대로 정리하는 방법
크기 순으로 정리하거나 거꾸로 정리할 수 있음

1. sorted() – 정렬된 새 배열 만들기

배열을 정렬하지만, 원래 배열은 그대로 두고 새로운 정렬된 배열을 만들어 줌

let numbers = [3, 1, 4, 1, 5, 9]
let sortedNumbers = numbers.sorted()
print(sortedNumbers)  // [1, 1, 3, 4, 5, 9]

👉 [3, 1, 4, 1, 5, 9]을 오름차순으로 정렬해서 [1, 1, 3, 4, 5, 9]이라는 새 배열로 만듦
원래 배열은 그대로 있음

2. sort() – 원래 배열을 정렬하기

배열을 정렬하고, 그 결과를 원래 배열에 저장함

var numbers = [3, 1, 4, 1, 5, 9]
numbers.sort()
print(numbers)  // [1, 1, 3, 4, 5, 9]

👉 정렬된 결과가 numbers에 바로 저장됨

3. 내림차순 정렬 – 큰 수부터 정렬하기

sorted(by: >) 또는 sort(by: >)를 쓰면 큰 수부터 정렬됨

let numbers = [3, 1, 4, 1, 5, 9]
let descendingNumbers = numbers.sorted(by: >)
print(descendingNumbers)  // [9, 5, 4, 3, 1, 1]

👉 숫자가 큰 것부터 차례로 정렬함


할 일쓰는 방법
맨 끝에 추가append()
중간에 추가insert()
여러 개 추가+=
앞/뒤 값 삭제remove(at:)
특정 값 삭제removeFirst(), removeLast()
전부 삭제removeAll()
조건에 맞는 값만 골라내기filter()
오름차순 정렬sorted(), sort()
내림차순 정렬sorted(by: >), sort(by: >)

 딕셔너리 심화

할 일쓰는 방법
딕셔너리 생성var dict: [String: Int] = ["A": 1, "B": 2]
값 가져오기dict["A"] → Optional(1)
기본값 설정dict["C", default: 0] → 0

값 추가/수정

할 일쓰는 방법
새 값 추가dict["C"] = 3
기존 값 수정dict["A"] = 10
기존 값 반환하며 수정dict.updateValue(20, forKey: "B") → 이전 값 반환

값 삭제

할 일쓰는 방법
특정 키 삭제dict.removeValue(forKey: "A")
nil로 삭제dict["B"] = nil
전부 삭제dict.removeAll()

순회

할 일쓰는 방법
키-값 모두 순회for (k, v) in dict {}
키만 순회for k in dict.keys {}
값만 순회for v in dict.values {}

활용

할 일쓰는 방법
조건에 맞는 값만 남기기dict.filter { $0.value > 90 }
값을 문자열로 변환dict.map { "($0.key): ($0.value)" }

 데이터 모델링이란?

데이터 모델링은 데이터를 구조화하고, 데이터 간 관계(Entity, Attribute, Relationship)를 정의하는 작업

목적: 데이터를 일관성 있게 관리하고, 효율적인 저장·검색을 가능하게 함.

Swift에서 데이터 모델 만들기

구조체(Struct)를 사용한 데이터 모델 예시
struct User {
    let id: Int
    var name: String
    var email: String
}

값 타입이라 복사되어 전달됨
주로 간단하고 변하지 않는 데이터에 적합

메서드를 활용한 구조체
mutating func updateEmail(newEmail: String) {
    self.email = newEmail
}

mutating 키워드로 구조체 내부 속성 변경 가능

실제 예시 – Product
struct Product {
    let id: Int
    var name: String
    var price: Double

    mutating func applyDiscount(_ percentage: Double) {
        price -= price * (percentage / 100)
    }
}

데이터 모델을 활용한 앱 구조화 – MVC 패턴

MVC 구성요소

Model : 데이터, 비즈니스 로직 담당 (Struct, API 등)

View : 사용자에게 보여지는 화면 (UILabel, UIView 등)

Controller : Model과 View 연결, 사용자 입력 처리 (UIViewController)

예시
// Model
struct User { let id: Int; var name: String; var email: String }

// View
class UserView: UIView {
    func updateUI(user: User) { /* 사용자 정보 표시 */ }
}

// Controller
class UserViewController: UIViewController {
    var user = User(...)
    func updateUserEmail(newEmail: String) { /* 모델 업데이트 및 뷰 반영 */ }
}

데이터 모델의 역할

데이터 저장 : 사용자, 상품, 게시글 등

데이터 처리 : 가공, 로직 적용

변경 감지 : 값이 바뀌면 UI에 반영

외부 통신 : API, DB와 연결

Swift에서 MVC 패턴 적용하기 요약

1. Model (데이터 모델)
struct User {
    let id: Int
    var name: String
    var email: String
}

사용자의 정보를 저장하는 구조체

데이터만을 책임짐

2. View (화면 구성 요소)

UIKit 기반 View

import UIKit

class UserView: UIView {
    let nameLabel = UILabel()
    let emailLabel = UILabel()

    func updateUI(user: User) {
        nameLabel.text = "이름: \(user.name)"
        emailLabel.text = "이메일: \(user.email)"
    }
}

UI 요소 정의

사용자에게 데이터 시각적으로 보여줌

사용자 입력 X, 로직 없음

콘솔 기반 View (간단 예제)

class UserView {
    func displayUserInfo(_ user: User?) {
        guard let user = user else {
            print("사용자를 찾을 수 없습니다.")
            return
        }
        print("사용자 정보: \(user.name) (\(user.email))")
    }
}
3. Controller (데이터 처리 및 흐름 제어)

UIKit 기반 Controller

import UIKit

class UserViewController: UIViewController {
    var user = User(id: 1, name: "Alice", email: "alice@example.com")
    let userView = UserView()

    override func viewDidLoad() {
        super.viewDidLoad()
        view.addSubview(userView)
        userView.updateUI(user: user)
    }

    func updateUserEmail(newEmail: String) {
        user.email = newEmail
        userView.updateUI(user: user)
    }
}

콘솔 기반 Controller (간단 예제)

class UserController {
    let userManager = UserManager()
    let userView = UserView()

    func addUser(id: Int, name: String, email: String) {
        let user = User(id: id, name: name, email: email)
        userManager.addUser(user)
    }

    func showUserInfo(id: Int) {
        let user = userManager.findUser(byID: id)
        userView.displayUserInfo(user)
    }
}
4. UserManager (Model의 확장)
class UserManager {
    private var users: [User] = []

    func addUser(_ user: User) {
        users.append(user)
    }

    func findUser(byID id: Int) -> User? {
        return users.first { $0.id == id }
    }

    func listUsers() {
        for user in users {
            print("ID: \(user.id), 이름: \(user.name), 이메일: \(user.email)")
        }
    }
}

복수의 사용자 관리 (배열로 저장)

Model이지만 로직 포함됨 (데이터 가공 및 검색)

5. 실행 예제
let userController = UserController()

userController.addUser(id: 1, name: "Alice", email: "alice@example.com")
userController.addUser(id: 2, name: "Bob", email: "bob@example.com")

userController.showUserInfo(id: 1) // 사용자 정보: Alice (alice@example.com)
userController.showUserInfo(id: 3) // 사용자를 찾을 수 없습니다.

MVC 패턴을 사용하는 이유

이점설명
코드 분리역할별로 책임을 나눠 유지보수가 쉬움
확장성각 구성요소를 독립적으로 수정 가능
재사용성View나 Model 재활용 가능

 UITableView 개념과 사용법 요약

1. UITableView란?

표 형태의 목록을 표시하는 UI 구성 요소

기본 구성

TableView: 전체 목록 컨테이너

Section: 데이터를 그룹화한 단위 (0개 이상 가능)

Row (행): 각 섹션의 개별 항목

Cell: 실제로 사용자에게 보여지는 각 행의 뷰

2. 구성 요소

구성 요소역할
UITableViewCell각 행을 구성하는 셀 (기본 스타일 or 커스텀 가능)
UITableViewDataSource데이터를 제공하고 셀을 생성하는 프로토콜
UITableViewDelegate셀 선택, 높이 조절 등 사용자 상호작용 처리

3. UITableViewController란?

테이블 뷰 전용 컨트롤러.

뷰에 직접 테이블 뷰를 추가하지 않아도 됨

데이터 연결, 셀 생성, 선택 처리 등이 기본 내장됨

4. 기본 테이블 뷰 구현 예제

정적인 목록

class FruitListViewController: UITableViewController {
    let fruits = ["사과", "바나나", "딸기", "오렌지", "포도"]

    override func viewDidLoad() {
        super.viewDidLoad()
        self.title = "과일 목록"
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return fruits.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") ?? UITableViewCell(style: .default, reuseIdentifier: "Cell")
        cell.textLabel?.text = fruits[indexPath.row]
        return cell
    }
}

동적인 목록 (배열 활용)

class DynamicListViewController: UITableViewController {
    var items = ["아이템 1", "아이템 2", "아이템 3"]

    override func viewDidLoad() {
        super.viewDidLoad()
        self.title = "동적 목록"
        navigationItem.rightBarButtonItem = UIBarButtonItem(title: "추가", style: .plain, target: self, action: #selector(addItem))
    }

    @objc func addItem() {
        let newItem = "아이템 \(items.count + 1)"
        items.append(newItem)
        tableView.reloadData()
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return items.count
    }

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

5. 주요 메서드 설명

메서드설명
numberOfRowsInSection각 섹션의 셀 개수 반환
cellForRowAt각 셀에 들어갈 데이터 지정
dequeueReusableCell셀 재사용으로 성능 최적화
reloadData()데이터 변경 후 화면 갱신 요청

왜 배열로 관리할까?

1️⃣ 유지 보수가 쉬움: 데이터만 바꾸면 됨

2️⃣ 유연성: 정렬, 필터링 간단

3️⃣ 동적 처리 용이: 네트워크, 사용자 입력 반영 쉬움

 UITableView 셀 종, 커스터마이징, 데이터 처리

기본 셀 스타일

.default, .subtitle, .value1, .value2 형태로 간단한 정보를 빠르게 표현 가능

간단하지만 디자인 제한이 있음

적은 개발 시간, 코드 한 줄로 구현 가능

커스텀 셀

UITableViewCell을 상속받아 UILabel, UIImageView 등 자유롭게 구성

복잡한 UI 필요할 때 필수

오토레이아웃과 translatesAutoresizingMaskIntoConstraints = false 설정이 중요

재사용 식별자(reuseIdentifier) 꼭 사용

데이터 동적 업데이트

배열 items에 데이터를 추가하거나 삭제

tableView.insertRows, deleteRows, reloadRows, reloadData() 등으로 UI 동기화

직접 배열을 바꾸고, 그 변화에 맞게 테이블을 업데이트해줘야 함

추가로 알면 좋은 팁

커스텀 셀에서 이벤트 처리

커스텀 셀 내부에 버튼이 있는 경우,

이벤트를 처리할 수 있도록 델리게이트 패턴이나 클로저를 활용하는 방식도 자주 사용됨

var onButtonTap: (() -> Void)?

@objc func buttonTapped() {
    onButtonTap?()
}
XIB나 스토리보드로 커스텀 셀 만들기

XIB로 만들면 시각적으로 디자인 가능

코드보다 직관적이지만, 코드 재사용성이 떨어질 수 있음

커스텀 셀 높이 조정

커스텀 셀의 높이가 내용에 따라 달라지는 경우에는 다음 설정을 추가함

tableView.rowHeight = UITableView.automaticDimension
tableView.estimatedRowHeight = 60

 reloadData() 요약 정리

역할

reloadData()는 테이블 뷰 전체를 다시 로드하고 UI를 최신 데이터로 갱신함

사용 시점

데이터 배열이 변경된 후

서버 응답 등 외부 데이터 수신 후

필터링, 정렬, 전체 갱신이 필요할 때

여러 셀을 한꺼번에 업데이트해야 할 때

items.append("새 항목")
tableView.reloadData()

작동 방식

numberOfSections, numberOfRowsInSection 메서드 다시 호출

각 셀에 대해 cellForRowAt 호출

전체 테이블 뷰 화면 새로 그림

장점

전체 UI를 간단하고 직관적으로 갱신 가능

단점
  • 모든 셀을 다시 그려서 성능 저하 가능

  • 스크롤 위치와 애니메이션 초기화

  • 한 셀만 바뀌어도 전체가 다시 로드됨

대안 메서드 (부분 업데이트에 적합)
상황메서드
행 추가insertRows(at:with:)
행 삭제deleteRows(at:with:)
특정 행 갱신reloadRows(at:with:)
let indexPath = IndexPath(row: 2, section: 0)
tableView.reloadRows(at: [indexPath], with: .automatic)
주의할 점

데이터 배열을 먼저 변경한 뒤 reloadData()를 호출해야 함

그렇지 않으면 배열과 셀 내용이 불일치할 수 있음

자주 반복 호출하면 퍼포먼스 저하 발생 가능

<정리>
상황권장 방법
전체 데이터를 새로 불러올 때reloadData()
일부 항목만 바뀌었을 때reloadRows, insertRows, deleteRows
성능이 중요한 대형 목록일 때부분 갱신 또는 diff 방식 고려

생각보다 어려운 게 많았던 3-1 ~ 3-2..
내일 한 번 더 복습해야할 듯..!ㅜㅜ

0개의 댓글