iOS中,在UIAcitionSheet中添加UIPickerView范例

iOS中,在UIAcitionSheet中添加UIPickerView实例
 写在之前,有些事情我们无法左右,但是至少我们可以努力去让它变得更好。我曾说过这样一句话,我可能不是最好的,但我给你的绝对是最好的。找到自己想要的东西,想过的生活,即使再艰难,也别回头看。一个人至少拥有一个梦想,有一个理由去坚强,心若没有栖息的地方,到哪里都是在流浪。                        
                                                                                                                                                         ——J!nl!n

佛祖镇楼,希望每个人开心快乐幸福。

iOS中,在UIAcitionSheet中添加UIPickerView范例

因项目需要,涉及到日期选择器和地区联动选择器。考虑到使用开源库的资源不是特别划算,于是决定自己重写一下iOS系统自身的控件。真正意义上本质也并不是重写,只是在UIAcitionSheet添加部分布局使用UIPickerFView填充。代码比较精简,但是有些地方显得很臃肿,后续随着时间的推移和技术的积累,进一步对其进行优化。此次日志只做记录,博客也会更新收集。

首先来看下一下效果图,如下:

iOS中,在UIAcitionSheet中添加UIPickerView范例iOS中,在UIAcitionSheet中添加UIPickerView范例

在这里,使用到了系统自带的UIActionSheet,熟悉iOS开发的人应该都知道。UIActionSheet是一个底部弹出的选择按钮项控件,可以添加多项,并为每项添加点击事件。它的初始化代码为:

NSString *title = UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation) ? @"\n\n\n\n\n\n\n\n\n" : @"\n\n\n\n\n\n\n\n\n\n\n\n" ;
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:title
                                                         delegate:self
                                                cancelButtonTitle:@"取消"
                                           destructiveButtonTitle:nil
                                                otherButtonTitles:@"确定",nil];
我们可以看到这里初始化了一个NSString,然后根据屏幕的横竖屏选择使用三目运算符指定填充字符串。这里只用字符\n换行符作为字符使得UIActionSheet的顶部出现一段空的布局以提供UIDatePicker和UIPickerView使用。

actionSheet.userInteractionEnabled = YES;
actionSheet.backgroundColor = [UIColor clearColor];
datePicker = [[UIDatePicker alloc] init];
datePicker.tag = 1000;
datePicker.datePickerMode = UIDatePickerModeDate;
[actionSheet addSubview:datePicker];
[actionSheet showInView:self.view];
actionSheet.tag = 100;
上述代码设置UIActionSheet可交互,背景为白色,必须设置背景色,否则可能部分机型会出现\n显示字符。然后初始化UIDatePicker并绑定tag以提供后面方法调用。紧接着设置日期格式,当然也可以是指日期时间格式。最好通过UIActionSheet的addSubView方法添加到之前我们用换行符占位的布局上,并且使用showInView显示在最上面,同样给UIActionSheet设置一个tag值标记。


以上是添加日期选择器的实现。

同理 ,地区联动也是一样的实现。不过相对比较复杂。这里不做详细介绍了。直接贴出实现部分。

plist文件就是普通的国内各省市,直辖市区县的信息,目前并不是很完善,本人地理知识有限,需要不断优化添加。
#pragma mark - 调用地区联动方法
- (void)showAreaPickerView{
    // 加载plist文件,初始化三个NSArray对象,然后做一些非法的事情,你懂的
    provinces = [[NSArray alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"area.plist" ofType:nil]];
    cities = [[provinces objectAtIndex:0] objectForKey:@"cities"];
    state = [[provinces objectAtIndex:0] objectForKey:@"state"];
    NSString *title = UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation) ? @"\n\n\n\n\n\n\n\n\n" : @"\n\n\n\n\n\n\n\n\n\n\n\n" ;
    UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:title
                                                             delegate:self
                                                    cancelButtonTitle:@"取消"
                                               destructiveButtonTitle:nil
                                                    otherButtonTitles:@"确定",nil];
    actionSheet.userInteractionEnabled = YES;
    actionSheet.backgroundColor = [UIColor clearColor];
    areaPicker = [[UIPickerView alloc] init];
    areaPicker.dataSource = self;
    areaPicker.delegate = self;
    
    [actionSheet addSubview:areaPicker];
    [actionSheet showInView:self.view];
    actionSheet.tag = 200;
}
接下来是UIPickerViewDataSource数据源方法和UIPickerViewDelegate代理方法。部分地方仍然可以精简。
// UIPickerViewDataSource中定义的方法,该方法的返回值决定改控件包含多少列
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
    return 3; // 返回3 表明什么呢?这个如果你不知道,你就别干了、、、表明该控件只包含3列,3列也就够了啊
}
// UIPickerViewDataSource中定义的方法,该方法的返回值决定该控件指定列包含多少哥列表项
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
    // 如果是第一列,返回provinces的个数
    // 也就是provinces包含多少个元素,大天朝有多少个省份里面就有多少个
    if (component == 0) {
        return provinces.count;
    } else if(component == 1){
        // 如果是第二列,返回cities的个数
        return cities.count;
    } else {
        return areas.count;
    }
}
// UIPickerViewDelegate中定义的方法,该方法返回NSString将作为UIPickerView中指定列和列表项上显示的标题
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
    // 如果是第一列,返回provinces中row索引出得元素
    switch (component) {
        case 0:
            return [[provinces objectAtIndex:row] objectForKey:@"state"];
            break;
        case 1:
            return [[cities objectAtIndex:row] objectForKey:@"city"];
            break;
        case 2:
            return [areas objectAtIndex:row];
            break;
        default:
            return @"";
            break;
    }
}
// 当用户选中UIPickerViewDataSource中指定列和列表项时激发该方法
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
    switch (component) {
        case 0:
            cities = [[provinces objectAtIndex:row] objectForKey:@"cities"];
            [self.areaPicker selectRow:0 inComponent:1 animated:YES];
            [self.areaPicker reloadComponent:1];
            
            areas = [[cities objectAtIndex:0] objectForKey:@"areas"];
            [self.areaPicker selectRow:0 inComponent:2 animated:YES];
            [self.areaPicker reloadComponent:2];
            
            state = [[provinces objectAtIndex:row] objectForKey:@"state"];
            city = [[cities objectAtIndex:0] objectForKey:@"city"];
            if ([areas count] > 0) {
                district = [areas objectAtIndex:0];
            } else{
                district = @"";
            }
            break;
        case 1:
            areas = [[cities objectAtIndex:row] objectForKey:@"areas"];
            [self.areaPicker selectRow:0 inComponent:2 animated:YES];
            [self.areaPicker reloadComponent:2];
            
            city = [[cities objectAtIndex:row] objectForKey:@"city"];
            if ([areas count] > 0) {
                district = [areas objectAtIndex:0];
            } else{
                district = @"";
            }
            break;
        case 2:
            if ([areas count] > 0) {
                district = [areas objectAtIndex:row];
            } else{
                district = @"";
            }
            break;
    }
}
具体逻辑实现可能有一些小细节处理的不好,但实际使用还是很棒的。这里就不贴动态gif图了。
本篇到此为止。