3.19 데이터소스

Jay·2025년 2월 6일

Level 3 - SingleView App

목록 보기
19/24

Goal

뷰의 정보를 담는 DistanceRange 모델을 생성하고 UIPickerDataSource로 지정해보기.

Meterials

Class NSObject
: Objective-C 클래스의 최상위 루트 클래스

Thinking First

이전 챕터에서 메서드를 별도의 모델로 분리해보았다. 이번엔 데이터소스를 담은 정보를 별도의 모델로 분리해 보자. 현재 뷰컨트롤러는 UIPickerViewDataSource 로서 distanceValues 라는 프로퍼티를
관리하고 있다. 새로운 클래스를 생성하여 UIPickerViewDataSource 로 지정해 보자.

뷰컨트롤러를 UIPickerDatsSource로 지정할 때 작업내용을 떠올려 보고 변경하면 된다.

Making Next

//DistanceRange.swift 

import UIKit        //UIPickerViewDataSource  프로토콜을 채택하기 위해 UIKit을 import  한다.

class DistanceRange: NSObject, UIPickerViewDataSource {     

NSObject를 상속하고 UIPickerViewDataSource 를 채택한다. UIPickerViewDataSource 는 NSObjectProtocol 을 준수하는 클래스로서 기본적으로 Objective-C 언어의 기반을 두고 있는데 이러한 프로토콜을 채택하려면 NSObject 를 먼저 상속해야 함을 기억해두자.
NSObject 클래스는 대부분의 클래스의 뿌리가 되는 기본 클래스로 알아두면 되는데 뷰컨트롤러는 UIViewController 를 상속받고 이때 UIViewController가 NSObject 를 상속하므로 따로 명시할 필요가 없었지만 DistanceRange 클래스는 UIViewController 클래스를 상속하지 않으므로 명시적으로 NSObject 를 상속받아야 한다.

let values = (1...100).map { $0 }

다른 파일에서도 이 클래스에 접근해야 하기 때문에 private 키워드를 삭제한다.
이제 DistancRange 클래스 안으로 들어왔으므로 distanceValues 를 values로 줄였다. 이름은 용도를 알 수 있는 범위내에서 최대한 간결한것이 좋다.

UIPickerViewDataSource로서 아래 메서드를 구현해야 하므로 뷰컨트롤러의 코드를 옮긴다.


func numberOfComponents(in pickerView: UIPickerView) -> Int {
       return 1   
}       

func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
       return values.count       //  위 프로퍼티 이름과 동일하게 변경한다.
}

이제 뷰컨트롤러 클래스를 변경해야 한다.

// UIPickerViewDataSource 삭제   
class ViewController: UIViewController, UIPickerViewDelegate {   

@IBOutlet var distanceRange: DistanceRange!    //  인터페이스빌더에서 DistanceRange 객체의 아웃렛을 생성한다.

	func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {               
    	let kmeterValue = distanceRange.values[row]      // 변경
		return "\(kmeterValue)km"   
		}      

	func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {       
		let kmeter = distanceRange.values[row]           // 변경
		distanceLabel.text = "\(converter.toMile(kilo:kmeter))mile"   
		}
profile
Software Engineer Specialized on iOS

0개의 댓글