佛祖鎮樓,希望每個人開心快樂幸福。
因項目需要,涉及到日期選擇器和地區聯動選擇器。考慮到使用開源庫的資源不是特別劃算,於是決定自己重寫一下iOS系統自身的控件。真正意義上本質也並不是重寫,只是在UIAcitionSheet添加部分布局使用UIPickerFView填充。代碼比較精簡,但是有些地方顯得很臃腫,後續隨著時間的推移和技術的積累,進一步對其進行優化。此次日志只做記錄,博客也會更新收集。
首先來看下一下效果圖,如下:
在這裡,使用到了系統自帶的UIActionSheet,熟悉iOS開發的人應該都知道。UIActionSheet是一個底部彈出的選擇按鈕項控件,可以添加多項,並為每項添加點擊事件。它的初始化代碼為:
NSString *title = UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation) ? @ ; UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:title delegate:self cancelButtonTitle:@取消 destructiveButtonTitle:nil otherButtonTitles:@確定,nil];我們可以看到這裡初始化了一個NSString,然後根據屏幕的橫豎屏選擇使用三目運算符指定填充字符串。這裡只用字符 換行符作為字符使得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可交互,背景為白色,必須設置背景色,否則可能部分機型會出現 顯示字符。然後初始化UIDatePicker並綁定tag以提供後面方法調用。緊接著設置日期格式,當然也可以是指日期時間格式。最好通過UIActionSheet的addSubView方法添加到之前我們用換行符占位的布局上,並且使用showInView顯示在最上面,同樣給UIActionSheet設置一個tag值標記。
以上是添加日期選擇器的實現。
同理 ,地區聯動也是一樣的實現。不過相對比較復雜。這裡不做詳細介紹了。直接貼出實現部分。
#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) ? @ : @ ; 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圖了。 本篇到此為止。