iOS Swift UIPickerView 使用记录(制作时间选择器)
UIPickerView的使用
项目中想实现一个日期选择器的效果,但普通的UIDatePickerView不能满足实际的应用,比如中间的选择框颜色调节,选择列的弯曲度调节等等,因此采用UIPickerView来实现。
一些基本应用(苹果官方手册中)
此处记录一些常用的苹果官方提供的属性修改接口:
1.在视图选取器中选择行
func selectRow(Int, inComponent: Int, animated: Bool)
在选取器视图的指定组件中选择一行。
func selectedRow(inComponent: Int) -> Int
返回给定组件中选定行的索引。
2.重新加载视图选择器
func reloadAllComponents()
重新加载选择器视图的所有组件。
func reloadComponent(Int)
重新加载选择器视图的特定组件。
3.获取视图选择器的尺寸
var numberOfComponents: Int
选择器视图的组件数。
func numberOfRows(inComponent: Int) -> Int
返回组件的行数。
func rowSize(forComponent: Int) -> CGSize
返回组件的行大小。
4.为选取器视图提供计数
func numberOfComponents(in: UIPickerView) -> Int
在需要组件数量时由选取器视图调用。必需的。
func pickerView(UIPickerView, numberOfRowsInComponent: Int) -> Int
Called by the picker view when it needs the number of rows for a specified component.
必需的。
参考链接: 苹果官方手册链接.
UIPickerView的中间选择框问题
在ios14前,UIPickerView的选择框默认中间有两条选择线
在ios14后,UIPickerVIew的选择框变为灰色的矩阵
在ios14前,选择框的两条线分别对应subviews[1]和subviews[2],在ios14后,选择框的灰色区域对应subviews[1],因此可以通过如下代码进行修改:
//隐藏中间两条分割线
if pickerView.subviews.count > 2{
pickerView.subviews[1].isHidden = true
pickerView.subviews[2].isHidden = true
}else{
pickerView.subviews[1].backgroundColor = .clear
}
//修改选中行的背景色
for subView in pickerView.subviews {
if subView.subviews.count != 0 {
let contentViews = subView.subviews[0]
for rowView in contentViews.subviews {
if rowView.center.y == contentViews.center.y {
//背景view
rowView.backgroundColor = .clear
break
}
}
break
}
}
同样的为满足需求,可以在UIPickerView外层套一个UIView视图,使其达到中间选择框的效果。
参考链接: 中间选择框的颜色分割线等的更改.
UIPickerView的两边列弯曲问题
原理: 苹果系统原生的UIPickerView和UIDataPickerView类似若添加较多列后,左右两边的列会自带弯曲效果,这个效果改动起来较为困难,因此为了实现多列竖直的效果,此处采用了定义多个PickerView共同联动的效果,以达到垂直排列,在多列UIPickerView的代理方式和一个PickerView的方式相似,比如定义YearPickerView、MonthPickerView以及DayPickerView三个UIPickerView:
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
//根据列、行索引判断需要改变数据的区域
if pickerView == YearPickerView{
//dosomething
return 1
}else if pickerView == MonthPickerView{
//dosomething
return 2
}else{
//dosomething
return 3
}
return 1
}
Row选项无限滚动问题
原理: 此实现较为简单,本质逻辑是给PickerView的行赋值的数据源非常庞大,PickerView的行数非常多,在开始的时选择栏置于数据源中部,以至于用户无法一下滑到底部,并在用户停止滑动时,将选择栏重新返回中部,并关闭此处的动画效果,以实现视觉上的无限滚动效果。
for year in 1900 ... 2100 {Year.append(year)}
for _ in 1 ... 1000 {Yearshow += Year} //Yearshow是重复1000次的大数组
YearIndex = SelectedYear - Year[0] + Yearshow.count/2 //设定Index位于数组中部
参考链接: 实现单列PickerView的无限滚动.
时间选择器中时间的回溯
原理: 将选中的时间和今天的日期进行比较,如果选择的日期是一个未来的时间,则改变选择值
func futuredaycomeback() -> Bool {
let now = SelectedYear*1000 + SelectedMonth*100 + SelectedDay
let today = todaydate[0]*1000 + todaydate[1]*100 + todaydate[2]
if(now>today){
SelectedYear = todaydate[0]
SelectedMonth = todaydate[1]
SelectedDay = todaydate[2]
YearIndex = SelectedYear - Year[0] + Yearshow.count/2
MonthIndex = SelectedMonth - 1 + Monthshow.count/2
DayIndex = SelectedDay - 1 + Dayshow[daytypechose()].count/2
return true
}
return false
}