Android里面有下拉列表控件,但是iOS里面没有下拉列表,可以使用滚轮控件(UIPickerView
)来实现这种功能。
使用滚轮控件UIPickerView类似于使用UITableView,需要实现两个代理UIPickerViewDelegate
和UIPickerViewDataSource
里面的方法。可以看官网的文档
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView;
用来设置有几个滚轮。(日历控件一般是三个滚轮,而我要实现下拉列表的话,一个滚轮就行。)
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component;
表示某个滚轮里面有多少行。
- (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component;
设置滚轮的宽度。
- (CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component;
设置滚轮每行的高度。
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component;
选择了某行后会触发这个方法。
- (nullable NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component;
某个滚轮内某行的内容。一般是一个字符串。
还有其他方法,我暂时用不到,以后再写。
把UIPickerView关联到UITextField里
希望当UITextField成为firstResponser的时候,弹出UIPickerView。需要把self.textField.inputView = pickerView;
我在这里遇到了一个问题:
Terminating app due to uncaught exception 'UIViewControllerHierarchyInconsistency', reason: 'child view controller:<UICompatibilityInputViewController: 0x15ef8c80> should have parent view controller:<InstallThirdVC: 0x15ddaae0> but requested parent is:<UIInputWindowController: 0x16a14400>'
后来在网上看见人说,在执行self.textField.inputView = pickerView;
之前,需要让[pickerView removeFromSuperview]
,结果还是报错!!!😭
后来,终于找到问题出在哪儿了。原来我使用xib创建布局的时候,把UIPickerView作为子视图添加到了布局上面,后来又IBOutlet它,即使removeFromSuperview也然并卵。
不报错的做法应该是这样:
1.首先还要设置UITextFieldDelegate
,即self.textField.delegate = self;
,这样就能后在输入框被编辑的时候获取到相关方法。如果不设置这句,那么就不会触发UITextFieldDelegate里面的方法。
2.把xib中UIPickerView删掉。
3.实现UITextFieldDelegate
里面的-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField
这个方法。在toolbar上放一个按钮,表示选中滚轮里面的某个值。
-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
UIPickerView *pickerView = [[UIPickerView alloc] init];
[pickerView sizeToFit];
pickerView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
pickerView.delegate = self;
pickerView.dataSource = self;
pickerView.showsSelectionIndicator = YES;
textField.inputView = pickerView;
UIToolbar* keyboardDoneButtonView = [[UIToolbar alloc] init];
keyboardDoneButtonView.barStyle = UIBarStyleDefault;
[keyboardDoneButtonView sizeToFit];
UIBarButtonItem* doneButton = [[UIBarButtonItem alloc] initWithTitle:@"确定" style:UIBarButtonItemStylePlain target:self action:@selector(pickerDoneClicked)] ;
[keyboardDoneButtonView setItems:[NSArray arrayWithObjects:doneButton, nil]];
textField.inputAccessoryView = keyboardDoneButtonView;
return YES;
}
当点击toolbar上的“确定”按钮后,会触发pickerDoneClicked
方法,在这个方法里面让[self.textField resignFirstResponder];
就能收起滚轮。
加入滚轮里面的内容是从网络获取,而不是固定的值,那么在获取到值之前,可以在-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField
里return NO;
,那么textField就不会进入编辑状态,也就不会弹出滚轮。
UIPickerView默认是在bottom的位置,当然你也可以在代码中设置它的位置
showsSelectionIndicator
这个属性从iOS7之后就不起作用了,在低版本iOS里面表示是否显示一个蓝色的选中框。在iOS7之后总是显示透明的选中框。
自定义UIPickerView里面的cell,修改分割线的颜色
可以遍历pickerView的subView,找到分割线,修改其颜色
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view {
//设置分割线的颜色
for(UIView *singleLine in pickerView.subviews)
{
//实际是两个高位0.5的分割线
if (singleLine.frame.size.height < 1)
{
singleLine.backgroundColor = [UIColor redColor];
}
}
UIView * v = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 50)];
v.backgroundColor = [UIColor yellowColor];
UILabel * label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 50, 50)];
label.text = @"123456";
label.textColor = [UIColor blackColor];
[v addSubview:label];
return v;
}
调用[self.pickerView selectRow:1 inComponent:0 animated:YES];
可以让滚动器直接滚动到指定位置,但是不会触发didSelecteRow方法