1
// 如何通过xib创建控制器
1.创建Xib文件
2.xib文件要有一个view描述控制器
3.连线,告诉xib描述哪个控制器,设置文件拥有者为控制器
4.调用initWithNibName创建控制器
ViewController *vc = [[ViewController alloc] initWithNibName:@"VC" bundle:nil];
self.window.rootViewController = vc;
/*
开发中,控制器的xib的名称一般不会乱取,一般都会用控制器的类名作为xib的名称,有什么好处,只要调用init,直接就会去加载根控制器类名同名的xib.
*/
2
//创建控制器调用的一些方法init initWithNibName (底层做的一些事情)
XMGViewController *vc = [[XMGViewController alloc] init];
// init底层调用initWithNibName
// initWithNibName:底层做了一些事情
// 1.判断有没有指定nibName,指定了,就会加载,若果没有指定 即nil会执行2
// 2.判断下有没有跟控制器类名同名的xib但是不带controller,如果有,就直接加载
// 3.判断下有没有跟控制器类名同名的xib,如果有,就直接加载
3
// 创建一个空的view
1.空 != 黑色 [UIColor blackColor];
2.空 != 完全透明 vc.view.alpha = 0;
3.空 == 几乎透明 [UIColor clearColor]
ViewController *vc = [[ViewController alloc] init];
// 透明,如果控制器的view完全透明,里面的可以点击
// vc.view.alpha = 0;
vc.view.backgroundColor = [UIColor clearColor];
self.window.rootViewController = vc;
4
//控制器的view加载方式是懒加载,解析
- (UIView *)view
{
if (_view == nil) {
[self loadView];
[self viewDidLoad];
}
return _view;
}
5
//viewDidLoad
控制器的view加载完成的时候调用
6
//loadView
在开发中,如果重写loadView,内部就不会调用[super loadView]
在开发中,只要重写了loadView,表示不需要系统帮我们创建控制器的view,需要自定义控制器的view
需求:一开始就想要控制器的view显示一张图片,解决:让控制器的view直接成为UIImageView
使用loadView注意点
1.在没有给控制器的view赋值之前,不能调用控制器的view的get方法.会发生死循环。
7
//UIPickerView
#pragma mark - UIPickerViewDataSource
// 返回有多少列
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *){}
// 返回第component列有多少行
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{}
#pragma mark - UIPickerViewDelegate
// 返回每一列行高
- (CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component;
//返回第component列第row行的标题
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
//NSAttributedString:属性字符串,富文本:颜色,字体,阴影,空心,图文混排(以后研究)
- (NSAttributedString *)pickerView:(UIPickerView *)pickerView attributedTitleForRow:(NSInteger)row forComponent:(NSInteger)component
//返回每一行的控件
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view
// 选中某一行的时候调用
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
8
//UITextField一些属性、一些代理方法
让文本框不允许输入
1.设置文本框的代理
2.实现拦截输入的方法
//UITextField的一些代理方法
// 是否允许开始编辑
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
// 开始编辑的时候调用
- (void)textFieldDidBeginEditing:(UITextField *)textField
// 是否允许结束编辑
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField
// 结束编辑的时候调用
- (void)textFieldDidEndEditing:(UITextField *)textField//
// 是否允许用户在文本框上输入文字
// 作用:拦截用户的输入
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
9
//KVC底层实现
KVC字典转模型
setValuesForKeysWithDictionary底层做的事情:
/*遍历字典中的所有key,去模型中查找,有没有对应的属性,有就直接赋值.
使用KVC注意点,必须保证模型的属性名跟字典的key一一对应.
[flag setValuesForKeysWithDictionary:dict]; */
//本来是- (void)setIcon:(UIImage *)icon 可以改写成下面
- (void)setIcon:(NSString *)icon
{
_icon = [UIImage imageNamed:icon];
}
/*
[flag setValue:zhongguo.jpg @"icon"]
1.首先会去flag模型中查找有没有setIcon,有,就直接调用 [flag setIcon:zhongguo.jpg]
2.去flag模型中查找有没有icon属性,有,icon = zhongguo.jpg
3.去flag模型中查找有没有_icon属性,有,_icon = zhongguo.jpg
4.找不到,就会直接报错.[flag setValue:forUndefinedKey:]
*/
10
//自定义UIDatePicker 的初始化操作(设置日期模式datePickerMode、设置地区locale 中国,中文 zh:中国)
// 初始化操作
- (void)setUp
{
// 创建UIDatePicker
UIDatePicker *picker = [[UIDatePicker alloc] init];
_datePicker = picker;
// 设置日期模式:年月日
picker.datePickerMode = UIDatePickerModeDate;
// 设置地区:中国,中文 zh:中国
picker.locale = [NSLocale localeWithLocaleIdentifier:@"zh"];
[picker addTarget:self action:@selector(dateChange:) forControlEvents:UIControlEventValueChanged];
// 自定义键盘
self.inputView = picker;
}
11
// 把NSDate -> NSString
- (void)dateChange:(UIDatePicker *)picker
{
// 获取控件上的日期
// 把NSDate -> NSString
// 2015-09-19
// 日期格式对象
NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
fmt.dateFormat = @"yyyy-MM-dd";
self.text = [fmt stringFromDate:picker.date];
}
12
//id:可以调用任何对象的方法,只要你声明了,就能调用,不管在哪个类中声明,都可以调用
// 开始编辑的时候调用
- (void)textFieldDidBeginEditing:(id)textField
{
// 开始编辑的时候,初始化文本框的内容
// id:可以调用任何对象的方法,只要你声明了,就能调用,不管在哪个类中声明,都可以调用.
// 利用运行时特性,一个对象只会去真实的类型去找方法
// 利用编译特性,
// FlagField *field = (FlagField *)textField;
[textField initialText];
// if ([textField isKindOfClass:[FlagField class]]) { // 国旗文本框开始编辑
// // 初始化文本框的内容
// FlagField *field = (FlagField *)textField;
// [field initialText];
// }else if ([textField isKindOfClass:[BirthdayField class]]){
// // 初始化文本框的内容
// BirthdayField *field = (BirthdayField *)textField;
// [field initialText];
// }else // 城市文本框
// {
// // 初始化文本框的内容
// CityField *field = (CityField *)textField;
// [field initialText];
// }
}
13
//UIPickerView didSelectRow 里面的一些操作(UIPickerView的刷新功能、自动选中功能)
// 给文本框赋值
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
if (component == 0) { // 滚动第0列,选择省会
// 记录下选中的新的省会的角标
_selProvinceIndex = row;
// 刷新第1列
[pickerView reloadComponent:1];
// 让pickerView第1列选中第0行
[pickerView selectRow:0 inComponent:1 animated:YES];
}
// 给文本框赋值
// 获取选中的省
// 获取第0列选中的省 selProvinceIndex:第0列选中的row
Province *p = self.provinces[_selProvinceIndex];
// 获取选中的城市
// 获取第1列选中哪一行
NSInteger cityIndex = [pickerView selectedRowInComponent:1];
NSString *cityName = p.cities[cityIndex];
self.text = [NSString stringWithFormat:@"%@ %@",p.name,cityName];
}