UIPickerView基本使用
控件PickerView,拖线
-
设置数据源,设置代理
- self.pickView.dataSource = self
- self.pickView.delegate = self
-
遵守协议
- UIPickerViewDataSource
- UIPickerViewDelegate
-
实现数据源方法
- 共有多少列:numberOfComponentsInPickerView:
- 每一列有多少行:numberOfRowsInComponents:
-
实现代理方法
- widthForComponents:每一列的宽度
- rowHeightForComponents:每一行的行高
- titleForRow:forComponent:每一列的每一行展示什么标题
- pickerView:attributeedTitleForRow:forComponent:每一列的每一行展示带有属性的标题(属性:文字的大小颜色)
- pickerView:viewForRow:forComponent:reusingView:每一列的每一行展示视图
- pickerView:didSelectedRow:inComponent:当选中某一列的某一行的时候会自动调用
-
展示数据
- 定义数据的数组属性,懒加载
- 获取plist路径
- 从路径当中加载数组
-
Label展示选中的数据
- didSelectedRow:InComponent:
- 设置默认
自定义键盘
搭建界面
-
textField,只能选择,不能输入(拦截用户输入)
- 拦截文本框,设置textField代理
- 设置代理,self.countryTextF.delegate = self
- 遵守协议<UITextFieldDelegate>
- 实现代理方法
- textFieldShouldBeginEditing:是否允许开始编辑 YES
- textFieldDidBeginEditing:开始编辑的时候调用,成为第一响应者弹出键盘
- textFieldShouldEndEditing:是否允许结束编辑,如果设置为NO,就出不来了,所以要设置为YES
- textFieldDidEndEditing:当结束编辑的时候调用
-
textField:shouldChangeCharactersInRange:replacementString:
是否允许改变字符,NO
-
点击textField弹出自定义的键盘
- show in finder -> 新建文件夹 -> 把文件夹拖到工程里面 ->创建自定义类
- 从storyboard或者xib绑定类的,加载完毕后,都会调用awakeFromNib方法
- 修改键盘类型self.inputView输入的视图,默认是系统的键盘
- 创建pickerView:alloc/init
- 设置pickView的数据源和代理,遵守协议
- 实现pickerView代理方法
- self.inputView = pickerView
-
通过代码,弹出pickerView,封装的思想
- 重写initWithFrame:方法
- 设置pickView的数据源和代理,遵守协议
- 实现pickerView代理方法
- self.inputView = pickerView
注意
:在同一个类中,把相同的代码,写到同一个方法当中,减少代码量,高内聚-
pickerView内部展示国旗数据
- 创建模型,加载plist文件,字典转模型
- 验证数据是否加载成功
- 列数:1
- 行数:self.flagArray.count;
- 每一行展示的UIView:pickerView:viewForRow:forComponent:reusingView:
- xib描述view
- 绑定view的类
- 创建flagView
- loadNibName:owner:options:
- [0]
- xib描述view
- 取出数据,把数据给view,让view展示数据
- 取出模型
- flagV中提供一个模型
- return flagView;
-
设置行高
- pickerView:rowHeightForComponent:
-
KVC的底层实现
- 拿字符串与当前类的属性进行匹配,如果匹配到,就给该属性赋值。
- setValuesForKeyWithDictionary:
- 遍历字典[dict enumerateKeysAndObjectsUsingBlock:^(){
内部调用setValue:obj ForKeyPath:key
1.去找有没有跟key值相同名称的set方法,就会调用set方法,把obj传入
2.如果没有set方法,那么它会去找有没有相同名称并且带有下划线的成员属性,如果有就会给该属性赋值
3.如果也没有带有下划线的成员属性,有没有跟它相同名称的成员属性
4.如果还没有跟它相同名称的成员属性,就会调用setValueForUndefinedKey:
5.如果没有实现setValueForUndefinedKey:就直接报错
}]
-
KVO的底层实现
- 耗性能,少用KVO
- 原理:监听某个属性值的改变
- 在运行的过程中派生一个类,在这个类中,有一个属性,就是你要监听的属性,会在属性里重写set方法,在set方法内部,调用obsever的方法
-
代码优化
- 不要在view里面进行逻辑运算,把运算写到模型里面,赋值的时候,直接赋值,比如icon赋值
- 重写icon的set方法
- (void)setIcon:(UIImage *)icon{
if ([icon isKindOfClass:[NSSting class]]){
UIImage *image = [UIImage imageNamed:(NSString*)icon];
_icon = image;
}else{
_icon = icon;
}
}
- 滚动过程中,把国家显示到文本框中
- 代理didSelectRow:
- 取出当前模型
- self.text = item.name;
UIDatePicker
- 生日键盘
- 自定义键盘
- awakeFromNib
- ininWithFrame:
- 修改键盘类型
- UIDatePicker
- 修改日期模式
- .datePickerMode = ModeDate
- 修改地区
- .locale = [NSLocale localeWithLocalIdentifier:@"zh"]
- iso编码
- 滚动过程当中,把日期显示到文本框中去
- UIDatePicker没有代理
- target:继承UIControl
- pickView addTarget:action:forControlEvent:
- 事件类型:可以通过拖线的方式,看event有哪些
- 获取当前datepick的日期
- NSDate * currentDate = datepick.date
- 把日期转成字符串
- NSDateFormatter alloc/init
- .dateFormat= @"yyyy-MM-dd"
- stringFromDate:
- 给当前文本框赋值
- self.text = dateString
城市键盘
- 自定义textField
- awakeFromNib
- initWithFrame:
- 设置代理
- 遵守协议
- 实现代理方法
- 展示数据
- 创建模型
- 懒加载
- 字典转模型
- 数据源代理方法
两列
-
第0列有多少行
- self.proviceArray.count
-
第1列有多少行
- 定义一个属性,记录当前选中的是哪个省份
- 取出模型self.proviceArray[self.provinceIndex]
- 当前选中省份下,城市的个数
- provinceItem.cities.count;
-
每一列每一行展示什么内容
- 第0列:返回省份的名称
- 省模型:self.provinceArray[row]
- return item.name
- 第1列:选中省份下城市的名称
- self.provinceArray[self.provinceIndex]
- return provinceItem.cities[row];
- 滚动省份,变化城市名称
- didSelectRow:
- 滚动第0列开始做处理
- 更新index
- self.provinceIndex = row
- 变数据,刷新列表(重新调用数据源代理方法)
- reloadAllComponents
- 当滚动完毕之后,让第一列选中第0行
- selectRow:inComponent:animated:
- 省份的名称和城市的名称显示到textF中
- 省份的模型self.provinceArray[self.provinceIndex]
- provinceItem.name;
- 获取当前选中省份下,当前选中的城市
- 获取当前第一列选中的是哪一行
- 获取第一列行号
- rowIndex = selectedRowInComponent:1
- provinceItem.cities[rowIndex]
- 拼接
- stingWithFormat:%@-%@