Android里面有下拉列表控件,但是iOS里面没有下拉列表,可以使用滚轮控件(UIPickerView)来实现这种功能。

使用滚轮控件UIPickerView类似于使用UITableView,需要实现两个代理UIPickerViewDelegateUIPickerViewDataSource里面的方法。可以看官网的文档

- (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],结果还是报错!!!😭

wtf

后来,终于找到问题出在哪儿了。原来我使用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 *)textFieldreturn 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方法