수학적 접근

[Xcode/Swift] 화면 아래에 표시되는 PickerView 만들기 본문

개발/iOS

[Xcode/Swift] 화면 아래에 표시되는 PickerView 만들기

평등수렴 2020. 2. 4. 17:56
반응형

이 글에서는 다음과 같이 화면 아래쪽에 picker가 표시되는 형태의 PickerView를 만들어볼 것입니다.

Xcode에서 기본적으로 제공하는 UITextField 을 이용하여 구성해보겠습니다.

 

우선, Main.storyboard의 원하는 SceneUITextField 하나를 삽입합니다.

 

저는 프로젝트를 처음 만들었을 때 생성되는 ViewController Scene 에서 작업하고 있습니다.

 

위와 같이 UI를 만든 뒤, cene과 연결된 ViewControllerCtrl + 드래그 하여 코드를 삽입합니다.

 

이름은 showPicker 로 하였습니다.

그리고 PickerView를 사용하기 위해 UITextFieldDelegate, UIPickerViewDelegate,

 

UIPickerViewDataSource 인터페이스를 ViewController에 포함시킵니다.

 

import UIKit

class ViewController: UIViewController, UITextFieldDelegate, UIPickerViewDelegate, UIPickerViewDataSource {

    @IBOutlet weak var showPicker: UITextField!
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }
}

 

그리고 PickerView에 들어갈 자료를 다음과 같이 정의해놓겠습니다.

let fruits = ["사과", "배", "포도", "망고", "딸기", "바나나", "파인애플"]

 

그리고 위 인터페이스들을 implement하기 위해서는 다음과 같은 메소드를 재정의해야합니다.

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

}


func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {

}


func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {

}


func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {

}

 

 

그럼 각 메소드에 대해 위에서부터 하나하나 살펴보겠습니다.

 

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

numberOfComponents() 메소드에서는 하나의 PickerView 안에 몇 개의 선택 가능한 리스트를 표시할 것인지를 정합니다.

 

예를 들어 생년월일을 결정하기 위해서는

 

'연도'에 해당하는 리스트에서 하나,

'월'에 해당하는 리스트에서 하나,

'일'에 해당하는 리스트에서 하나를 정해야 합니다.

 

이를 하나의 각각의 PickerView에 나타낼 수도 있지만, 하나의 PickerView에 나타낸다면,

이 메서드에서는 3을 반환하여 세 가지 리스트가 하나의 PickerView에 나타나도록 할 수 있습니다.

 

하지만 이 예제에서는 하나짜리를 보여드리고 있기 때문에, 1로 두고 진행할 것입니다.

 

 

 

func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return fruits.count
}

PickerView에 표시될 항목의 개수를 반환하는 메서드입니다.

여기서는 우리가 보여주기로 결정한 fruits 리스트의 길이를 반환하고 있습니다.

 

 

 

 

func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
       return fruits[row]
}

PickerView 내에서 특정한 위치(row)를 가리키게 될 때, 그 위치에 해당하는 문자열을 반환하는 메서드입니다.

여기서는 fruits의 row 번째 문자열을 반환하게 됩니다.

 

 

 

 

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
    showPicker.text = fruits[row]
}

PickerView 에서 특정 row가 focus되었을 때 어떤 행동을 할지 정의하는 메서드입니다.

여기서는 showPicker 텍스트필드의 텍스트를 선택된 문자열로 바꾸도록 하였습니다.

그리고 실제로 PickerView를 사용하기 위해, 사용자 정의 메서드를 두 개 만듭니다.

 

 

 

 

func createPickerView(tagNo : Int) {
    let pickerView = UIPickerView()
    pickerView.delegate = self
    showPicker.inputView = pickerView
}

PickerView의 인스턴스를 생성하여, showPicker 텍스트필드를 눌렀을 때 뜨는 뷰(inputView)에 생성한 인스턴스를 연결시키는 메서드입니다.

 

 

 

 

func dismissPickerView() {
        let toolBar = UIToolbar()
        toolBar.sizeToFit()
        let button = UIBarButtonItem(title: "선택", style: .plain, target: self, action: #selector(self.action))
        toolBar.setItems([button], animated: true)
        toolBar.isUserInteractionEnabled = true
        showPicker.inputAccessoryView = toolBar
}

PickerView의 내부를 정의하는 코드와 및 PickerView가 화면에서 사라질 때 동작하는 코드를 정의하는 메서드입니다.

각 코드가 어떤 기능을 하는지는 예제 사진과 대조하여 확인해주시면 됩니다.

위 두 메서드를 viewDidLoad() 메서드에서 호출합니다.

 

 

 

 

override func viewDidLoad() {
    super.viewDidLoad()

    createPickerView()
    dismissPickerView()

}

이 상태에서 앱을 실행시키면 아래와 같이 잘 동작하는 PickerView가 만들어져 있는 것을 확인할 수 있습니다.

하지만 실행해서 테스트해보았을 때 한 가지 거슬리는 점이 있을 것입니다.

 

이 UI는 기본적으로 UITextField로부터 만들어진 UI이기 때문에, UI에 나타난 텍스트 뒤에 깜빡이는 커서가 보일 것입니다.

 

이것은 다음과 같이 코드로 해결해줄 수 있습니다.

showPicker.tintColor = .clear

위 코드를 viewDidAppear() 메서드에 삽입합니다.

 

좀더 그럴듯해 보이는 UI를 만들기 위해 가운데 정렬, 배경색, 텍스트필드의 모양 등 필요한 설정을 해 줄 수도 있습니다.

 

 

 

모든 작업이 완료된 후 ViewController.swift 의 코드는 아래와 같습니다.

import UIKit

class ViewController: UIViewController, UITextFieldDelegate, UIPickerViewDelegate, UIPickerViewDataSource {

    let fruits = ["사과", "배", "포도", "망고", "딸기", "바나나", "파인애플"]

    @IBOutlet weak var showPicker: UITextField!
    override func viewDidLoad() {
        super.viewDidLoad()

        showPicker.tintColor = .clear
        createPickerView()
        dismissPickerView()
    }


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


    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return fruits.count
    }


    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
       return fruits[row]
    }


    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        showPicker.text = fruits[row]
    }


    func createPickerView() {
        let pickerView = UIPickerView()
        pickerView.delegate = self
        showPicker.inputView = pickerView
    }

    func dismissPickerView() {
        let toolBar = UIToolbar()
        toolBar.sizeToFit()
        let button = UIBarButtonItem(title: "선택", style: .plain, target: self, action: #selector(self.action))
        toolBar.setItems([button], animated: true)
        toolBar.isUserInteractionEnabled = true
        showPicker.inputAccessoryView = toolBar
    }
}

 

필요하신 분들을 위해 해당 프로젝트를 github에 올려놓겠습니다.

 

 

dmseo1/dm-tisrory-ios-pickerview

Contribute to dmseo1/dm-tisrory-ios-pickerview development by creating an account on GitHub.

github.com

 

 

+++++

 

내가 마시고 있는 생수는 안전한 생수일까?

15년도부터 생수 수질기준 부적합 판정을 받은 이력을 확인할 수 있는 앱, <바른생수>를 출시하였습니다.

 

관심 한번씩만 부탁드립니다 ^^

 

바로가기!

 

 

반응형

'개발 > iOS' 카테고리의 다른 글

[Xcode/Swift] AutoLayout에서 UIScrollView 다루기  (2) 2020.02.05
Comments