MOFSAddressPickerView.m 12.5 KB
//
//  MOFSAddressPickerView.m
//  MOFSPickerManager
//
//  Created by lzqhoh@163.com on 16/8/31.
//  Copyright © 2016年 luoyuan. All rights reserved.
//

#import "MOFSAddressPickerView.h"

@interface MOFSAddressPickerView() <UIPickerViewDelegate,UIPickerViewDataSource>

@property (nonatomic, strong) UIView *bgView;
@property (nonatomic, strong) NSMutableArray *dataArr;

@property (nonatomic, assign) NSInteger selectedIndex_province;
@property (nonatomic, assign) NSInteger selectedIndex_city;
@property (nonatomic, assign) NSInteger selectedIndex_area;

@property (nonatomic, assign) BOOL isGettingData;
@property (nonatomic, strong) void (^getDataCompleteBlock)();

@property (nonatomic, strong) dispatch_semaphore_t semaphore;

@end

@implementation MOFSAddressPickerView


#pragma mark - create UI

- (instancetype)initWithFrame:(CGRect)frame {
    
    self.semaphore = dispatch_semaphore_create(1);
    
    [self initToolBar];
    [self initContainerView];
    
    CGRect initialFrame;
    if (CGRectIsEmpty(frame)) {
        initialFrame = CGRectMake(0, self.toolBar.frame.size.height, UISCREEN_WIDTH, 216);
    } else {
        initialFrame = frame;
    }
    self = [super initWithFrame:initialFrame];
    if (self) {
        self.backgroundColor = [UIColor whiteColor];
        self.autoresizingMask = UIViewAutoresizingFlexibleWidth;
        
        self.delegate = self;
        self.dataSource = self;
        
        [self initBgView];
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            
            [self getData];
            dispatch_queue_t queue = dispatch_queue_create("my.current.queue", DISPATCH_QUEUE_CONCURRENT);
            dispatch_barrier_async(queue, ^{
                dispatch_async(dispatch_get_main_queue(), ^{
                    [self reloadAllComponents];
                });
            });
        });
    }
    return self;
}

- (void)initToolBar {
    self.toolBar = [[MOFSToolbar alloc] initWithFrame:CGRectMake(0, 0, UISCREEN_WIDTH, 44)];
    self.toolBar.translucent = NO;
}

- (void)initContainerView {
    self.containerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, UISCREEN_WIDTH, UISCREEN_HEIGHT)];
    self.containerView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.4];
    self.containerView.userInteractionEnabled = YES;
    [self.containerView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hiddenWithAnimation)]];
}

- (void)initBgView {
    self.bgView = [[UIView alloc] initWithFrame:CGRectMake(0, UISCREEN_HEIGHT - self.frame.size.height - 44, UISCREEN_WIDTH, self.frame.size.height + self.toolBar.frame.size.height)];
}

#pragma mark - Action

- (void)showMOFSAddressPickerCommitBlock:(void(^)(NSString *address, NSString *zipcode))commitBlock cancelBlock:(void(^)())cancelBlock {
    [self showWithAnimation];
    
    __weak typeof(self) weakSelf = self;
    self.toolBar.cancelBlock = ^ {
        if (cancelBlock) {
            [weakSelf hiddenWithAnimation];
            cancelBlock();
        }
    };
    
    self.toolBar.commitBlock = ^ {
        if (commitBlock) {
            [weakSelf hiddenWithAnimation];
            if (weakSelf.dataArr.count > 0) {
               PickerAddressModel *PickerAddressModel = weakSelf.dataArr[weakSelf.selectedIndex_province];
                CityModel *cityModel;
                DistrictModel *districtModel;
                if (PickerAddressModel.list.count > 0) {
                    cityModel = PickerAddressModel.list[weakSelf.selectedIndex_city];
                }
                if (cityModel && cityModel.list.count > 0) {
                    districtModel = cityModel.list[weakSelf.selectedIndex_area];
                }
                
                NSString *address;
                NSString *zipcode;
                if (!cityModel) {
                    address = [NSString stringWithFormat:@"%@",PickerAddressModel.name];
                    zipcode = [NSString stringWithFormat:@"%@",PickerAddressModel.zipcode];
                } else {
                    if (!districtModel) {
                        address = [NSString stringWithFormat:@"%@-%@",PickerAddressModel.name,cityModel.name];
                        zipcode = [NSString stringWithFormat:@"%@-%@",PickerAddressModel.zipcode,cityModel.zipcode];
                    } else {
                        address = [NSString stringWithFormat:@"%@-%@-%@",PickerAddressModel.name,cityModel.name,districtModel.name];
                        zipcode = [NSString stringWithFormat:@"%@-%@-%@",PickerAddressModel.zipcode,cityModel.zipcode,districtModel.zipcode];
                    }
                }
                
                
                commitBlock(address, zipcode);
            }
        }
    };
}

- (void)showWithAnimation {
    [self addViews];
    self.containerView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.0];
    CGFloat height = self.bgView.frame.size.height;
    self.bgView.center = CGPointMake(UISCREEN_WIDTH / 2, UISCREEN_HEIGHT + height / 2);
    [UIView animateWithDuration:0.25 animations:^{
        self.bgView.center = CGPointMake(UISCREEN_WIDTH / 2, UISCREEN_HEIGHT - height / 2);
        self.containerView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.4];
    }];
    
}

- (void)hiddenWithAnimation {
    CGFloat height = self.bgView.frame.size.height;
    [UIView animateWithDuration:0.25 animations:^{
        self.bgView.center = CGPointMake(UISCREEN_WIDTH / 2, UISCREEN_HEIGHT + height / 2);
        self.containerView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.0];
    } completion:^(BOOL finished) {
        [self hiddenViews];
    }];
}

- (void)addViews {
    UIWindow *window = [UIApplication sharedApplication].keyWindow;
    [window addSubview:self.containerView];
    [window addSubview:self.bgView];
    [self.bgView addSubview:self.toolBar];
    [self.bgView addSubview:self];
}

- (void)hiddenViews {
    [self removeFromSuperview];
    [self.toolBar removeFromSuperview];
    [self.bgView removeFromSuperview];
    [self.containerView removeFromSuperview];
}

- (void)getData {
    self.isGettingData = YES;
    NSString *path = [[NSBundle mainBundle] pathForResource:@"province_data" ofType:@"xml"];
    NSString *dataStr;
    if (!_dataArr) {
        _dataArr = [NSMutableArray array];
    }
    if (_dataArr.count != 0) {
        [_dataArr removeAllObjects];
    }
    @try {
        dataStr = [[NSString alloc] initWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
        GDataXMLDocument *document = [[GDataXMLDocument alloc] initWithXMLString:dataStr options:0 error:nil];
        NSArray *arr = [document nodesForXPath:@"root/province" error:nil];
        for (int i = 0; i < arr.count; i++) {
            PickerAddressModel *model = [[PickerAddressModel alloc] initWithXML:arr[i]];
            
            [_dataArr addObject:model];
        }
        self.isGettingData = NO;
        if (self.getDataCompleteBlock) {
            self.getDataCompleteBlock();
        }
    } @catch (NSException *exception) {
        
    } @finally {
        
    }
}

- (void)searchType:(SearchType)searchType key:(NSString *)key block:(void(^)(NSString *result))block {
    
    dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
    
    NSString *valueName = searchType == SearchTypeAddress ? @"name" : @"zipcode";
    NSString *type  = searchType == SearchTypeAddress ? @"zipcode" : @"name";
    if (self.isGettingData || !self.dataArr || self.dataArr.count == 0) {
        __weak typeof(self) weakSelf = self;
        self.getDataCompleteBlock = ^{
            if (block) {
                
                dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
                    block([weakSelf searchByKey:key valueName:valueName type:type]);
                });
                
                dispatch_semaphore_signal(weakSelf.semaphore);
            }
        };
    } else {
        if (block) {
            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
                block([self searchByKey:key valueName:valueName type:type]);
            });
            dispatch_semaphore_signal(self.semaphore);
        }
    }

}


- (NSString *)searchByKey:(NSString *)key valueName:(NSString *)valueName type:(NSString *)type {
    
    NSArray *arr = [key componentsSeparatedByString:@"-"];
    if (arr.count > 3) {
        return @"error0"; //最多只能输入省市区三个部分
    }
    PickerAddressModel *PickerAddressModel = [self searchModelInArr:_dataArr key:arr[0] type:type];
    if (PickerAddressModel) {
        if (arr.count == 1) { //只输入了省份
            return [PickerAddressModel valueForKey:valueName];
        }
        CityModel *cityModel = (CityModel *)[self searchModelInArr:PickerAddressModel.list key:arr[1] type:type];
        if (cityModel) {
            if (arr.count == 2) { //只输入了省份+城市
                return [NSString stringWithFormat:@"%@-%@",[PickerAddressModel valueForKey:valueName],[cityModel valueForKey:valueName]];
            }
            DistrictModel *districtModel = (DistrictModel *)[self searchModelInArr:cityModel.list key:arr[2] type:type];
            if (districtModel) {
                return [NSString stringWithFormat:@"%@-%@-%@",[PickerAddressModel valueForKey:valueName],[cityModel valueForKey:valueName],[districtModel valueForKey:valueName]];
            } else {
                return @"error3"; //输入区错误
            }
        } else {
            return @"error2"; //输入城市错误
        }
    } else {
        return @"error1"; //输入省份错误
    }


}

- (NSObject *)searchModelInArr:(NSArray *)arr key:(NSString *)key type:(NSString *)type {
    
    NSObject *object;
    
    for (NSObject *obj in arr) {
        if ([key isEqualToString:[obj valueForKey:type]]) {
            object = obj;
            break;
        }
    }
    
    return object;
}


#pragma mark - UIPickerViewDelegate,UIPickerViewDataSource

- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
    return 3;
}

- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
     PickerAddressModel *PickerAddressModel;
    if (self.dataArr.count > 0) {
        PickerAddressModel = self.dataArr[self.selectedIndex_province];
    }
   
    CityModel *cityModel;
    if (PickerAddressModel && PickerAddressModel.list.count > 0) {
        cityModel = PickerAddressModel.list[self.selectedIndex_city];
    }
    if (self.dataArr.count != 0) {
        if (component == 0) {
            return self.dataArr.count;
        } else if (component == 1) {
            return PickerAddressModel == nil ? 0 : PickerAddressModel.list.count;
        } else if (component == 2) {
            return cityModel == nil ? 0 : cityModel.list.count;
        } else {
            return 0;
        }
    } else {
        return 0;
    }

}

- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
    
    if (component == 0) {
        PickerAddressModel *PickerAddressModel = self.dataArr[row];
        return PickerAddressModel.name;
    } else if (component == 1) {
        PickerAddressModel *PickerAddressModel = self.dataArr[self.selectedIndex_province];
        CityModel *cityModel = PickerAddressModel.list[row];
        return cityModel.name;
    } else if (component == 2) {
        PickerAddressModel *PickerAddressModel = self.dataArr[self.selectedIndex_province];
        CityModel *cityModel = PickerAddressModel.list[self.selectedIndex_city];
        DistrictModel *districtModel = cityModel.list[row];
        return districtModel.name;
    } else {
        return nil;
    }
}

- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
    switch (component) {
        case 0:
            self.selectedIndex_province = row;
            self.selectedIndex_city = 0;
            self.selectedIndex_area = 0;
            [pickerView reloadComponent:1];
            [pickerView reloadComponent:2];
            [pickerView selectRow:0 inComponent:1 animated:NO];
            [pickerView selectRow:0 inComponent:2 animated:NO];
            break;
        case 1:
            self.selectedIndex_city = row;
            self.selectedIndex_area = 0;
            [pickerView reloadComponent:2];
            [pickerView selectRow:0 inComponent:2 animated:NO];
            break;
        case 2:
            self.selectedIndex_area = row;
            break;
        default:
            break;
    }
}

- (void)dealloc {
   
}

@end