日了孝天犬了,剛剛看見我居然沒有寫心得六直接寫了七,這不能容忍。是以我精心挑選一個很常使用的iOS小功能作為心得六的知識點(可以直接拷貝進去使用的demo)。經過幾次構思,決定把地區時舉器寫一個。因為基本上做app都會有位址這一選項。而蘋果手機90%都是用時舉器去顯示位址。現在進入正題。
首先,和往常一樣,demo放在github上,位址:https://github.com/sunyunfei/AreaDemo.git
時舉器 UIPickerView 是一個我不是經常用的控件。但是位址選擇,日期顯示基本上還是選擇他的,不為别的,他省空間,顯示形式比較好。它和表思路基本是一樣的,兩個代理UIPickerViewDelegate,UIPickerViewDataSource。我再說這個demo的基礎是你已經學習過時舉器,如果你還沒有,那麼請你看一下他的相關的資料。
首先我建立一個UIPickerView的視圖。
.h
#import <UIKit/UIKit.h>
#import "AreaModel.h"
@interface AreaPickerView : UIView<UIPickerViewDelegate, UIPickerViewDataSource>
//取消按鈕事件
- (IBAction)clickCancelBtn:(UIBarButtonItem *)sender;
//确定按鈕事件
- (IBAction)clickOkBtn:(UIBarButtonItem *)sender;
//時舉器
@property (weak, nonatomic) IBOutlet UIPickerView *areaPicker;
@property (strong, nonatomic) AreaModel *locate;
//選中塊
@property(nonatomic,copy)void(^chooseBlock)(AreaPickerView *area);
//取消塊
@property(nonatomic,copy)void(^cancelBlock)();
//确定塊
@property(nonatomic,copy)void(^okBlock)();
- (id)initWithArea;
- (void)showInView:(UIView *)view;
- (void)cancelPicker;
@end
.m
#import "AreaPickerView.h"
@interface AreaPickerView()
{
NSArray *provinces, *cities, *areas;
}
@end
@implementation AreaPickerView
- (id)initWithArea
{
self = [[[NSBundle mainBundle] loadNibNamed:@"AreaPickerView" owner:self options:nil] objectAtIndex:0];
if (self) {
self.areaPicker.dataSource = self;
self.areaPicker.delegate = self;
//加載資料
provinces = [[NSArray alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"area.plist" ofType:nil]];
cities = [[provinces objectAtIndex:0] objectForKey:@"cities"];
self.locate.state = [[provinces objectAtIndex:0] objectForKey:@"state"];
self.locate.city = [[cities objectAtIndex:0] objectForKey:@"city"];
areas = [[cities objectAtIndex:0] objectForKey:@"areas"];
if (areas.count > 0) {
self.locate.district = [areas objectAtIndex:0];
} else{
self.locate.district = @"";
}
}
return self;
}
-(AreaModel *)locate
{
if (_locate == nil) {
_locate = [[AreaModel alloc] init];
}
return _locate;
}
#pragma mark - PickerView lifecycle
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 3;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
switch (component) {
case 0:
return [provinces count];
break;
case 1:
return [cities count];
break;
case 2:
return [areas count];
break;
default:
return 0;
break;
}
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
switch (component) {
case 0:
return [[provinces objectAtIndex:row] objectForKey:@"state"];
break;
case 1:
return [[cities objectAtIndex:row] objectForKey:@"city"];
break;
case 2:
if ([areas count] > 0) {
return [areas objectAtIndex:row];
break;
}
default:
return @"";
break;
}
}
- (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];
self.locate.state = [[provinces objectAtIndex:row] objectForKey:@"state"];
self.locate.city = [[cities objectAtIndex:0] objectForKey:@"city"];
if ([areas count] > 0) {
self.locate.district = [areas objectAtIndex:0];
} else{
self.locate.district = @"";
}
break;
case 1:
areas = [[cities objectAtIndex:row] objectForKey:@"areas"];
[self.areaPicker selectRow:0 inComponent:2 animated:YES];
[self.areaPicker reloadComponent:2];
self.locate.city = [[cities objectAtIndex:row] objectForKey:@"city"];
if ([areas count] > 0) {
self.locate.district = [areas objectAtIndex:0];
} else{
self.locate.district = @"";
}
break;
case 2:
if ([areas count] > 0) {
self.locate.district = [areas objectAtIndex:row];
} else{
self.locate.district = @"";
}
break;
default:
break;
}
//選中塊
self.chooseBlock(self);
}
- (void)showInView:(UIView *)view
{
CGFloat width = [UIScreen mainScreen].applicationFrame.size.width;
CGFloat height = [UIScreen mainScreen].applicationFrame.size.height;
self.frame = CGRectMake(0, height, width, self.frame.size.height);
[view addSubview:self];
[UIView animateWithDuration:0.3 animations:^{
self.frame = CGRectMake(0, height - self.frame.size.height, width, self.frame.size.height);
}];
}
- (void)cancelPicker
{
[UIView animateWithDuration:0.3
animations:^{
self.frame = CGRectMake(0, self.frame.origin.y+self.frame.size.height, self.frame.size.width, self.frame.size.height);
}
completion:^(BOOL finished){
[self removeFromSuperview];
}];
}
- (IBAction)clickCancelBtn:(UIBarButtonItem *)sender {
self.cancelBlock();
}
- (IBAction)clickOkBtn:(UIBarButtonItem *)sender {
self.okBlock();
}
@end
其實你浏覽一下就知道使用和表一樣的,确定行數确定列數,標明方法之類的。我這是自己用nib畫了一個時舉器
然後再控制器建立一個按鈕做為調出時舉器的按鈕, .h
#import "ViewController.h"
#import "AreaPickerView.h"
@interface ViewController ()
- (IBAction)clickBtn:(UIButton *)sender;
//位址按鈕
@property (weak, nonatomic) IBOutlet UIButton *areaBtn;
@property (strong, nonatomic) NSString *areaValue;
@property (strong, nonatomic) AreaPickerView *locatePicker;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self cancelLocatePicker];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (IBAction)clickBtn:(UIButton *)sender {
self.locatePicker = [[AreaPickerView alloc]
initWithArea];
//塊的相關操作
__weak typeof(self)weakSelf = self;
self.locatePicker.chooseBlock= ^(AreaPickerView *area)
{
weakSelf.areaValue = [NSString stringWithFormat:@"%@ %@ %@", area.locate.state, area.locate.city, area.locate.district];
};
self.locatePicker.cancelBlock = ^()
{
[weakSelf cancelLocatePicker];
};
self.locatePicker.okBlock = ^()
{
if( (weakSelf.areaValue == nil) || [weakSelf.areaValue isEqualToString:@"北京 北京 通州"])
{
weakSelf.areaValue = @"北京 北京 通州";
}
[weakSelf.areaBtn
setTitle:weakSelf.areaValue
forState:UIControlStateNormal];
[weakSelf cancelLocatePicker];
};
[self.locatePicker showInView:self.view];
}
#pragma mark - HZAreaPicker delegate
-(void)pickerDidChaneStatus:(AreaPickerView *)picker
{
self.areaValue = [NSString stringWithFormat:@"%@ %@ %@", picker.locate.state, picker.locate.city, picker.locate.district];
NSLog(@"%@",self.areaValue);
}
-(void)cancelLocatePicker
{
[self.locatePicker cancelPicker];
self.locatePicker = nil;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesBegan:touches withEvent:event];
if( (self.areaValue == nil) || [self.areaValue isEqualToString:@"北京 北京 通州"])
{
self.areaValue = @"北京 北京 通州";
}
[self.areaBtn
setTitle:self.areaValue
forState:UIControlStateNormal];
[self cancelLocatePicker];
}
@end
這樣,一個地區時舉器就完成了
在這裡面我是留了一個小bug的,不知道你們能不能看出來。看出來自己修改一下,相信自己的能力,很快就可以成功。