iOS 一款新房、二手房、租房的通用篩選控件

前言

之前項(xiàng)目為一個(gè)房產(chǎn)類項(xiàng)目,所以必不可少的需要一個(gè)新房、二手房、租房、中介門店的篩選控件,當(dāng)然大多數(shù)項(xiàng)目可能新房、二手房、租房篩選就夠了哈,不過多了個(gè)中介門店篩選倒不至于對(duì)篩選控件需求有多大影響,樣式也都能復(fù)用的。所以就想著去找一個(gè)別人封裝好的輪子直接拿來用了,奈何找來找去也沒找到有合適的,無奈只能自己花些時(shí)間去封裝一個(gè)了。項(xiàng)目完成了,當(dāng)然篩選功能也是好的了,便打算整理一下開源出去了,也省的后面人用到了再造輪子了,畢竟能幫助更多人省些事自己也是開心的。奈何當(dāng)初項(xiàng)目中篩選需求幾經(jīng)變更,方法定義過多,代碼略顯冗余了,使用起來實(shí)在不夠簡(jiǎn)潔好用。趁著項(xiàng)目完結(jié)時(shí)間有些盈余,所以便就抽空結(jié)合自己項(xiàng)目和貝殼找房的篩選功能和樣式,重新寫了一份篩選控件好開源出來了。

支持

  • 提供新房、二手房、租房的完整篩選功能實(shí)現(xiàn)
  • 支持固定和列表sectionHead懸停下拉篩選兩種模式
  • 支持單列表、雙列表、滑動(dòng)列表、切換列表、列表輸入等多種下拉篩選樣式
  • 展示樣式支持自定義調(diào)節(jié)
  • 展示數(shù)據(jù)支持自定義設(shè)置

預(yù)覽

頂部固定模式

列表下拉懸停模式

單雙列表切換篩選模式
ZHFilterMenuView
ZHFilterMenuView
ZHFilterMenuView

概述

總的來說實(shí)現(xiàn)這樣一個(gè)房屋篩選控件倒不復(fù)雜,為了實(shí)現(xiàn)代碼的簡(jiǎn)潔性,基本的實(shí)現(xiàn)就是數(shù)據(jù)源的構(gòu)造、傳參、UI構(gòu)造及數(shù)據(jù)綁定、數(shù)據(jù)處理及回調(diào)這幾個(gè)常用過程。下拉列表也是由UITableView根據(jù)數(shù)據(jù)參數(shù)進(jìn)行的一個(gè)動(dòng)態(tài)展示。這里便也不再多贅述內(nèi)部實(shí)現(xiàn)了,只講一下數(shù)據(jù)源的構(gòu)造了,傳參方式下面使用示例中會(huì)有提到。

  • 數(shù)據(jù)構(gòu)造
    根據(jù)項(xiàng)目需求不同可能數(shù)據(jù)來源也有些區(qū)別,我們之前的項(xiàng)目中項(xiàng)篩選所需數(shù)據(jù)為接口請(qǐng)求所得,以此更好來實(shí)現(xiàn)后臺(tái)動(dòng)態(tài)配置,當(dāng)然也是有缺陷的哈,就是每次需要接口請(qǐng)求后才能展示篩選。這里為了展示和實(shí)現(xiàn)篩選功能就把這些數(shù)據(jù)在本地寫了,當(dāng)然如果有其它篩選要求也可以在本地json中動(dòng)態(tài)增加。這里是封裝了一個(gè)FilterDataUtil類專門構(gòu)造數(shù)據(jù)源,通過傳入FilterType類型獲取篩選數(shù)據(jù)源。如果有對(duì)數(shù)據(jù)源操作有需求可以在此類的方法實(shí)現(xiàn)中進(jìn)行調(diào)整或修改。
/** 篩選類型 */
typedef NS_ENUM(NSUInteger, FilterType) {
    FilterTypeIsNewHouse = 1,  //新房
    FilterTypeSecondHandHouse, //二手房
    FilterTypeISRent,          //租房
};

@interface FilterDataUtil : NSObject

/** 根據(jù)FilterType類型獲取數(shù)據(jù) */
- (NSMutableArray *)getTabDataByType:(FilterType)type;

@end

屬性定義

為了實(shí)現(xiàn)篩選控件的通用性,所以開放以下屬性和方法,方便外部更好的調(diào)節(jié)設(shè)置和調(diào)用。

@property (nonatomic, weak) id<ZHFilterMenuViewDelegate> zh_delegate;
@property (nonatomic, weak) id<ZHFilterMenuViewDetaSource> zh_dataSource;

@property (nonatomic, strong) NSMutableArray *filterDataArr;          //傳入數(shù)據(jù)源(必傳)
@property (nonatomic, strong) NSArray<NSString *> *titleArr;          //傳入標(biāo)題數(shù)據(jù)源(必傳)
@property (nonatomic, strong) NSArray<NSString *> *imageNameArr;      //傳入折疊圖片數(shù)據(jù)源(不傳不展示圖片)
@property (nonatomic, strong) NSArray<NSString *> *selectImageNameArr;//傳入選擇狀態(tài)下的折疊圖片數(shù)據(jù)源(不傳默認(rèn)取imageNameArr里的圖片)

@property (nonatomic, strong) UIColor *titleColor;           //菜單標(biāo)題文本顏色(默認(rèn)333333)
@property (nonatomic, strong) UIColor *titleSelectedColor;   //菜單標(biāo)題選擇狀態(tài)下的顏色(默認(rèn)3072F5)
@property (nonatomic, strong) UIColor *lineColor;            //菜單標(biāo)題底部分割線顏色(默認(rèn)e8e8e8)
@property (nonatomic, assign) CGFloat titleFontSize;         //菜單標(biāo)題字號(hào)(默認(rèn)15)

@property (nonatomic, assign) BOOL showLine;                 //菜單標(biāo)題底部分割線是否顯示(默認(rèn)YES)
@property (nonatomic, assign) BOOL titleLeft;                //文字標(biāo)題是否居左 不平分(默認(rèn)NO)
@property (nonatomic, assign) BOOL lastTitleRight;           //最后一個(gè)文字標(biāo)題是否固定居右(默認(rèn)NO,為YES的情況下tab標(biāo)題寬度固定為60)
@property (nonatomic, assign) CGFloat listHeight;            //選擇列表的高度(默認(rèn)44)
@property (nonatomic, assign) CGFloat bottomHeight;          //列表底部的高度(默認(rèn)80)

@property (nonatomic, assign) CGFloat itemTitleFontSize;     //item標(biāo)題字號(hào)大小(默認(rèn)12)
@property (nonatomic, strong) UIColor *itemBGColor;          //item背景顏色(默認(rèn)f5f5f5)
@property (nonatomic, strong) UIColor *itemBGSelectedColor;  //item選擇時(shí)背景顏色(默認(rèn)eef6ff)
@property (nonatomic, assign) CGFloat space;                 //item間隔(默認(rèn)15)
@property (nonatomic, assign) CGFloat itemHeight;            //item高(默認(rèn)30)
@property (nonatomic, assign) NSInteger lineNum;             //一行展示數(shù)量(默認(rèn)4,當(dāng)內(nèi)容字符數(shù)大于7時(shí)lineNum = 2)
@property (nonatomic, assign) NSInteger maxLength;           //輸入框最大文本數(shù)量(默認(rèn)7位)

@property (nonatomic, strong) NSMutableArray *buttonArr;//菜單tab標(biāo)題button數(shù)據(jù)


/** 快速初始化
 *  maxHeight:下拉列表最大展示高度
 */
- (instancetype)initWithFrame:(CGRect)frame maxHeight:(CGFloat)maxHeight;

/** 參數(shù)傳完后開始調(diào)用以顯示 */
- (void)beginShowMenuView;

/** 外部快捷調(diào)用展開菜單列表 */
- (void)menuTappedWithIndex:(NSInteger)tapIndex;

/** 菜單列表消失 */
- (void)hideMenuList;

使用示例

注意:為了方便展示演示,這里代碼使用示例是新房、二手房、租房篩選功能整合在一起的。如果需要分開的,和根據(jù)自身情況根據(jù)相應(yīng)類型做下拆分即可。

  • 初始化
- (ZHFilterMenuView *)menuView
{
    if (!_menuView) {
        _menuView = [[ZHFilterMenuView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.view.frame), 45) maxHeight:CGRectGetHeight(self.view.frame) - 45];
        _menuView.zh_delegate = self;
        _menuView.zh_dataSource = self;
        if (self.filterType == FilterTypeIsNewHouse) {
            _menuView.titleArr = @[@"區(qū)域",@"價(jià)格",@"戶型",@"更多",@"排序"];
            _menuView.imageNameArr = @[@"x_arrow",@"x_arrow",@"x_arrow",@"x_arrow",@"x_arrow"];
        } else if (self.filterType == FilterTypeSecondHandHouse) {
            _menuView.titleArr = @[@"區(qū)域",@"價(jià)格",@"房型",@"更多",@"排序"];
            _menuView.imageNameArr = @[@"x_arrow",@"x_arrow",@"x_arrow",@"x_arrow",@"x_arrow"];
        } else if (self.filterType == FilterTypeISRent) {
            _menuView.titleArr = @[@"位置",@"方式",@"租金",@"更多",@""];
            _menuView.imageNameArr = @[@"x_arrow",@"x_arrow",@"x_arrow",@"x_arrow",@"x_px"];
        }
        [self.view addSubview:_menuView];
    }
    return _menuView;
}
  • 傳參并開始顯示
    這里根據(jù)FilterDataUtil類通過傳入FilterType類型獲取篩選數(shù)據(jù)源傳參即可。
//便于演示房源展示數(shù)據(jù)源暫時(shí)是寫在本地,可根據(jù)自身情況,如果需從接口請(qǐng)求可自行做下調(diào)整
    FilterDataUtil *dataUtil = [[FilterDataUtil alloc] init];
    self.menuView.filterDataArr = [dataUtil getTabDataByType:self.filterType];
    //開始顯示
    [self.menuView beginShowMenuView];

這里傳入展示類型,以此控制每種情況下的展示類型和確定類型。

/** 返回每個(gè) tabIndex 下的確定類型 */
- (ZHFilterMenuConfirmType)menuView:(ZHFilterMenuView *)menuView confirmTypeInTabIndex:(NSInteger)tabIndex
{
    if (tabIndex == 4) {
        return ZHFilterMenuConfirmTypeSpeedConfirm;
    }
    return ZHFilterMenuConfirmTypeBottomConfirm;
}

/** 返回每個(gè) tabIndex 下的下拉展示類型 */
- (ZHFilterMenuDownType)menuView:(ZHFilterMenuView *)menuView downTypeInTabIndex:(NSInteger)tabIndex
{
    if (tabIndex == 0) {
        return ZHFilterMenuDownTypeTwoLists;
    } else if (tabIndex == 1) {
        if (self.filterType == FilterTypeISRent) {
            return ZHFilterMenuDownTypeOnlyItem;
        } else {
            return ZHFilterMenuDownTypeItemInput;
        }
    } else if (tabIndex == 2) {
        if (self.filterType == FilterTypeISRent) {
            return ZHFilterMenuDownTypeItemInput;
        } else {
            return ZHFilterMenuDownTypeOnlyItem;
        }
    } else if (tabIndex == 3) {
        return ZHFilterMenuDownTypeOnlyItem;
    } else if (tabIndex == 4) {
        return ZHFilterMenuDownTypeOnlyList;
    }
    return ZHFilterMenuDownTypeOnlyList;
}
  • 回調(diào)
/** 確定回調(diào) */
- (void)menuView:(ZHFilterMenuView *)menuView didSelectConfirmAtSelectedModelArr:(NSArray *)selectedModelArr
{
    NSArray *dictArr = [ZHFilterItemModel mj_keyValuesArrayWithObjectArray:selectedModelArr];
    NSLog(@"結(jié)果回調(diào):%@",dictArr.mj_JSONString);
}

/** 警告回調(diào)(用于錯(cuò)誤提示) */
- (void)menuView:(ZHFilterMenuView *)menuView wangType:(ZHFilterMenuViewWangType)wangType
{
    if (wangType == ZHFilterMenuViewWangTypeInput) {
        NSLog(@"請(qǐng)輸入正確的價(jià)格區(qū)間!");
    }
}

經(jīng)過重新封裝之后控件方法調(diào)用和使用要簡(jiǎn)潔了很多,也更加通用性。但是也有可能會(huì)有些遺漏或問題,如果使用中遇到問題或者有更好的意見建議也歡迎提出。

下載地址

ZHFilterMenuView,如果感覺對(duì)你有所幫助的話記得給個(gè)star嘍!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容