登录 立即注册
金钱:

Code4App-iOS开发-iOS 开源代码库-iOS代码实例搜索-iOS特效示例-iOS代码例子下载-Code4App.com

AASubviews - 自动排列子视图

[复制链接]
来自: 东东_qh 分类: iOS精品源码 上传时间: 2017-12-23 15:22:56
Tag:

项目介绍:

调用说明:  

只需引入 AASubviews.h 后,调用下面的方法即可:

+ (void)superview:(UIView *)superview subviews:(NSArray *)subviews;

使用场景:

如果你使用 frame 来布局,这是一个很方便的工具。场景是这样的,一个页面由多个不同的展示元素组成,考虑到可维护性和扩展性,这些元素可以划分成从上至下排列的多个分组,一个分组就是一个自定义的 subview ,每个 subview 实现各自内部的展示逻辑,并且有以下特点:

  • subview 的高度可能变化;

  • subview 也可能突然隐藏或显示;

  • 由于以上两点,superview 的高度也会跟着变化;

  • subview 的排列顺序可能变化。

演示例子:

例如需求是展示某个商家的详情页,对于酒店(Hotel)类型商家是下面这样展示的,并且,为了方便管理,从上至下划分为以下几个部分:
例子

还有交互上是这样的:点击“关闭”按钮会隐藏 DemoAdView,点击“展开”会使 DemoDescView 变高,点击“重置”会使所有 view 重置一遍。并且对于商店(Shop)类型的商家是有不同的展示方式。

AASubViews 可以很方便的管理这种变化。

DemoHeaderView *headerView = [DemoHeaderView createViewFromXib];
DemoNameView *nameView = [DemoNameView createViewFromXib];
DemoAdView *adView = [DemoAdView createViewFromXib];
DemoDescView *descView = [DemoDescView createViewFromXib];
DemoCommentView *commentView = [DemoCommentView createViewFromXib];

NSArray *subviews = nil;
if (self.type == DemoTypeHotel) {
    subviews = @[headerView, nameView, adView, descView, commentView];
} else {
    subviews = @[adView, nameView, descView, commentView];
}

[AASubviews superview:self.scrollView subviews:subviews];

要查看更详细的代码请打开工程。

原理分析:

从上至下排列 subviews,使用 KVO 原理检测 subviewframehidden 变化,从而自动调整布局。

难点是,如果只是简单利用 KVOsuperview 来观察 subview 的变化,会有很多问题,例如:

  1. 如果重复 addObserver 会多次触发 observeValueForKeyPath:ofObject:change:context 方法;

  2. 如果重复 removeObserver 会导致闪退;

  3. 如果被观察者释放了而还没有 removeObserver 的话,也会导致闪退,模拟器不会发生,但是真机会发生;

  4. superview 观察 subview ,实现 observeValueForKeyPath:ofObject:change:context 方法,最初想到有两种方式,第一种是自定义一个 UIView 的子类,所有的 superview 继承于这个类,这种方式改动太大了,不可取;第二种是用 category 的方式实现这个方法,这种方式会影响到整个工程所有的 view ,这种方式也不太好。

为了解决问题 1 和 2,可以每个 subview 做一个标记是否被观察了。为了解决问题 3 和 4,可以引入一个专门观察 subview 的类 AAObserver,然后 superview 持有这个类的实例。

以下是对象的引用关系,实线代表强引用,虚线代表弱引用:
引用关系

addSubview 的时候 addObserver,当 removeFromSuperview 的时候 removeObserver。但是当 controller 退出时 superview 自动释放时,导致 subviews 也会自动 removeFromSuperview, 因为我们无法获取 removeFromSuperview 的回调,这时候我们怎么 removeObserver 呢?看上面的引用关系图,因为 observer 是对 subviews 强引用的,所以 observer 的释放肯定在 subviews 的释放之前, superview 释放会导致 observer 释放,我们可以在 observiewdealloc 方法里做 removeObserver。 这就巧妙地解决了没移除观察者的问题。

github地址:https://github.com/qhd/AASubviews

AASubviews.zip (436.66 KB, 下载次数: 31)

我来说两句
*滑动验证:
所有评论(5)
逆鳞九霄 2017-12-25 12:04:30
楼主用心了,内容非常精彩。
回复
phoiu 2017-12-25 12:06:03
小弟学习了~支持,支持
回复
kengsir 2017-12-25 12:06:48
我是来学习的
回复
BlueManlove 2017-12-25 12:08:32
code4app好的代码demo真的很多,谢谢啦~
回复
littleRed 2017-12-25 12:08:58
小弟学习了~支持,支持
回复
AlonMessi 2017-12-25 12:11:08
mark,收藏了
回复
hellokenken 2017-12-25 12:17:20
感谢大神~
回复
code4app热心网友 2017-12-25 14:37:39
淡定,淡定,淡定……
回复
code4app热心网友 2017-12-26 08:54:51
感谢分享,Code4App有你更精彩:)
回复
提取码:  下载次数:21 状态:已购或VIP 售价:0(原价:15)金钱 下载权限:初级码农 
551 0 21
联系我们
首页/微信公众账号投稿

帖子代码编辑/版权问题

QQ:435399051,742864542


代码贡献英雄榜
用户名 下载数
通过邮件订阅最新 Code4App 信息
上一条 /4 下一条
联系我们
关闭
合作电话:
13802416937
Email:
435399051@qq.com
商务市场合作/投稿
问题反馈及帮助
联系我们

广告投放| Github|申请友链|手机版|Code4App ( 粤ICP备15117877号-1 )

快速回复 返回顶部 返回列表