当前位置: > > > Swift - 选择框(UIPickerView)的用法

Swift - 选择框(UIPickerView)的用法

(本文代码已升级至Swift4)

1,基本用法

选择框可以让用户以滑动的方式选择值。示例如下:
import UIKit

class ViewController:UIViewController, UIPickerViewDelegate, UIPickerViewDataSource{
    
    var pickerView:UIPickerView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        pickerView = UIPickerView()
        //将dataSource设置成自己
        pickerView.dataSource = self
        //将delegate设置成自己
        pickerView.delegate = self
        //设置选择框的默认值
        pickerView.selectRow(1,inComponent:0,animated:true)
        pickerView.selectRow(2,inComponent:1,animated:true)
        pickerView.selectRow(3,inComponent:2,animated:true)
        self.view.addSubview(pickerView)
        
        //建立一个按钮,触摸按钮时获得选择框被选择的索引
        let button = UIButton(frame:CGRect(x:0, y:0, width:100, height:30))
        button.center = self.view.center
        button.backgroundColor = UIColor.blue
        button.setTitle("获取信息",for:.normal)
        button.addTarget(self, action:#selector(ViewController.getPickerViewValue),
                         for: .touchUpInside)
        self.view.addSubview(button)
    }
    //设置选择框的列数为3列,继承于UIPickerViewDataSource协议
    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 3
    }
    
    //设置选择框的行数为9行,继承于UIPickerViewDataSource协议
    func pickerView(_ pickerView: UIPickerView,
                    numberOfRowsInComponent component: Int) -> Int {
        return 9
    }
    
    //设置选择框各选项的内容,继承于UIPickerViewDelegate协议
    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int,
                    forComponent component: Int) -> String? {
        return String(row)+"-"+String(component)
    }
    
    //触摸按钮时,获得被选中的索引
    @objc func getPickerViewValue(){
        let message = String(pickerView.selectedRow(inComponent: 0)) + "-"
            + String(pickerView!.selectedRow(inComponent: 1)) + "-"
            + String(pickerView.selectedRow(inComponent: 2))
        let alertController = UIAlertController(title: "被选中的索引为",
                                                message: message, preferredStyle: .alert)
        let okAction = UIAlertAction(title: "OK", style: .cancel, handler: nil)
        alertController.addAction(okAction)
        self.present(alertController, animated: true, completion: nil)
    }
}

2,调整选择框的尺寸

UIPickerView frame center 两个属性设置整个选择框的大小和位置。
如果要调整内部列的宽度,需要实现 UIPickerViewDelegate 协议类中 pickerView:widthForComponent 方法设置
如果要调整内部行高,则需要实习上述协议类中 pickerView:rowHeightForComponent 方法设置
//设置列宽
func pickerView(_ pickerView: UIPickerView, widthForComponent component: Int) -> CGFloat {
    if(0 == component){
        //第一列变宽
        return 100
    }else{
        //第二、三列变窄
        return 30
    }
}

//设置行高
func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int)
    -> CGFloat {
    return 50
}

3,将图片作为选择框选项

选择框选项的内容,除了可以使字符串类型的,还可以是任意UIView类型的元素。比如我们将选项内容设置为图片:
func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int,
                reusing view: UIView?) -> UIView {
    let image = UIImage(named:"icon_"+String(row))
    let imageView = UIImageView()
    imageView.image = image
    return imageView
}

4,检测响应选项的选择状态

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int,
                inComponent component: Int) {
    //将在滑动停止后触发,并打印出选中列和行索引
    print(component)
    print(row)
}

5,修改选项的字体大小和颜色

func pickerView(_ pickerView: UIPickerView, viewForRow row: Int,
                forComponent component: Int, reusing view: UIView?) -> UIView {
    var pickerLabel = view as? UILabel
    if pickerLabel == nil {
        pickerLabel = UILabel()
        pickerLabel?.font = UIFont.systemFont(ofSize: 13)
        pickerLabel?.textAlignment = .center
    }
    pickerLabel?.text = String(row)+"-"+String(component)
    pickerLabel?.textColor = UIColor.blue
    return pickerLabel!
}
评论6
  • 6楼
    2018-01-08 13:55
    小豪

    航歌,这个能设置内容多行显示吗?毕竟有些内容太长显示不全。。。

    站长回复

    可以通过自定义选项视图实现,具体参考文章第5条内容。

  • 5楼
    2016-08-06 17:05
    YZStyle

    航哥,怎么改变pickerview每一列“显示的”行数(不是总的行数)。

    站长回复

    好像没有直接设置显示行数的办法。你可以通过设置整个pickerview的尺寸,以及单元格的高度。变相地来改变显示的行数。不过这样对所有的列都生效,没发每个列都设置显示不同的行数。

  • 4楼
    2016-07-28 09:30
    LMD

    触摸按钮时,能不能直接获取被选中的内容;

    站长回复

    通常都是把数据源放在一个集合或者数组里,通过选中项的索义取得对应的数据。

  • 3楼
    2016-07-19 17:24
    酒剑仙

    报错
    /Users/wangjian/Desktop/testwj/testwj/LoginViewController.swift:6:7: Type 'LoginViewController' does not conform to protocol 'UIPickerViewDataSource'

    站长回复

    看提示是你有UIPickerViewDataSource的协议方法没实现。

  • 2楼
    2016-05-04 19:40
    was

    请问做成省份和城市的两个pickerview,做出选择省份城市自动更新的效果该怎么做?

    站长回复

    在didSelectRow方法中根据选择项,刷新数据源数据,然后调用pickerview的reloadComponent()方法重新加载下数据就可以了。

  • 1楼
    2016-03-03 15:58
    罗哈哈

    请问下站长第二个的第三行的 00 是什么意思

    站长回复

    那个是0,原来多敲了一个0,现已修正。