ios 常用控件之地址選擇器

最近做項目封裝了一個pickerView 用法很簡單,先來看圖

singlePicker.gif

先來說思路吧,首先創建一個基類的BasePickerView,方便以后擴展功能用,它是繼承自UIView

單一選擇器

1.看看BasePickerView.h文件

@interface BasePickerView : UIView<UIPickerViewDataSource, UIPickerViewDelegate>
/** 確認按鈕 */
@property (nonatomic, strong) UIButton *comfirmBtn;
/** 取消按鈕 */
@property (nonatomic, strong) UIButton *cancelBtn;
/** pickerView */
@property (nonatomic, strong) UIPickerView *pickerView;
/** 子類實現的方法  */
- (void)setupPickerView;
/** 確認按鈕點擊事件 */
- (void)comfirmBtnClick;
/** 取消按鈕點擊事件 */
- (void)cancelBtnClick;
/** 彈出頁面 */
- (void)show;
@end

可以看到基類中已經引入了UIPickerViewDataSourceUIPickerViewDelegate,子類在繼承的時候就不用再引入了,接下來是一些公開屬性,其實comfirmBtncancelBtn是不用公開的

/** 子類實現的方法  */
- (void)setupPickerView;

這個方法是給子類實現的,方便做一些數據配置
2.BasePickerView.m

#define kWindowH   [UIScreen mainScreen].bounds.size.height //應用程序的屏幕高度
#define kWindowW    [UIScreen mainScreen].bounds.size.width  //應用程序的屏幕寬度

@interface BasePickerView ()<UIGestureRecognizerDelegate>
/** 確認 取消按鈕所在的視圖 */
@property (nonatomic, strong) UIView *barView;
/** 內容視圖 */
@property (nonatomic, strong) UIView *contentView;
/** 內容高度 */
@property (nonatomic, assign) CGFloat contentHeight;
/** barViewHeight */
@property (nonatomic, assign) CGFloat barViewHeight;
/** btnWidth */
@property (nonatomic, assign) CGFloat btnWidth;
@end

@implementation BasePickerView
- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        /** 設置默認的內容視圖高度 */
        self.contentHeight = 250;
        /** 設置默認的按鈕視圖高度 */
        self.barViewHeight = 40;
        /** 設置默認的按鈕寬度 */
        self.btnWidth = 50;
        self.bounds = [UIScreen mainScreen].bounds;
        self.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.1];
        [self addSubview:self.contentView];
        [self.barView addSubview:self.comfirmBtn];
        [self.barView addSubview:self.cancelBtn];
        [self.contentView addSubview:self.barView];
        [self.contentView addSubview:self.pickerView];
        /** 添加手勢 */
        UITapGestureRecognizer *tap=[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(remove)];
        self.userInteractionEnabled = YES;
        tap.delegate = self;
        [self addGestureRecognizer:tap];
        [self setupPickerView];
    }
    return self;
}
/** 展示 */
- (void)show {
    /** 添加到window */
    [[UIApplication sharedApplication].delegate.window addSubview:self];
    self.center = [UIApplication sharedApplication].keyWindow.center;
    CGRect contentViewFrame = CGRectMake(0, kWindowH, kWindowW, self.contentHeight);
    contentViewFrame.origin.y -= self.contentView.frame.size.height;
    [UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
        self.contentView.frame = contentViewFrame;
    } completion:^(BOOL finished) {
        
    }];
}
/** 銷毀 */
- (void)remove {
    
    CGRect contentViewFrame = self.contentView.frame;
    contentViewFrame.origin.y += self.contentView.frame.size.height;
    [UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
        self.contentView.frame = contentViewFrame;
    } completion:^(BOOL finished) {
        [self.contentView removeFromSuperview];
        [self removeFromSuperview];
    }];
    
}
/** 子類實現的方法  */
- (void)setupPickerView {
    
}
/** 確認按鈕點擊事件 */
- (void)comfirmBtnClick {
    [self remove];
}
/** 取消按鈕點擊事件 */
- (void)cancelBtnClick {
    [self remove];
}
#pragma mark - UIGestureRecognizerDelegate
/** 為了不讓子視圖響應手勢點擊 */
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{
    if ([touch.view isDescendantOfView:self.contentView]) {
        return NO;
    }
    return YES;
}
#pragma mark - lazy
- (UIView *)barView {
    if (!_barView) {
        _barView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kWindowW, self.barViewHeight)];
    }
    return _barView;
}
- (UIView *)contentView {
    if (!_contentView) {
        _contentView = [[UIView alloc] initWithFrame:CGRectMake(0, kWindowH, kWindowW, self.contentHeight)];
        _contentView.backgroundColor = [UIColor whiteColor];
    }
    return _contentView;
}
- (UIPickerView *)pickerView {
    if (!_pickerView) {
        _pickerView = [[UIPickerView alloc] initWithFrame:CGRectMake(0, self.barViewHeight, self.contentView.frame.size.width, self.contentView.frame.size.height - self.barViewHeight)];
        _pickerView.delegate = self;
        _pickerView.dataSource = self;
        _pickerView.backgroundColor = [UIColor colorWithRed:230/255.0 green:230/255.0 blue:230/255.0 alpha:1];
    }
    return _pickerView;
}
- (UIButton *)comfirmBtn {
    if (!_comfirmBtn) {
        _comfirmBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        _comfirmBtn.frame = CGRectMake(kWindowW - self.btnWidth, 0, self.btnWidth, self.barViewHeight);
        [_comfirmBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
        [_comfirmBtn setTitle:@"確定" forState:UIControlStateNormal];
        [_comfirmBtn addTarget:self action:@selector(comfirmBtnClick) forControlEvents:UIControlEventTouchUpInside];
    }
    return _comfirmBtn;
}
- (UIButton *)cancelBtn {
    if (!_cancelBtn) {
        _cancelBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        _cancelBtn.frame = CGRectMake(0, 0, self.btnWidth, self.barViewHeight);
        [_cancelBtn setTitle:@"取消" forState:UIControlStateNormal];
        [_cancelBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
        [_cancelBtn addTarget:self action:@selector(cancelBtnClick) forControlEvents:UIControlEventTouchUpInside];
    }
    return _cancelBtn;
}
#pragma mark - UIPickerViewDataSource
/** 僅消除警告 子類會重寫*/
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
    return 1;
}

/** 僅消除警告 子類會重寫*/
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
    return 1;
}

整個文件的代碼都貼出來了,很簡單,一看就明白,這里提一點就是為了防止子視圖響應點擊手勢而銷毀頁面,在UIGestureRecognizerDelegate代理方法-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch中做了處理,基類就這么完了,是不是很簡單,我也覺得....
3.接下來我們看看SinglePickerView,這個是繼承自BasePickerView.h 的子類,頭文件 SinglePickerView.h 中的內容也不多,看代碼

#import "BasePickerView.h"
typedef void(^selectedBlock)(NSString *str,NSInteger index);
/** 單列的pickerView 傳一個數組即可 */
@interface SinglePickerView : BasePickerView
/** 回調block */
@property (nonatomic, copy) selectedBlock block;
/** 使用類方法創建 傳一個數組即可 str為選中的字符串 index為字符串對應數組元素的下標 (比如 要顯示的值為廣州  發請求的時候取code  這時就可以用到index來取值了) */
+ (instancetype)showWithDataArray:(NSArray *)array block:(selectedBlock)block;
@end

公開一個類方法方便調用,不用創建一堆的屬性,命名可能不規范,不要吐槽了....
4.SinglePickerView.m

+(instancetype)showWithDataArray:(NSArray *)array block:(selectedBlock)block {
    SinglePickerView *pick = [[SinglePickerView alloc] init];
    [pick setDataArray:array];
    [pick show];
    pick.block = block;
    return pick;
}

調用的類方法,大神常用這種方式的,此外應有贊

- (void)setupPickerView {
    [super setupPickerView];
    _index = 0;
}

設置默認的下標為0,其實在- (void)setDataArray:(NSArray *)dataArray中已經設置了,這里........

- (void)setDataArray:(NSArray *)dataArray {
    _dataArray = dataArray;
    _selectedTitle = dataArray.firstObject;
    _index = 0;
    [self.pickerView reloadAllComponents];
}

初始化數據,_selectedTitle為選中的字符串 ,_index為選中的數組下標

- (void)show {
    [super show];
    if (self.dataArray.count>0) {
        [self.pickerView selectRow:0 inComponent:0 animated:NO];
    }
}

pickerView默認選中第一行

- (void)comfirmBtnClick{
    if (self.block) {
        self.block(self.selectedTitle,self.index);
    }
    [super comfirmBtnClick];
}

確認按鈕點擊事件,回調block,嗯,完犢子了....

地址選擇器

上面說了那么多,感覺都是廢話......
來來來,繼續,接下來有請JWAddressPickerView,上圖,哎呦,命名沒改..你們自己改吧...

addressPicker.gif

1.來看看JWAddressPickerView.h也是沒啥可看的

#import "BasePickerView.h"
typedef void(^AddressBlcok)(NSString *province,NSString *city,NSString *area);
@interface JWAddressPickerView : BasePickerView
/** 回調block */
@property (nonatomic, copy) AddressBlcok addressBlock;
+ (instancetype)showWithAddressBlock:(AddressBlcok)block;
@end

太簡單,不解釋
2.JWAddressPickerView.m,這個文件得說下.JWAddress.plist是數據我是拿到別人的,然后轉plist了,時間太久不記得是誰的了,有看到的@我一個,我加上來源

- (void)loadAddressData {
    NSString *path = [[NSBundle mainBundle] pathForResource:@"JWAddress" ofType:@"plist"];
    self.pickerDic = [[NSDictionary alloc] initWithContentsOfFile:path];
    self.provinceArray = [self.pickerDic valueForKey:@"p"];
    self.selectedArray = self.pickerDic[@"c"][self.provinceArray.firstObject];
    self.cityArray = self.selectedArray;
    self.townArray = self.pickerDic[@"a"][@"北京市-北京市"];
}

這個是在本地加載地址數據的方法,也很簡單,嗯,完了,獻上你們要的具體的Demo,請點贊

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,461評論 6 532
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,538評論 3 417
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,423評論 0 375
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,991評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,761評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,207評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,268評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,419評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,959評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,782評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,983評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,528評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,222評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,653評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,901評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,678評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,978評論 2 374

推薦閱讀更多精彩內容