ios设计模式源码
1. ios为什么要使用设计模式
原因如下:
使用设计模式,为了代团数吵码可重用性、让代码更容易被塌侍他人理解、保证代码可靠性。设计模式使代码编写真正工程化。
iOS是由苹果公司开发的毕氏移动操作系统。苹果公司最早于2007年1月9日的Macworld大会上公布这个系统,最初是设计给iPhone使用的,后来陆续套用到iPodtouch、iPad上。
2. iOS设计模式2 - 观察者模式_通知机制
NSnotificationCenter是一种典型的有调度中心的观察者模式实现方式。以NSNotificationCenter为中心,观察者往Center中注册对某个主题对象的变化感兴趣,主题对象通过NSNotificationCenter进行变化广播。这种模型就是文章开始发布订阅报纸在OC中的一种类似实现。所有的观察和监听行为都向同一个中心注册,所有对象的变化也都通过同一个中心胡帆向外广播。
在通知机制中对某个通知感兴趣的所有对象都可以成为接收者。
首先,这些对象需要对通知中心(NSNotificationCenter)发出addObserver:selector:name:object:消息进行注册,在投送对象投
送通知给通知中心时,通知中心就会把通知广播给注册过的接收者。所有的接收者都不知道通知是谁投送的,更不关心它的细节。投送对象与接收者是一对多的关系。接收者如果薯码对通知不再关注,会给通知中心发出
removeObserver:name:object:消息解除注册,以后不再接收通知。
1)注册观察者:(一般数做哪在viewDidLoad方法中实现)
2)接收广播后的处理
3)解除注册(一般在dealloc方法中解除=注册)
通过postNotificationName:object:userInfo:发送某一类型通知,广播改变。
一个通知对象要包含的内容:
3. 三大平台设计模式分析之ios——新浪微博(2017.1.15)
选择理由:新浪微博页眉页脚部分是经典的ios风格,在复杂的结构里也穿插着标签式导航的变体等其他形式,还有复杂多样的列表模式,在社交类APP里比较典型。
使用平台:iphone7
下图(左图)是新浪微博的首页,页眉是ios典型的导航栏,标题在中间,按钮分布在左右两边,因为是首页,不需要返回按钮。微博在这里放置了一个叫做“好友关注动态”的页面入口,用更多元的方式为用户推荐好友。
用的是舵式导航,置于中间突出位置的是发布按钮,点击后从底部飞出6个按钮,用户可以选择需要的发布方式。而原来的发布按钮“+”号,顺时针旋转变成了X号,点击X号又逆时针变回“+”号,同时页面回到动态列表。在这个用户最顺手的位置做了这样的交互,方便用户快速地在发布和浏览之间快速切换。这两个行为方式在社交类APP里是最核心的行为。
如上图所示的首页,有一个ios风格的内嵌式搜索框。刚进入首页时候是没有的,当页面刷新或下拉之后就会出现。因为用户无论是刷新或者下拉之后再返回,都是因为没有找到或者错过了自己想要的内容,这个时候提供搜索给用户,可以让用户自己检索想要的内容。
左边这个是经典的ios风格下拉框——带小三角的圆角矩形。右边这个做了一些改变:(1)当分组很多的时候,下拉框可以上下滚动,显示更多的内容。如果用tab导航的话,由于分组的名字是由用户起的,字段长度差异可能会比较大,会显得比较凌乱,而且首页的元素已经够多了,再用tab导航的话内容区域就更小了。下拉框则可以在不需要时候收起,节约空间。(2)在下拉框的底部有一个“编辑我的分组”按钮。这样做的优点在于不需要频繁地跳转到另一个页面,可以直接快速的切换分组,只有在要对分组进行编辑时,锋迹才会跳转到新的页面,在新的页面用户可以更专注于编辑分组,而不用担心误操作,毕竟下拉框空间有限,不方便直接编辑。再说回左图,有个小问题,就是图标用了雷达的图标。用户点开会发现除了雷达还有其他的2个功能,所以用雷达的图禅基兆标代表所有的功能会有歧义,它正确的意思不是“雷达”而是“雷达等功能”。不喜欢用“雷达”的用户,也会比较难发现“扫一扫”和“打车”的功能。(现在贺租最新版本的微博里右上角只有“扫一扫”和“打车”,并且默认显示扫一扫这个比较常用的功能)
微博中,下拉刷新和页面加载用的都是这样的菊花形加载,这种加载方式只表示状态,没有进度显示,如果用户长时间的等待的话,会感到不耐烦,不知何时才会加载完。但下拉刷新和页面加载都属于短时间的加载。在网络正常的情况下几秒之内就能完成加载。所以不需要显示进度,只需让用户明白正在加载即可。
微博的列表从整体的结构来说是以垂直列表为主,穿插着小图轮播式的“好友关注”和“相关文章”。但是往细了说,根据微博内容的不同,呈现的结构也稍有区别,这些设计模式同样也出现在其他社交类应用里:
1)纯文字微博
除此以外微博还有很多类型的单元格,都是在文字后插入其他的内容,例如图片、视频、链接等。
2)图片微博
文字后插入图片的形式是微博乃至大部分的社交APP里最常见的一种模式。如下图所示的是插有图片的微博。根据图片的数量不同,布局上会有些变化。只有一张图片时,按实际比例展示成缩略图,优点是展示出图片最真实的比例效果,缺点是当图片是竖图的时候布局不是特别好看。图片大于一张时会变成网格的布局,优点是在有限的空间里罗列尽可能多的内容,尺寸统一的方形图片和较小的间距,看起来比较有品质。有些爱玩的网友会利用这个特点进行自定义的设计,例如把9张局部的图拼成一张大图,更有趣味性和视觉冲击力。
值得一提的是,当图片为4张时,正好形成一个四宫格。这样就不会导致第二行只有一张图片了。不过在有些app里还做了更好的处理,就是把4宫格单张缩略图的尺寸比9宫格的单张尺寸做得略大一点。这样排版上会看起来更饱满。
3)视频微博
除了图片以外,插入视频也是非常常见的一种模式。如下图左图所示,微博的视频用一个相同的大图比例呈现,图片上会有一个播放按钮。但其实当视频拖动到页面中间时,视频会自动以无声的方式播放并显示进度。优点是可以让用户实时地看到视频内容,比较生动。
4)文章微博
上图右图所示的是发布文章所生成的微博,会以一张较大的封面图加上一行标题(图下方)的形式呈现。这种形式在一些电商的社区也是常常会看到,例如淘宝微淘里的“热文”。单张大图以统一的比例呈现,与单图微博(左上图)不同的是,它更有感染力,看起来更有档次,让人产生一种内容很专业的感觉。因为在信息量如此之大的微博(包括其他社区),用户往往是匆匆的浏览,如果不增强感染力,很难让用户驻足,甚至去浏览较长的内容。标题都在图片之下,可见图片才是吸引用户的首要元素。不过微博这里的设计,标题的存在感似乎太弱了一些。和图片的整体性有点欠缺,这样容易让用户产生只有一张大图的错觉而错过文章。
5)其他链接
除了以上所述的几种主流的单元格模式以外,有些微博在文末也会插入如下图所示的其他链接,可以是文章,也可以是商品、音乐等其他内容。以图片+标题等内容的形式呈现。比起纯文字来更生动,还可以知道链接的属性,例如音乐的话上面会有一个播放的图标之类的,缺点是感染力不够,优点是不会占太多空间,在有限的空间里给用途提供足够多的信息。
6)小图轮播的推荐列表
下图是微信的好友关注,其实不止是好友关注,还有推荐的文章等,都会以这种形式穿插在微博列表里,目的是向用户推荐好友或文章,以促进活跃度及强化社交。同时又不能影响用户正常浏览微博,所以用这种形式可以在有限的空间里推荐足够多的好友或文章,或其他信息给用户。缺点是在用户快速浏览时容易忽略。
1)下图左图是微博一级导航下的第二个tab——消息。同首页一样,标准的ios风格导航栏和内嵌式搜索,一进来的时候搜索是隐藏的,下拉才会显示。
页面内是标准的垂直列表。这种形式的优点是简洁清晰,冷静高效。用户到这里来往往是主动寻找一些内容,不像在首页常常是浏览的。所以这里不需要像首页那么复杂详细的列表,只需要简洁清晰的列表即可。根据用户从左至右、从上至下的阅读习惯,左边一排呈现的是图标或头像,用户可以一目了然。而“@我的”、“评论”、“赞”三个核心的社交功能图标置顶,之后的内容按时间由近及远排序,让用户可以随时见到最新的消息。
上图消息列表有2种单元格。一种是带箭头的二级列表,进去以后是子列表。这种形式的列表缺点是中间空白太多,有点浪费空间,而且不适用于层级太深,容易造成用户的厌倦。所以微博在这里只用作二级列表,再进去就是最后一层列表——微博列表,层级很浅。
另一种是没有箭头的列表,进去以后是对话框列表。优点是显示了一部分内容信息,用户可以快速的做出判断是否有兴趣查看,提高了使用效率。根据ios的操作习惯,左滑可以进行删除。缺点是呈现的内容太多不能再放置其他操作,比如箭头、控件等。所以这种形式最适合用于这种消息列表。
2)上图(右图)是“我”的界面。“我”与“消息”的界面一样,是一个标准的垂直列表页。由于这里只是功能的陈列,不像消息列表所要显示时间等信息,所以这里每个单元格的高度都不高,刚刚好容纳一行标题。“新的好友”、“我的相册”、“草稿箱”这些原始的功能层级都不深,而“微博钱包”、“微博运动”、“粉丝服务”、“粉丝头条”这些扩展的功能进去以后都是一个独立功能的首页。所以这里的内容层级都比较浅,适合这种带箭头的列表,可以直达目标页面;四个扩展功能后面还有灰色的小字用来引导用户;根据具体页面的类型还进行了分隔。所以整个页面看起来简洁清晰,冷静高效。
最后,这两个页面时都有一个共通的缺点,就是只有标题的单元格和有补充信息的单元格放在一起,布局上疏密明显,只有标题的单元格看起来很单薄,标题右边空荡荡的。而与其他信息的单元格对比之下就觉得密密麻麻的。
下图(左起第一张)是微博的“发现”页面。头部是ios经典的导航栏搜索。下面是轮播banner,这里用了轮播是为了在有限的空间里多呈现一些广告内容。再往下有两行入口图标,然后是微博列表。
微博列表模块的开头部分有个导航标签式的导航。如果页面上滑到了微博列表头部的位置,或者点击某个标签,这条标签式导航就会吸到页面顶部,变成标签式导航样式的分段式导航,见缝插针插进了导航栏。这是因为每个标签下面的内容信息量很大,还要分出第二层级,也就是吸到顶部以后
该导航下面出现的一行标签(见右图)。但是分段式导航的标签不宜太多,最好2-3个,微博用了4个,但所幸都是2个字的,看起来不算太拥挤,因为还有返回按钮,如果太拥挤的话,第一个标签离返回太近也会有歧议。布局上也会显得头部太重。
如右上图所示,“热门”、“榜单”、“视频”这三个板块都是微博内容,标签多于5个,所以做成了滚动式标签。
这个设计的优点在于灵活的运用了标签式导航的变化,让用户在没有明显的跳转的情况下,顺利的切换,不影响用户阅读的同时,承载了更大的内容量。缺点在于标签不宜太多,例如“热门”下的标签
有三十多个,后面的标签点击率会很低。并且如果不是根据用户的偏好进行排序的话,很有可能用户并不喜欢前面的内容,而喜欢在最后面,但他未必知道后面会有,也未必有耐心浏览到最后。
而最后的“头条”是用户可以自己定制的新闻内容,所以只放了4个优先级最高的,最后一个“更多”点击后进入“全部频道”(见上图右图),可以调整优先级,或者选择想去的频道。与底部导航栏一样的是,关闭按钮还是在底部,这样方便用户快速地回到头条页面。缺点同样也是标签过多容易造成用户的困惑。还有,不是在原标签下直接展开的,而是滑出一个浮层,所以可能会有点跳出感。但比起滚动式标签还是好一点,因为这种网格式布局的标签列表,把每一个标签都平等清晰的呈现给用户,便于用户快速的选择,而不用反复操作滑动去找不确定是否会有的标签。
1)下图是“我”里的“我的赞”。页眉也是典型的ios风格。标题在中间,右边是ios风格的“更多”(安卓是竖着的,之后分析安卓的app时候会有图),左侧是返回,并且带有上一级的标签,即“我”。这页的标签式导航是一个典型的标签式导航,并且一直置顶。无论页面如何滚动,它一直都在,用户可以便捷的再不同类目之间切换。
2)点击三个点的“更多”按钮从底部浮现选项,可以选择“刷新”或“返回首页”。这里只有2项,其实也可以做成2个按钮放在右上角。之所以这样做,好处首先是给用户更大的点击空间,避免误操作。还有就是页眉的布局不至于太挤。缺点就是需要多点一步。并且在上面点击后从底部浮出浮层的话用户的操作幅度有点大。但这和首页的下拉框是有区别的,下拉框主要是同级页面间的切换或者功能的切换。而这里是显示更多操作,所以也不适合用下拉框。
4. iOS中都有什么设计模式各个设计模式的作用
大致有23种
都是表示类与类之间的构架关系 也就是表示对象的逻辑关系
设计模式根据使用类型可以分为三种:
1、 创建模式:工厂模式、单子模式、建造者模式、原型模式颤和、工厂方法模式。
2、 结构模式:外观模式、代理模式、适配器模式、组合模式、装饰模式、桥模式、
共享模式。
3、 行为模式:模板模式、纪念品模式、观察者模式、责任链模式、命令模式、声明模式、
策略模式、中介模式、解释器模式、访问模式
说白了模式就是前人经过大量的实践,总结出来的优化的对象关系 你也可以自己总结出来
3.iOS 10 隐私权限设置
iOS 10 开始对隐私权限更加严格,如果你不设置就会直接崩溃或洞指,现在很多遇到崩溃问题了,一般解决办法都是在info.plist文件添加对应的Key-Value就可以了。
iOS 10 UIStatusBar方法过期:
在我们开发中有可能用到UIStatusBar一些属性,在iOS 10 中这些方法已经过期了,如果你的项目中有用的话就得需要适配。上面的图片也能发现,如果在iOS 10中你需要使用preferredStatusBar比如这样:
//iOS 10 - (UIStatusBarStyle)preferredStatusBarStyle { return UIStatusBarStyleDefault; }
我们都是用RGB来设置颜色,反正用起来也不是特别多样化,这次新增的方法应该就是一个弥补吧。所以在iOS 10 苹果官方建议我们使用sRGB,因为它性能更好,色彩更丰富。如果你自己为UIColor写了一套分类的话也可尝试替换为sRGB,UIColor类中新增衫配了两个Api如下:
+ (UIColor *)colorWithDisplayP3Red:(CGFloat)displayP3Red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha NS_AVAILABLE_IOS(10_0); - (UIColor *)initWithDisplayP3Red:(CGFloat)displayP3Red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha NS_AVAILABLE_IOS(10_0);
5. iOS 设计模式(一)-代理模式
代理模式是一种消息传递方式,一个完整的代理模式包括:委托对象、代理对象和协议。
协议:用来指定代理双方可以做什么,必须做什么。
委托对象:根据指定的协议,指定代理去完成什么功能。
代理对象:根据指定的协议,完成委托方需要实现的功能。
从上图中可以看到三方之间的关系,在实际应用中通过协议来规定代理双方的行为,协议中的内容一般都是方法列表,当然也可以定义属性。
协议是公共的定义,如果只是某个类使用,我们常做的就是写在某个类中。如果是多个类都是用同一个协议,建议创建一个Protocol文件,在这个文件中定义协议。遵循的协议可以被继承,例如我们常用的 UITableView ,由于继承自 UIScrollView 的缘故,所以也将 UIScrollViewDelegate 继承了过来,我们可以通过代理方法获取 UITableView 偏移量等状态参数。
协议只能定义公用的一套接口,灶散行类似于一个约束代理双方的作用。但不能提供具体的实现方法,实现方法需要代理对象去实现。协议可以继承其他协议,并且可以继承多个协议,在iOS中对象是不支持多继承的,而协议可以多继承。
协议有两个修饰符 @optional 和 @required ,创建一个协议如果没有声明,默认是 @required 状态的。这两个修饰符只是约定代理是否强制需要遵守协议,如果 @required 状态的方法代理没有遵守,会报一个黄色的警告,只是起一个约束的作用,没有其他功能。
无论是 @optional 还是 @required ,在委托方调用代理方法时都需要做一个判断,判断代理是否实现当前方法,否则会导致崩溃。
在iOS中代理的本质就是代理对象内存的传递和操作,我们在委托类设置代理对象后,实际上只是用一个id类型的指针将代理对象进行了一个弱引用。委托方让代理隐哗方执行操作,实际上是在委托类中向这个id类型指针指向的对象发送消息,而这个id类型指针指向的对象,就是代理对象。
通过上面这张图我们发现,其实委托方的代理属性本质上就是代理对象自身,设置委托代理就是代理属性指针指向代理对象,相当于代理对象只是在委托方中调用自己的方法,如果方法没有实现就会导致崩溃。从崩溃的信息上来看,就可以看出来是代理方没有实现协议中的方法导致的崩溃。
而协议只是一种语法,是声明委托方中的代理属性可以调用协议中声明的方法,而协议中方法的实现还是有代理方完成,而协议掘和方和委托方都不知道代理方有没有完成,也不需要知道怎么完成。
由于代理对象使用强引用指针,引用创建的委托方对象,并且成为委托对象的代理。这就会导致委托对象的delegate属性强引用代理对象,导致循环引用的问题,最终两个对象都无法正常释放。
我们将委托对象的delegate属性,设置为弱引用属性。
weak 和 assign 是一种“非拥有关系”的指针,通过这两种修饰符修饰的指针变量,都不会改变被引用对象的引用计数。但是在一个对象被释放后, weak 会自动将指针指向 nil ,而 assign 则不会。在iOS中,向 nil 发送消息时不会导致崩溃的,所以 assign 就会导致野指针的错误 unrecognized selector sent to instance 。
所以我们如果修饰代理属性,还是用 weak 修饰,比较安全。
6. iOS中的常用的几种设计模式
观察者模式
应用场景:一般为model层对,controller和view进行的通知方式数蠢,不关心谁去接收,只负责发布信息。
优势:解耦合
敏捷原则:接口隔离原则,开放-封闭原则
实例:通知中心,注册通知中心,任何位置可以发送消息,注册观察者的对象可以接收。
kvo,键值对改变通知的观察者。
MVC模式
应用场景:是一中非常古薯困陪老的设计模式,通过数据模型,控制器逻辑,视图展示将应用程序进行逻辑尺歼划分。
优势:使系统,层次清晰,职责分明,易于维护
敏捷原则:对扩展开放-对修改封闭
实例:model-即数据模型,view-视图展示,controller进行UI展现和数据交互的逻辑控制。