项目需求一个地址选址器,必须是动态的网络或者本地数据库中获取下一级的地址,然后偶然看到京东的地址选择器不错,就模仿了下。
设计模式是模仿了UItableView的数据源和代理模式,其中数据源返回用了block,是因为有可能返回的数据源是网络请求,这样用block回调方便些。
代码如下:
#import
#import "SFSelectModel.h"
#import "SFSelectTableViewCell.h"
typedef void (^SoureBlock)(NSMutableArray *models);
@protocol SFSelectVCDataSource
- (void)sFSelectVCSourceBackWithDepth:(NSInteger)depth regionId:(NSInteger)regionId block:(SoureBlock)block;
@end
@protocol SFSelectVCDelegate
- (void)sFSelectVCDidChange:(NSString*)adress firstRegionId:(NSInteger)firstRegionId lastRegionId:(NSInteger)lastRegionId;
@end
@interface SFSelectVC : UIViewController
@property (nonatomic ,weak) id dataSource;
@property (nonatomic ,weak) id delegate;
- (instancetype)initWithFirstData:(NSMutableArray*)firstData;
@end
.m文件:
//
// SFSelectVC.m
// iseasoftCompany
//
// Created by songfei on 2018/4/19.
// Copyright © 2018年 hycrazyfish. All rights reserved.
//
#import "SFSelectVC.h"
#import "SFTitleView.h"
static NSString *const CellID = @"CellID";
@interface SFSelectVC ()
@property (nonatomic, strong) SFTitleView *titleView;// 选择头部
@property (nonatomic ,strong) UITableView *tableView;
@property (nonatomic ,strong) NSMutableArray*> *allModelArray;//全部的数据
@property (nonatomic ,strong) NSMutableArray *midelModels;//中间分类
@end
@implementation SFSelectVC{
SFSelectModel *lastSelctcModel;
NSMutableArray *btnArry;
}
- (instancetype)initWithFirstData:(NSMutableArray*)firstData{
if (self = [super init]) {
self.midelModels = firstData;
}
return self;
}
- (SFTitleView *)titleView{
if (!_titleView) {
_titleView = [[SFTitleView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 44)];
_titleView.backgroundColor = [UIColor whiteColor];
__weak typeof (self)weakSelf = self;
_titleView.btnBlock = ^(NSInteger onClickBtn) {
[weakSelf onClickBtn:onClickBtn];
};
}
return _titleView;
}
- (UITableView *)tableView{
if (!_tableView) {
_tableView = [[UITableView alloc]init];
_tableView.backgroundColor = [UIColor groupTableViewBackgroundColor];
_tableView.tableFooterView = [UIView new];//不显示多余的分割线
_tableView.dataSource = self;
_tableView.delegate = self;
[_tableView registerClass:[SFSelectTableViewCell class] forCellReuseIdentifier:CellID];
}
return _tableView;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [[UIColor blackColor]colorWithAlphaComponent:0.5f];
[self.view addSubview:self.titleView];
[self.view addSubview:self.tableView];
[self setMasnory];
btnArry = [NSMutableArray array];
self.allModelArray = [NSMutableArray array];
[self.tableView reloadData];
}
- (void)setMasnory{
[self.tableView mas_makeConstraints:^(MASConstraintMaker *make) {
make.bottom.mas_equalTo(self.view.mas_bottom);
make.left.mas_equalTo(self.view.mas_left);
make.right.mas_equalTo(self.view.mas_right);
make.height.mas_equalTo(300);
}];
[self.titleView mas_makeConstraints:^(MASConstraintMaker *make) {
make.bottom.mas_equalTo(self.tableView.mas_top);
make.left.mas_equalTo(self.tableView.mas_left);
make.right.mas_equalTo(self.tableView.mas_right);
make.height.mas_equalTo(44);
}];
}
#pragma mark --UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return self.midelModels.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
SFSelectTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellID forIndexPath:indexPath];
if(!cell){
cell = [[SFSelectTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellID];
}
[cell setModel:self.midelModels[indexPath.row]];
return cell;
}
#pragma mark --UITableViewDelegate
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return 40;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
[tableView deselectRowAtIndexPath:indexPath animated:true];
__weak typeof (self)weakSelf = self;
SFSelectModel *clickModel = self.midelModels[indexPath.row];
NSIndexPath *lastIndexPath;
if (lastSelctcModel == clickModel){
}else if (lastSelctcModel.depth == clickModel.depth){
if (lastSelctcModel) {
NSInteger row = [self.midelModels indexOfObject:lastSelctcModel];
lastIndexPath = [NSIndexPath indexPathForRow:row inSection:0];
}
for (SFSelectModel *mod in self.midelModels) {
mod.isSelect = false;
}
self.midelModels[indexPath.row].isSelect = true;
[self.titleView removeBtnWitBtn:btnArry.lastObject];
[btnArry removeLastObject];
UIButton *btn = [self.titleView addOneButton:clickModel.name];
[btnArry addObject:btn];
lastSelctcModel = clickModel;
}else{
lastSelctcModel = clickModel;
self.midelModels[indexPath.row].isSelect = true;
UIButton *btn = [self.titleView addOneButton:clickModel.name];
[btnArry addObject:btn];
}
if (self.dataSource) {
[self.dataSource sFSelectVCSourceBackWithDepth:clickModel.depth+1 regionId:clickModel.regionId block:^(NSMutableArray *models) {
if (models.count > 0) {
if (!(weakSelf.allModelArray.lastObject.lastObject.depth == weakSelf.midelModels.lastObject.depth) || weakSelf.allModelArray.count == 0) {
[weakSelf.allModelArray addObject:weakSelf.midelModels];
}
weakSelf.midelModels = models;
[weakSelf.tableView reloadData];
}else{
if (!(weakSelf.allModelArray.lastObject.lastObject.depth == weakSelf.midelModels.lastObject.depth) || weakSelf.allModelArray.count == 0) {
[weakSelf.allModelArray addObject:weakSelf.midelModels];
}
if (lastIndexPath) {
[weakSelf.tableView reloadRowsAtIndexPaths:@[lastIndexPath] withRowAnimation:UITableViewRowAnimationNone];
}
[weakSelf.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
}
}];
}
}
#pragma mark --点击了BTN
- (void)onClickBtn:(NSInteger)index{
if (index < 0) {
if (self.delegate) {
NSInteger firstRegionId = 0;
NSInteger lastRegionId = 0;
NSString *adressStr = @"";
for (int i = 0; i < self.allModelArray.count; i++) {
if (i == 0) {
for (SFSelectModel *model in self.allModelArray[i]) {
if (model.isSelect) {
firstRegionId = model.regionId;
adressStr = [adressStr stringByAppendingString:model.name];
}
}
}else if (i == (self.allModelArray.count - 1)){
for (SFSelectModel *model in self.allModelArray[i]) {
if (model.isSelect) {
lastRegionId = model.regionId;
adressStr = [adressStr stringByAppendingString:model.name];
}
}
}else{
for (SFSelectModel *model in self.allModelArray[i]) {
if (model.isSelect) {
lastRegionId = model.regionId;
adressStr = [adressStr stringByAppendingString:model.name];
}
}
}
}
if ([adressStr isEqualToString:@""]) {
[self dismissViewControllerAnimated:true completion:nil];
return;
}
[self.delegate sFSelectVCDidChange:adressStr firstRegionId:firstRegionId lastRegionId:lastRegionId];
}
[self dismissViewControllerAnimated:true completion:nil];
return;
}
if (btnArry.count == (index +1)) {
return;
}
for (NSInteger i = index + 1; i < btnArry.count; i++) {
UIButton* btn = btnArry[I];
[self.titleView removeBtnWitBtn:btn];
}
[btnArry removeObjectsInRange:NSMakeRange(index+1, btnArry.count - (index + 1))];
[self.allModelArray removeObjectsInRange:NSMakeRange(index+1, self.allModelArray.count - (index +1))];
self.midelModels = self.allModelArray.lastObject;
[self.tableView reloadData];
NSIndexPath *nowPath;
for (SFSelectModel *model in self.midelModels) {
if (model.isSelect) {
NSInteger atNub = [self.midelModels indexOfObject:model];
nowPath = [NSIndexPath indexPathForRow:atNub inSection:0];
lastSelctcModel = model;
}
}
[self.tableView scrollToRowAtIndexPath:nowPath atScrollPosition:UITableViewScrollPositionMiddle animated:true];
}
//点击其他地方退出
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
CGPoint point = [[touches anyObject] locationInView:self.view];
point = [self.tableView.layer convertPoint:point fromLayer:self.view.layer];
if (![self.tableView.layer containsPoint:point]) {
point = [[touches anyObject] locationInView:self.view];
point = [self.titleView.layer convertPoint:point fromLayer:self.view.layer];
if (![self.titleView.layer containsPoint:point]){
[self dismissViewControllerAnimated:true completion:nil];
}
}
}
@end
代码Git链接:https://github.com/songfeiSF/-SFAdressSelectVC-
图示: