[iOS] - PickerView

Din의 개발노트·2021년 3월 6일
0

PickerView

PickerView를 활용해서 text와 image 데이터 목록을 표시하는 방법을 알아보도록 하겠습니다.

  • Picker View를 구현할때는 모든 부분을 코드로 구현합니다.
  • 핵심은 데이터 소스와, 델리게이트 입니다.

1. Text Picker

참고 UIPickerView

DataSource

  • 반드시 필수 메소드 2개를 구현해야합니다.
    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        <#code#>
    }
    
    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        <#code#>
    }
    

Code

import UIKit

class ViewController: UIViewController {
    
 
    let uppercaseAlphabet = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K"]
    let lowercaseAlphabet = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"]
    
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

extension ViewController: UIPickerViewDataSource {
    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 2
    }
    
    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        switch component {
        case 0:
            return uppercaseAlphabet.count
        case 1:
            return lowercaseAlphabet.count
        default:
            return 0
        }
    }
}

extension ViewController: UIPickerViewDelegate {
    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        switch component {
        case 0:
            return uppercaseAlphabet[row]
        case 1:
            return lowercaseAlphabet[row]
        default:
            return nil
        }
    }
    
    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        switch component {
        case 0:
            print(uppercaseAlphabet[row])
        case 1:
            print(lowercaseAlphabet[row])
        default:
            break
        }
    }
}

2. Image Picker

import UIKit

class ViewController: UIViewController {
    
    lazy var images: [UIImage] = {
        return (1...6).compactMap { UIImage(named: "num-\($0)") }
    }()
    
    @IBOutlet weak var picker: UIPickerView!
    
    @IBAction func start(_ sender: Any?) {
        let firstIndex = Int.random(in: 0 ..< images.count)
        let secondIndex = Int.random(in: 0 ..< images.count)
        let thirdIndex = Int.random(in: 0 ..< images.count)
        
        picker.selectRow(firstIndex, inComponent: 0, animated: true)
        picker.selectRow(secondIndex, inComponent: 1, animated: true)
        picker.selectRow(thirdIndex, inComponent: 2, animated: true)
        
    }

    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

extension ViewController: UIPickerViewDataSource {
    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 3
    }
    
    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return images.count * 4 // 무한 스크롤
    }
    
}

extension ViewController: UIPickerViewDelegate {
    func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
        if let imageView = view as? UIImageView {
            imageView.image = images[row % images.count]
            return imageView
        }
        
        let imageView = UIImageView()
        imageView.image = images[row % images.count]
        imageView.contentMode = .scaleAspectFit
        return imageView
    }
    
    func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat {
        return 50
    }
}

이렇게만 하면 터치 이벤트를 사용자가 직접 제어할 수 있기때문에 터치 이벤트를 비활성화 해줘야합니다.

override func viewDidLoad() {
        super.viewDidLoad()
        // 터치 이벤트 비활성화
        picker.isUserInteractionEnabled = false
        picker.reloadAllComponents()
        start(nil)
    }

최종 Code

import UIKit

class ViewController: UIViewController {
    
    lazy var images: [UIImage] = {
        return (1...6).compactMap { UIImage(named: "num-\($0)") }
    }()
    
    @IBOutlet weak var picker: UIPickerView!
    
    @IBAction func start(_ sender: Any?) {
        let firstIndex = Int.random(in: 0 ..< images.count)
        let secondIndex = Int.random(in: 0 ..< images.count)
        let thirdIndex = Int.random(in: 0 ..< images.count)
        
        picker.selectRow(firstIndex, inComponent: 0, animated: true)
        picker.selectRow(secondIndex, inComponent: 1, animated: true)
        picker.selectRow(thirdIndex, inComponent: 2, animated: true)
        
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        // 터치 이벤트 비활성화
        picker.isUserInteractionEnabled = false
        picker.reloadAllComponents()
        start(nil)
    }
}

extension ViewController: UIPickerViewDataSource {
    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 3
    }
    
    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return images.count * 4 // 무한 스크롤
    }
    
}

extension ViewController: UIPickerViewDelegate {
    func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
        if let imageView = view as? UIImageView {
            imageView.image = images[row % images.count]
            return imageView
        }
        
        let imageView = UIImageView()
        imageView.image = images[row % images.count]
        imageView.contentMode = .scaleAspectFit
        return imageView
    }
    
    func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat {
        return 50
    }
}

슬롯머신 구현

import UIKit

class ViewController: UIViewController {
    
  
    @IBOutlet weak var picker: UIPickerView!
    @IBOutlet weak var btn: UIButton!
    
    
    lazy var list: [UIImage] = {
        return (0...7).compactMap { UIImage(named: "0\($0)") }
    }()
    
    func win() {
        var set = Set<Int>()
        
        (0...2).forEach {
            set.insert(picker.selectedRow(inComponent: $0) % list.count)
        }
        
        if set.count == 1 {
            print("WIN")
        }
    }
    
    func shuffle(animated: Bool = true) {
        for index in 0 ... 2 {
            picker.selectRow(500 + Int.random(in: -100...100), inComponent: index, animated: animated)
        }
    }
    
    @IBAction func start(_ sender: Any?) {
        win()
        shuffle()
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        picker.isUserInteractionEnabled = false
        picker.reloadAllComponents()
        start(nil)
        btn.titleLabel?.font = UIFont.systemFont(ofSize: 50)
       
    }
}

extension ViewController: UIPickerViewDataSource {
    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 3
    }
    
    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return 1000
    }
    
}

extension ViewController: UIPickerViewDelegate {
    func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
        if let imageView = view as? UIImageView {
            imageView.image = list[row % list.count]
            return imageView
        }
        
        let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 50, height: 50))
        imageView.image = list[row % list.count]
        return imageView
    }
    
    func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat {
        return 50
    }
    
    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        print(component, row)
    }
}

profile
iOS Develpoer

0개의 댓글