iOS开发 - 一个天真的搜索控制器的独白

文/Azen(简书做者)
原文连接:http://www.jianshu.com/p/6d5327111511
著做权归做者全部,转载请联系做者得到受权,并标注“简书做者”。

正文


1、关于横向模块开发

团队型项目开发中,每每是根据功能模块进行开发任务分工的,如:商品模块、社交模块、设置模块等等,可是模块与模块之间,每每存在着一些横向的、通用的小功能,如:日历选择、出发地选择以及本文要谈到的搜索控制器。
作横向模块和封装框架是同样同样的,最最重要的,是接口的设计。如何加强模块的通用性、减小侵入性,让该模块的使用者用的爽,在设计接口的时候须要充分考虑的。git

  • 所谓通用性,是指能在多大程度上让别人用。作的最好的应该是苹果的UITableView。UITableView被称为“SB控件”,由于他不用知道本身展现什么内容,不用知道本身须要展现多少行,一切差别化的东西,所有经过代理来获取,因此他能拥有极其强大的通用性,全部想要作表格型展现的人都能用。github

    • 然而,通用性也有它的弊端,就是会额外增长使用该控件的开发人员的工做量。
    • 假设项目中用到的全部tableView,都有相同的tableHeaderView、相同的numberOfSection & numberOfRow。若是仍是用官方原生的UITableView,那咱们每次使用,都须要写相同的、重复的代码来设置。
    • 这个时候咱们就应该经过二次封装的方式,主动下降通用性,来减小重复代码。
    • 因此,不论是产品仍是技术,没有绝对好的方案,只有在必定范围内,最适用的方案。技术就是权衡。
  • 所谓侵入性,是指别人用了你的控件,一旦不想继续用了,要花费的调整代码的精力会不会很是大。推荐杰哥的MJExtension,这个神同样的框架基本上作到了零侵入性。数组

OK,装B完毕,我们来看看这个“搜索控制器”的需求。缓存

2、需求

  1. 不一样板块相同需求
    1.1 右上角的“搜索”按钮title,没输入关键词,展现“取消”;输入了关键词,展现“搜索”
    1.2 没搜索到结果,关键词高亮现实

    统一:搜索无结果.gif

    1.3 搜索有结果,展现搜索结果
    1.4 请求数据时,转菊花
  2. 不一样板块不一样需求
    2.1 板块一

    板块一:刚进来没点搜索.gif

    2.2 板块二

    板块二:刚进来没点搜索.gif

    2.3 板块三

    板块三:刚进来没点搜索.gif

3、思考

问题:

  • UI层面,不一样的元素如何如何处理?
    • 如:搜索框的placeHolder,是让使用者传字符串进来?仍是传type进来,咱们根据传进来的type,在控制器内设置不一样placeholder?
  • 数据层面,请求数据的逻辑在搜索控制器内部写死?仍是让外部把搜索结果传进来?网络

  • 其余框架

    • 接口方法设计为相似MBProgressHUD的“+ (void)showXXXXX”型,仍是设计成普通的返回一个实例控制器,让使用者决定什么时候弹出该控制器?

结论

  • UI层面的差别比较简单明了,不涉及到后续一些东西,在控制器内部设置比较方便,采用传入type方式
  • 数据层面的东西(包括网络请求和本地持久化),逻辑不那么简单直接,并且不一样板块应该请求哪些接口、本地存储存在什么地方,显然负责作该板块的同窗比咱们更清楚,因此最好的办法是把请求数据之类的事情交给外部去作,咱们只要提供一个方法,让外部能把请求好的数据转换成字符串数组传进来,咱们负责展现就好。
  • "+ (void)showXXX"方法用起来显然更爽,并且咱们不会把过多的细节暴漏给该控制器的使用者,能够限制使用者的权限,防止使用者进行一些不恰当的操做致使崩溃(顺便插一句,相对于window来讲,mac OS 就是这样作的。不用关心什么杀毒软件、硬盘分区之类的破事儿,写代码就安心写代码,作设计就安心作设计,系统方面的东西能够不用关心...这也是macOS用起来更爽的缘由之一)

思路整理

如今,我们想作这样一个搜索控制器:ide

  1. 足够封闭,不把搜索控制器对象返还给使用者
  2. 有足够的通用性,请求数据、数据存储等事情交给调用者处理,咱们的搜索控制器只负责数据展现
    1.1 这意味着,咱们须要告诉调用者(数据逆传):spa

    • 何时应该请求网络数据(点击了搜索按钮)
    • 何时应该清空本地缓存(点击了清除按钮)
    • 用户点击了哪条搜索结果

    1.2 调用者须要告诉咱们(数据顺传):设计

    • 请求回来的数据是什么
  3. 请注意,一般咱们进行数据顺传的方式,是拿到某个控制器,点出来他的属性,并进行赋值;而我们想要的效果,是最大程度限制调用者的权限,不让调用者拿到我们的搜索控制器(意味着不能点出来)的同时,最好限制调用者只能经过我们给定的方法告诉我们搜索结果(不让调用者拿到搜索控制器的属性)。3d

怎么办?有什么办法能不返还给调用者一个对象,只返还给调用者一个方法?答案是block。
数据逆传方面,我的也仍是很是喜欢block。由于相比于代理,block可以让代码实现“高聚合、低耦合”,不用跳来跳去的找代码,维护起来更方便。
(下一篇:一个复杂的首页的独白中,我们会用到将代理和数据源方法,全都变成block的tableView)

4、上代码吧

这篇文章主要讲的,其实仍是接口设计。因此代码就只贴头文件吧,源码丢在Github上了嗯(源码传送门)...若是以为还有那么点小启发的话,记得顺手点星哦^_^

 1 文/Azen(简书做者)
 2 原文连接:http://www.jianshu.com/p/6d5327111511
 3 著做权归做者全部,转载请联系做者得到受权,并标注“简书做者”。
 4 
 5 //
 6 //  AZXSearchController.h
 7 //  AZXSearchControllerDemo
 8 //
 9 //  Created by Azen.Xu on 15/12/5.
10 //  Copyright © 2015年 Azen.Xu. All rights reserved.
11 //
12 
13 #import <UIKit/UIKit.h>
14 
15 typedef NS_ENUM(NSInteger, AZXSearchControllerType) //  搜索控制器类型
16 {
17     AZXSearchControllerTypePartOne = 1 << 0,   //  板块一
18     AZXSearchControllerTypePartTwo = 1 << 1,   //  板块二
19     AZXSearchControllerTypePartThree = 1 << 2  //  板块三
20 };
21 
22 typedef NS_ENUM(NSInteger, AZXSearchFunctionType)   //  点击事件类型
23 {
24     AZXSearchFunctionTypeClear = 1 << 0,    //  点击了"清除搜索历史"按钮
25     AZXSearchFunctionTypeSearch = 1 << 1,   //  点击了"搜索"按钮
26     AZXSearchFunctionTypeSearchArray = 1 << 2,    //  点选了搜索结果列表
27     AZXSearchFunctionTypeHotArray = 1 << 3,       //  点选了热门搜索列表
28     AZXSearchFunctionTypeHistoryArray = 1 << 4,   //  点选了历史搜索列表
29     AZXSearchFunctionTypeCreatTagForDiscover = 1 << 5   //  点选了建立标签
30 };
31 
32 typedef void(^AZXSearchCallBack)(AZXSearchFunctionType selectedType , NSInteger selectedRowIndex , NSString *resultString); //  点击回调 参数一:点击事件类型 参数二:选中行号 参数三:选中文字
33 typedef void(^AZXSearchSetNewArrayHandle)(NSArray *newArray);   //  经过此block传递搜索结果字符串数组
34 
35 
36 @interface AZXSearchController : UIViewController
37 
38 /**
39  *  根据type建立不一样展现样式的搜索控制器,返回搜索结果handleArray
40  *
41  *  @param fromController 来源控制器
42  *  @param hotArray       热门搜索stringArray
43  *  @param hisArray       历史搜索stringArray
44  *  @param type           样式枚举
45  *  @param calBack        回调 - 数据请求成功后请为handleStringArray从新赋值
46  *
47  *  @return 搜索结果handelArray
48  */
49 + (AZXSearchSetNewArrayHandle)showSearchControllerFromController :(UIViewController *)fromController
50                                                withHotModelArray :(NSArray *)hotArray
51                                                    hisModelArray :(NSArray *)hisArray
52                                                             type :(AZXSearchControllerType)type
53                                                         callBack :(AZXSearchCallBack)callBack;
54 
55 @end
View Code
相关文章
相关标签/搜索