iOS开发 - 一个天真的搜索控制器的独白
原文链接:http://www.jianshu.com/p/6d5327111511
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
正文
一、关于横向模块开发
团队型项目开发中,往往是根据功能模块进行开发任务分工的,如:商品模块、社交模块、设置模块等等,但是模块与模块之间,往往存在着一些横向的、通用的小功能,如:日历选择、出发地选择以及本文要谈到的搜索控制器。
做横向模块和封装框架是一样一样的,最最重要的,是接口的设计。如何增强模块的通用性、减少侵入性,让该模块的使用者用的爽,在设计接口的时候需要充分考虑的。
所谓通用性,是指能在多大程度上让别人用。做的最好的应该是苹果的UITableView。UITableView被称为“SB控件”,因为他不用知道自己展示什么内容,不用知道自己需要展示多少行,一切差异化的东西,全部通过代理来获取,所以他能拥有极其强大的通用性,所有想要做表格型展示的人都能用。
- 然而,通用性也有它的弊端,就是会额外增加使用该控件的开发人员的工作量。
- 假设项目中用到的所有tableView,都有相同的tableHeaderView、相同的numberOfSection & numberOfRow。如果还是用官方原生的UITableView,那我们每次使用,都需要写相同的、重复的代码来设置。
- 这个时候我们就应该通过二次封装的方式,主动降低通用性,来减少重复代码。
- 所以,不管是产品还是技术,没有绝对好的方案,只有在一定范围内,最适用的方案。技术就是权衡。
所谓侵入性,是指别人用了你的控件,一旦不想继续用了,要花费的调整代码的精力会不会非常大。推荐杰哥的MJExtension,这个神一样的框架基本上做到了零侵入性。
OK,装B完毕,咱们来看看这个“搜索控制器”的需求。
二、需求
- 不同板块相同需求
1.1 右上角的“搜索”按钮title,没输入关键词,展示“取消”;输入了关键词,展示“搜索”
1.2 没搜索到结果,关键词高亮现实
统一:搜索无结果.gif1.3 搜索有结果,展示搜索结果
1.4 请求数据时,转菊花 - 不同板块不同需求
2.1 板块一
板块一:刚进来没点搜索.gif2.2 板块二
板块二:刚进来没点搜索.gif2.3 板块三
板块三:刚进来没点搜索.gif
三、思考
问题:
- UI层面,不同的元素如何如何处理?
- 如:搜索框的placeHolder,是让使用者传字符串进来?还是传type进来,我们根据传进来的type,在控制器内设置不同placeholder?
数据层面,请求数据的逻辑在搜索控制器内部写死?还是让外部把搜索结果传进来?
其他
- 接口方法设计为类似MBProgressHUD的“+ (void)showXXXXX”型,还是设计成普通的返回一个实例控制器,让使用者决定何时弹出该控制器?
结论
- UI层面的差异比较简单明了,不涉及到后续一些东西,在控制器内部设置比较方便,采用传入type方式
- 数据层面的东西(包括网络请求和本地持久化),逻辑不那么简单直接,而且不同板块应该请求哪些接口、本地存储存在什么地方,显然负责做该板块的同学比我们更清楚,所以最好的办法是把请求数据之类的事情交给外部去做,我们只要提供一个方法,让外部能把请求好的数据转换成字符串数组传进来,我们负责展示就好。
- "+ (void)showXXX"方法用起来显然更爽,而且我们不会把过多的细节暴漏给该控制器的使用者,可以限制使用者的权限,防止使用者进行一些不恰当的操作导致崩溃(顺便插一句,相对于window来说,mac OS 就是这样做的。不用关心什么杀毒软件、硬盘分区之类的破事儿,写代码就安心写代码,做设计就安心做设计,系统方面的东西可以不用关心...这也是macOS用起来更爽的原因之一)
思路整理
现在,咱们想做这样一个搜索控制器:
- 足够封闭,不把搜索控制器对象返还给使用者
有足够的通用性,请求数据、数据存储等事情交给调用者处理,我们的搜索控制器只负责数据展示
1.1 这意味着,我们需要告诉调用者(数据逆传):- 什么时候应该请求网络数据(点击了搜索按钮)
- 什么时候应该清空本地缓存(点击了清除按钮)
- 用户点击了哪条搜索结果
1.2 调用者需要告诉我们(数据顺传):
- 请求回来的数据是什么
请注意,通常我们进行数据顺传的方式,是拿到某个控制器,点出来他的属性,并进行赋值;而咱们想要的效果,是最大程度限制调用者的权限,不让调用者拿到咱们的搜索控制器(意味着不能点出来)的同时,最好限制调用者只能通过咱们给定的方法告诉咱们搜索结果(不让调用者拿到搜索控制器的属性)。
怎么办?有什么办法能不返还给调用者一个对象,只返还给调用者一个方法?答案是block。
数据逆传方面,个人也还是非常喜欢block。因为相比于代理,block能够让代码实现“高聚合、低耦合”,不用跳来跳去的找代码,维护起来更方便。
(下一篇:一个复杂的首页的独白中,咱们会用到将代理和数据源方法,全都变成block的tableView)
四、上代码吧
这篇文章主要讲的,其实还是接口设计。所以代码就只贴头文件吧,源码丢在Github上了嗯(源码传送门)...如果觉得还有那么点小启发的话,记得顺手点星哦^_^
文/Azen(简书作者)
原文链接:http://www.jianshu.com/p/6d5327111511
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。 //
// AZXSearchController.h
// AZXSearchControllerDemo
//
// Created by Azen.Xu on 15/12/5.
// Copyright © 2015年 Azen.Xu. All rights reserved.
// #import <UIKit/UIKit.h> typedef NS_ENUM(NSInteger, AZXSearchControllerType) // 搜索控制器类型
{
AZXSearchControllerTypePartOne = << , // 板块一
AZXSearchControllerTypePartTwo = << , // 板块二
AZXSearchControllerTypePartThree = << // 板块三
}; typedef NS_ENUM(NSInteger, AZXSearchFunctionType) // 点击事件类型
{
AZXSearchFunctionTypeClear = << , // 点击了"清除搜索历史"按钮
AZXSearchFunctionTypeSearch = << , // 点击了"搜索"按钮
AZXSearchFunctionTypeSearchArray = << , // 点选了搜索结果列表
AZXSearchFunctionTypeHotArray = << , // 点选了热门搜索列表
AZXSearchFunctionTypeHistoryArray = << , // 点选了历史搜索列表
AZXSearchFunctionTypeCreatTagForDiscover = << // 点选了创建标签
}; typedef void(^AZXSearchCallBack)(AZXSearchFunctionType selectedType , NSInteger selectedRowIndex , NSString *resultString); // 点击回调 参数一:点击事件类型 参数二:选中行号 参数三:选中文字
typedef void(^AZXSearchSetNewArrayHandle)(NSArray *newArray); // 通过此block传递搜索结果字符串数组 @interface AZXSearchController : UIViewController /**
* 根据type创建不同展示样式的搜索控制器,返回搜索结果handleArray
*
* @param fromController 来源控制器
* @param hotArray 热门搜索stringArray
* @param hisArray 历史搜索stringArray
* @param type 样式枚举
* @param calBack 回调 - 数据请求成功后请为handleStringArray重新赋值
*
* @return 搜索结果handelArray
*/
+ (AZXSearchSetNewArrayHandle)showSearchControllerFromController :(UIViewController *)fromController
withHotModelArray :(NSArray *)hotArray
hisModelArray :(NSArray *)hisArray
type :(AZXSearchControllerType)type
callBack :(AZXSearchCallBack)callBack; @end
iOS开发 - 一个天真的搜索控制器的独白的更多相关文章
- iOS开发一个制作Live Photo的工具
代码地址如下:http://www.demodashi.com/demo/13339.html 1.livePhoto简介 livePhoto是iOS 9.0 之后系统相机提供的拍摄动态照片的功能,但 ...
- IOS开发之视图和视图控制器
视图(View), 视图控制器(ViewController)是IOS开发UI部分比较重要的东西.在学习视图这一块的东西的时候,感觉和Java Swing中的Panel差不多.在UIKit框架中都有一 ...
- iOS开发一个用户登录注册模块需要解决的坑
最近和另外一位同事负责公司登录和用户中心模块的开发工作,开发周期计划两周,减去和产品和接口的协调时间,再减去由于原型图和接口的问题,导致强迫症纠结症状高发,情绪不稳定耗费的时间,能在两周基本完成也算是 ...
- [分享]IOS开发-简单实现搜索框显示历史记录的本地缓存及搜索历史每次只能获取到一个的解决方案
注:原文:http://www.zhimengzhe.com/IOSkaifa/40433.html 1.首先,我们需要对进行过搜索的textField的输入内容进行一个NSUserDefaults的 ...
- IOS开发-表视图LV3导航控制器
学到这里感觉有点难了,其实这篇文章再草稿箱里放了好久了~ 最近对于学习的热情下降了.这不行-抓紧学习走起! 在这一章节的学习中主要针对导航控制器及表视图来建立多视图的应用, 首先要了解一些概念-- 1 ...
- iOS开发-- 一个苹果证书如何多次使用
苹果的开发者账号限制开发者证书只能有5个,我们开发过程中遇到超过5个人需要真机调试的情况,如何解决这个问题呢? 有两种方式可以解决问题: 1. Revoke原来的证书----不推荐 将以前的证书“re ...
- ios开发--一个苹果证书怎么多次使用——导出p12文件
为什么要导出.p12文件 当我们用大于三个mac设备开发应用时,想要申请新的证书,如果在我们的证书里,包含了3个发布证书,2个开发证书,可以发现再也申请不了开发证书和发布证书了(一般在我们的证书界面中 ...
- IOS开发UI篇-NavigationController的控制器之间的跳转
一.效果图如下 1> 第一个控制器的NavigationBar隐藏 2> 有按钮,可以跳转到下一个控制器,返回上一个控制器或者根控制器 二.思路代码 思路: 1> 设置window的 ...
- 【iOS开发-21】UINavigationController导航控制器初始化,导航控制器栈的push和pop跳转理解
(1)导航控制器初始化的时候一般都有一个根视图控制器,导航控制器相当于一个栈,里面装的是视图控制器,最先进去的在最以下,最后进去的在最上面.在最上面的那个视图控制器的视图就是这个导航控制器对外展示的界 ...
随机推荐
- jQuery和js如何判断checkbox是否选中
jquery: <div id="divId" class="divTable"><div class="tableBody&quo ...
- mysql innobackupex xtrabackup 大数据量 备份 还原(转)
原文:http://blog.51yip.com/mysql/1650.html 作者:海底苍鹰 大数据量备份与还原,始终是个难点.当MYSQL超10G,用mysqldump来导出就比较慢了.在这里推 ...
- STL学习系列七:优先级队列priority_queue容器
1.简介 最大值优先级队列.最小值优先级队列 优先级队列适配器 STL priority_queue 用来开发一些特殊的应用,请对stl的类库,多做扩展性学习 这里给个例子: #include< ...
- Python基础-函数(function)
这里我们看看Python中函数定义的语法,函数的局部变量,函数的参数,Python中函数的形参可以有默认值,参数的传递是赋值操作,在函数调用时,可以对实参进行打包和解包 1,函数定义 关键字def引 ...
- 程序设计第三次作业--C++计算器初始部分
面向对象程序设计作业3--C++计算器初始部分 Github 链接:https://github.com/luojingzhao/object-oriented/tree/master/calcula ...
- CodeForces 709A Juicer (水题, 模拟)
题意:给定 n 个桔子的大小,一个杯子的容积,一个最大限度,挨着挤桔子汁,如果大小大于限度,扔掉,如果不杯子满了倒掉,问你要倒掉多少杯. 析:直接按要求模拟就好,满了就清空杯子. 代码如下: #pra ...
- Java中的多线程操作初探
问题引出: 说是java,其实还是在做android的时候遇到的问题,在android 4.0以后,访问网络必须在新线程中实现,所以才会遇到这个问题.只是为了方面说明问题,才新建一个java项目.在m ...
- iOS国际化多语言设置
一.创建工程.添加语言
- Mahout之Navie Bayesian命令端运行
landen@landen-Lenovo:~/文档/20news$ mahout trainclassifier --helpMAHOUT_LOCAL is not set; adding HADOO ...
- asp获取勾选checkbox的值
Dim str_select str_select = CStr(request.Form("c_name")) c_name是checkbox的name