5
section / row / cell
UITableViewCell
직접 디자인 할 셀을 만들었다. (UItableViewCell) identifier를 지정해줘야한다.
Constraints
dequeueReusableCell
자식으로 바꾸기 위해 as!를 사용해야한다.
didSelectRowAt
셀을 클릭했을 때 호출되는 메소드이다.
source
import UIKit
// 영화 정보를 저장하는 배열 선언
let image = ["1.png","2.png","3.png","4.png","5.png"] // 영화 포스터 이미지 파일 이름
let name = ["쿵푸팬더4","파묘","남은 인생 10년","댓글부대","오멘: 저주의 시작"] // 영화 제목
let rank = [1,2,3,4,5] // 영화 순위
let open = ["2024-04-10", "2024-02-22", "2023-05-24","2024-03-27", "2024-04-03"] // 영화 개봉일
// UIViewController를 상속받는 ViewController 클래스 선언. UITableViewDelegate와 UITableViewDataSource 프로토콜을 준수하여 테이블 뷰의 기능을 구현합니다.
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet weak var table: UITableView! // 스토리보드에서 연결한 테이블 뷰 아웃렛 변수
// 테이블 뷰의 섹션 개수를 정의하는 메소드. 여기서는 5개의 섹션을 반환합니다.
func numberOfSections(in tableView: UITableView) -> Int {
return 5
}
// 각 섹션에 표시될 행의 개수를 정의하는 메소드. 여기서는 각 섹션마다 5개의 행을 반환합니다.
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 5
}
// 각 행에 대한 셀을 구성하는 메소드. 여기서는 MyTableViewCell 클래스를 사용하여 셀을 구성하고, 영화 제목과 개봉일을 셀에 표시합니다.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "myCell", for: indexPath) as! MyTableViewCell
cell.myLabel.text = name[indexPath.row] // 영화 제목 설정
cell.myOpen.text = open[indexPath.row] // 영화 개봉일 설정
return cell
}
// 특정 행이 선택되었을 때 호출되는 메소드. 여기서는 선택된 행의 indexPath를 콘솔에 출력합니다.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print(indexPath.description)
}
// 뷰가 로드되었을 때 초기 설정을 수행하는 메소드. 테이블 뷰의 delegate와 dataSource를 self로 설정합니다.
override func viewDidLoad() {
super.viewDidLoad()
table.delegate = self
table.dataSource = self
}
}
stack view
line, autoshrink
line : 줄을 몇개 쓸건지 (0으로 설정하면 여러 줄 사용) autoshrink : 폰트 크기 자동 조절
myLabel, myOpen이 Optional인데 풀지 않는 이유
! 옵셔널으로 설정되어있기 때문에 따로 풀지 않아도 알아서 풀린다.
downcasting / upcasting
다운캐스팅(Downcasting)과 업캐스팅(Upcasting)은 객체 지향 프로그래밍에서 사용되는 중요한 개념입니다.
- 업캐스팅(Upcasting):
- 업캐스팅은 하위 클래스의 인스턴스를 상위 클래스의 인스턴스로 캐스팅하는 것을 말합니다.
- 즉, 하위 클래스의 객체를 상위 클래스의 객체로 변환하는 것을 의미합니다.
- 업캐스팅은 자동으로 이루어지며, 명시적인 형변환 없이 상위 클래스의 참조 변수에 하위 클래스의 객체를 할당할 수 있습니다.
- 업캐스팅을 통해 상위 클래스의 메서드와 속성에 접근할 수 있지만, 하위 클래스의 고유한 메서드나 속성에는 접근할 수 없습니다.
- 다운캐스팅(Downcasting):
- 다운캐스팅은 상위 클래스의 인스턴스를 하위 클래스의 인스턴스로 캐스팅하는 것을 말합니다.
- 즉, 상위 클래스의 객체를 하위 클래스의 객체로 변환하는 것을 의미합니다.
- 다운캐스팅은 명시적으로 형변환을 해주어야 하며, 이때 캐스팅이 유효한지를 확인해야 합니다. (예: as? 또는 as! 연산자를 사용하여 캐스팅)
- 다운캐스팅을 통해 하위 클래스의 고유한 메서드나 속성에 접근할 수 있습니다.
간단히 말하면, 업캐스팅은 하위 클래스를 상위 클래스로 변환하는 것이며, 다운캐스팅은 상위 클래스를 하위 클래스로 변환하는 것입니다. 업캐스팅은 자동으로 이루어지지만, 다운캐스팅은 명시적으로 형변환을 해주어야 하며, 유효성을 확인해야 합니다.
예제
class Animal {}
class Dog : Animal {}
let myDog : Dog = Dog()
let myAnimal : Animal = myDog
//모든 강아지는 동물이다
// 안전한 Downcasting
let someAnimal: Animal = Dog()
print(type(of:someAnimal)) //Dog
let x = someAnimal as? Dog
//as?는 안전(옵셔널로 반환, 실패하면 nil반환)
print(type(of:x)) //Optional<Dog>
if let someDog = someAnimal as? Dog {
print(type(of:someDog)) //Dog
} else {
print("Downcasting 실패.")
}
// 강제적인 Downcasting
let anotherDog = someAnimal as! Dog //강제적인 방법(실패 시 런타임 오류 발생)
//someAnimal이 Dog의 인스턴스가 아니면 런타임 오류 발생
print(type(of:anotherDog)) //Dog
위의 Swift 코드는 클래스 상속과 타입 캐스팅(업캐스팅과 다운캐스팅)에 대한 예제입니다. 각 부분에 대한 자세한 설명은 다음과 같습니다:
- 클래스 정의:
Animal
이라는 기본 클래스를 정의합니다.Dog
클래스는Animal
클래스를 상속받습니다. 즉,Dog
는Animal
의 하위 클래스입니다.
- 업캐스팅:
let myDog : Dog = Dog()
는Dog
타입의 인스턴스를 생성하고myDog
변수에 할당합니다.let myAnimal : Animal = myDog
에서myDog
인스턴스(하위 클래스 타입)를myAnimal
변수(상위 클래스 타입)에 할당합니다. 이 과정에서 업캐스팅이 자동으로 발생합니다. 모든Dog
는Animal
이기 때문에 이러한 할당은 안전합니다.
- 다운캐스팅 시도:
let someAnimal: Animal = Dog()
는Dog
인스턴스를 생성하고 이를Animal
타입의 변수someAnimal
에 할당합니다. 이는 업캐스팅의 예입니다.print(type(of:someAnimal))
는someAnimal
의 타입을 출력합니다. 결과는Dog
입니다. 이는someAnimal
이 실제로Dog
인스턴스를 가리키고 있음을 나타냅니다.let x = someAnimal as? Dog
는 안전한 다운캐스팅을 시도합니다.as?
연산자는 실패할 경우nil
을 반환합니다. 여기서는someAnimal
이 실제로Dog
타입이므로 다운캐스팅이 성공하고x
는Optional<Dog>
타입이 됩니다.if let someDog = someAnimal as? Dog
는 옵셔널 바인딩을 사용하여someAnimal
을Dog
타입으로 안전하게 다운캐스팅합니다. 다운캐스팅이 성공하면someDog
변수에 할당되고, 실패하면else
블록이 실행됩니다.
- 강제 다운캐스팅:
let anotherDog = someAnimal as! Dog
는 강제 다운캐스팅을 시도합니다.as!
연산자는 다운캐스팅이 실패할 경우 런타임 오류를 발생시킵니다. 여기서는someAnimal
이 실제로Dog
인스턴스이므로 다운캐스팅이 성공하고 오류가 발생하지 않습니다.
이 예제는 업캐스팅이 자동으로 이루어지며 안전하다는 것과, 다운캐스팅을 할 때는 as?
를 사용하여 안전하게 시도하거나, 확신이 있을 때만 as!
를 사용하여 강제로 시도해야 한다는 것을 보여줍니다.
Optional Chaining
예제
// Person 클래스 정의
class Person {
var name: String // 이름을 저장하는 변수
var age: Int // 나이를 저장하는 변수
// 초기화 메소드. 인스턴스 생성 시 이름과 나이를 설정할 수 있습니다.
init(name: String, age: Int) {
self.name = name
self.age = age
}
}
// Person 인스턴스 생성 및 사용
let kim: Person = Person(name: "Kim", age: 20) // 'Kim'이라는 이름과 20이라는 나이로 Person 인스턴스 생성
print(kim.age) // 20 출력
// 옵셔널 Person 인스턴스 생성 및 사용
let han: Person? = Person(name: "Han", age: 25) // 'Han'이라는 이름과 25라는 나이로 옵셔널 Person 인스턴스 생성
// print(han?.age) //error - 이 줄은 실제로는 에러를 발생시키지 않으며, 옵셔널 체이닝을 사용하여 옵셔널 값을 안전하게 접근합니다.
print(han!.age) // 강제 언래핑을 사용하여 옵셔널 값을 접근. 주의: 옵셔널 값이 nil일 경우 런타임 에러 발생
print(han?.age) // 옵셔널 체이닝을 사용하여 옵셔널 값을 안전하게 접근. 결과는 Optional(25)로 출력됩니다.
print((han?.age)!) // 옵셔널 체이닝 후 강제 언래핑을 사용하여 값을 접근. 25 출력
// 옵셔널 바인딩을 사용하여 옵셔널 값을 안전하게 언래핑
if let hanAge = han?.age {
print(hanAge) // 옵셔널 값이 nil이 아닐 경우, hanAge 변수에 값을 할당하고 출력
} else {
print("nil") // 옵셔널 값이 nil일 경우 "nil" 출력
}
옵셔널을 언래핑하는 여러가지 방법
// 옵셔널 변수 x 선언 및 초기화
var x: String? = "Hi" // x는 옵셔널 String 타입. 초기값으로 "Hi"를 가짐. "Hi"를 지우면 x는 nil 값을 가짐.
// 옵셔널 변수 x의 값과 강제 언래핑된 값을 출력
print(x, x!) // 첫 번째 x는 옵셔널 값을 그대로 출력. 두 번째 x!는 강제 언래핑을 통해 옵셔널을 벗겨내고 값을 출력.
// 옵셔널 바인딩을 사용하여 x의 값을 안전하게 언래핑
if let a = x {
print(a) // x가 nil이 아니면 a에 x의 값을 할당하고 출력. x가 nil이면 이 블록은 실행되지 않음.
}
// 강제 언래핑을 사용하여 x의 문자열 길이를 구함
let b = x!.count // x!를 통해 강제 언래핑. x가 nil일 경우 런타임 에러 발생.
print(type(of:b), b) // b의 타입(Int)과 값을 출력.
// 옵셔널 체이닝을 사용하여 x의 문자열 길이를 안전하게 구함
let b1 = x?.count // x?를 통해 옵셔널 체이닝. x가 nil이면 b1도 nil.
print(type(of:b1), b1, b1!) // b1의 타입(Optional<Int>), 옵셔널 값, 강제 언래핑된 값을 출력.
// nil 병합 연산자를 사용하여 x의 값을 안전하게 언래핑하거나 기본값 제공
let c = x ?? "" // x가 nil이 아니면 x의 값을 사용, nil이면 빈 문자열("")을 사용.
print(c) // c의 값을 출력.
출처
- Smile Han의 iOS 프로그래밍 실무, 한성현(출판 예정), PPT로 제공
- Do it! 스위프트로 아이폰 앱 만들기 입문(개정 7판)(이지스퍼블리싱,송호정, 이범근, 2023.1)
- 핵심만 골라 배우는 SwiftUI 기반의 iOS 프로그래밍(제이펍, 닐 스미스, 2023.12)
- https://www.techotopia.com/index.php/IOS_iPhone_iPad_eBooks
- 스위프트 프로그래밍(Swift 5) 3판(한빛미디어, 야곰, 2019.10)
- 꼼꼼한 재은 씨의 스위프트 기본편 (루비페이퍼, 이재은, 2018.05)
- 꼼꼼한 재은 씨의 스위프트 실전편 (Swift) (루비페이퍼, 이재은, 2018.08)
- 꼼꼼한 재은 씨의 Swift 문법편 (루비페이퍼, 이재은, 2017.12)