iOS中,在UIAcitionSheet中添加UIPickerView執行個體
寫在之前,有些事情我們無法左右,但是至少我們可以努力去讓它變得更好。我曾說過這樣一句話,我可能不是最好的,但我給你的絕對是最好的。找到自己想要的東西,想過的生活,即使再艱難,也別回頭看。一個人至少擁有一個夢想,有一個理由去堅強,心若沒有棲息的地方,到哪裡都是在流浪。
——J!nl!n
佛祖鎮樓,希望每個人開心快樂幸福。
因項目需要,涉及到日期選取器和地區聯動選取器。考慮到使用開源庫的資源不是特別划算,於是決定自己重寫一下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值標記。
以上是添加日期選取器的實現。
同理 ,地區聯動也是一樣的實現。不過相對比較複雜。這裡不做詳細介紹了。直接貼出實現部分。
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) ? @ : @ ; 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圖了。 本篇到此為止。