VesselWheel

UIPickerView와 protocol & delegate 본문

Xcode Study

UIPickerView와 protocol & delegate

JasonYang 2023. 12. 12. 17:28

Protocol UIPickerViewDelegate와 UIPikcerViewDataSource를 채택한 UIPickerView 구현 화면
protocol_ex2.xcodeproj.zip
0.01MB

 

 

 

//
//  ViewController.swift
//  UIPickerView
//
//  Created by Jason Yang on 12/12/23.
//

 import UIKit

 class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {

     let pickerView = UIPickerView() // 인스턴스화
     let data = ["Option 1", "Option 2", "Option 3"] //데이터 설정

     override func viewDidLoad() {
         super.viewDidLoad()
         setUIPickerView()
         
         func setUIPickerView() {
             let pickerView = UIPickerView()
             //ViewController에 pickerViewDelegate와 DataSource를 설정
           pickerView.delegate = self
           pickerView.dataSource = self
           pickerView.center = view.center
             self.view.addSubview(pickerView)
         }

     }

     // UIPickerViewDataSource

         /* [필수] Component 수를 보고합니다. */
         // Component는 섹션의 개념과 유사합니다. UIPickerView는 여러 열(구성 요소)을 가질 수 있습니다.
     func numberOfComponents(in pickerView: UIPickerView) -> Int {
         return 1
     }

         /* [필수] component에 따른 행 수를 보고합니다. */
         // component: 0부터 시작합니다.
     func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
         return data.count // 인스턴스 data에 3개의 components를 가져온다.
     }

     // UIPickerViewDelegate
         // 위임해서 어떤 역할을 대신해준다.
         /* row와 component조합으로 표시될 선택지를 return합니다. */
         // row: 0부터 시작합니다.
         // component: 0부터 시작합니다.
     func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
         return data[row]
     }

         /* 선택지가 선택되었을 때 호출 */
       // row: 0부터 시작합니다. / 선택된 row
         // component: 0부터 시작합니다. / 선택된 component
     func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
         print("Selected: \(data[row])")
     }
 }

 

Protocol UIPickerViewDelegate와 UIPikcerViewDataSource

- Protocol UIPickerViewDelegate를 cmd 좌클릭하거나 우클릭 Jump to Definition으로 하면 해당 protocol의 필수구현 매소드와 optional 매소드를 확인할 수 있다. 

- optional func는 선택적으로 구현하는 사항이고, 옵셔널 func가 아닌 func 매소드는 반드시 구현해야하는 매소드이다.

UIPickerViewDelegate
protocol UIPickerViewDataSource의 필수 구현 method numberOfComponents와 pickerView

 

protocol이란? 

    • 특정 역할을 하기 위한 메소드, 프로퍼티, 기타 요구사항 등을 정의 해놓은 “규약” 혹은 “약속”
    • class, structure, enum이 프로토콜을 ‘채택’하고 모든 요구사항을 충족하면 프로토콜을 ‘준수’했다고 합니다.
    • class, structure, enum이 프로토콜을 채택해서 특정 기능을 실행하기 위한 프로토콜의 요구사항을 실제로 구현할 수 있습니다.
    • 프로토콜은 설계된 조건만 정의를 하고 제시를 할 뿐 스스로 기능을 구현하지 않습니다.
    • 프로토콜에서는 이름과 타입 그리고 gettable, settable을 명시합니다
    • 프로퍼티는 항상 var로 선언해야 합니다.
    • 메서드를 정의할 때 메서드 이름과 리턴값을 지정할 수 있고, ****{}(구현 코드)는 적지 않습니다.
    • 상속과 유사하다고 볼 수도 있겠지만 class 이외에 struct나 enum도 프로토콜을 채택할 수 있다는 특징이 있습니다
    • 상속은 다중 상속이 불가능하지만 프로토콜은 다중 상속이 가능합니다(확장성이 높음)

protocol 예시

//
//  main.swift
//  protocol_ex
//
//  Created by Jason Yang on 12/13/23.
//

import Foundation

protocol Vehicle {
    var speed: Double {get set} // get, set 읽기 쓰기 모두 요구 가변 속성
    var manufacturer : String {get} // 읽기 전용 속성
}

class Car: Vehicle {
    var speed: Double = 0.0
    var manufacturer: String = "Kia"
}

class Bicycle : Vehicle {
    var speed: Double = 0.0
    var manufacturer: String {
        return "Cello"
    }
}

let car = Car() // class Car의 인스턴스 객체화
car.speed = 60.0 // set의 쓰기 가능
print(car.speed) // get의 읽기 가능  // 60.0
print(car.manufacturer) // get의 읽기 기능 // Kia

let bike = Bicycle()
bike.speed = 20.0
print(bike.speed) // 20.0
print(bike.manufacturer) // Cello
//
//  protoco_ex2.swift
//  protocol_ex
//
//  Created by Jason Yang on 12/13/23.
//

import Foundation

protocol Student {
    var studentId: Int { get set }
    var name: String { get }
    func printInfo() -> String  // printInfo() 매소드가 String을 반환
}

struct UnderGraduateStudent: Student { //구조체 UnderGraduateStudent가 Student 프로토콜을 규약
    var studentId: Int
    var name: String
    var major: String // 프로퍼티 major를 정의
    
    func printInfo() -> String {
        return "\(name), whose student id is \(studentId), is major in \(major)"
    }
}

struct GraduateStudent: Student { // 구조체 GraduateStudent가 Student 프로토콜을 규약
    var studentId: Int
    var name: String
    var degree: String
    var labNumber: Int // 프로퍼티 labNumber를 정의
    
    func printInfo() -> String {
        return "\(name), member of lab no.\(labNumber), has a \(degree) degree"
    }
}

// 프로토콜은 타입으로서도 사용가능
// 타입으로 사용한 프로토콜을 인스턴스에 지정기입한 객체화
let underGraduate: Student = UnderGraduateStudent(studentId: 1, name: "홍길동", major: "computer")
let graduate: Student = GraduateStudent(studentId: 2, name: "김철수", degree: "master", labNumber: 104)


//객체화 한 인스턴스를 배열 studentArray에 주입
let studentArray: [Student] = [underGraduate, graduate]

 

 

 

 

delegate란?

 

 

 

'Xcode Study' 카테고리의 다른 글

Counter앱 만들기  (0) 2023.12.13
디버깅  (0) 2023.12.13
Xcode 시작하기 - 화면 - Interface  (1) 2023.12.11
키오스크 프로그램에 사용된 protocol과 extension  (0) 2023.12.09
키오스크 프로그램(lv3)  (0) 2023.12.06