适用于iOS的AsyncDisplayKit里面有什么
以Pinterest为例,Pinterest主屏幕是一个ASCollectionNode,每个Pin是一个ASCellNode,其中包含ASNetworkImageNodes,ASTextNodes。 在屏幕上,Pinterest的Pin的生命周期将经历从初始到可见的状态:
- 初始状态:ASCollectionNode在Pin节点上运行批量计算。 引脚节点从子节点获取布局规格,然后为其子视图计算布局。 结果为
_calculatedDisplayNodeLayout
,其中包含所有节点的框架。 - 预加载状态:引脚的网络图像节点触发后台线程延迟加载图像url,从而导致本地UIImage。
- 显示状态:在此状态下,节点将先前状态中的图像绘制到CoreGraphic的位图中,从而得到已解码内容,该内容已准备好在主线程中可见。
- 可见状态:几乎处于主线程中。
layoutSublayouts
从初始状态获取_calculatedDisplayNodeLayout
以便设置框架。 图像节点渲染解码内容。
如果节点在当前状态尚未完成时进入下一状态怎么办?
如果图像节点尚未下载图像而进入显示状态,它将显示占位符。 下载完成后,图像触发再次显示。
如果在尚未完成批计算的情况下收集节点进入“显示”状态,则它将在主线程中运行布局(仅在第一次出现时)。 它足够智能,可以先计算可见节点,然后显示/预加载节点。 还要记住,计算是在多线程concurrent中同时运行的。
异步意味着在后台线程中进行操作,因此为了释放主线程的工作量,Concurrently可以利用CPU多核来减少在主线程中可用的时间。
AsyncDisplayKit的布局
如果您熟悉CSS盒模型,则ASDK的布局是CSS布局(填充,位置:相对,..)和FlexBox的子集。
如果您熟悉UIStackView,则ASDK的ASStackLayoutSpec类似于UIStackView,可以扩展子视图,并支持flex-spacing和对齐方式。
如果您仍然不知道ASDK的布局如何,请查看快速入门,一些示例和FlexBox。
布局规格
布局系统包含定义如何在屏幕上布局视图的组件。 ASDK布局的组件包括:
- ASStackLayoutSpec:ASDK布局的核心是堆栈规范。 堆栈规格沿其水平宽度或垂直高度散布其子视图。 与UIStackView不同的是,始终在开始时就吸引“重力”子视图,堆栈规范允许在中心,末端甚至相等的分布间距吸引“重力”子视图。
- ASInsetLayoutSpec:类似于CSS填充样式,允许您在内部插入。
- ASRatioLayoutSpec,ASRelativeLayoutSpec:虽然ASRatioLayoutSpec允许您按比例考虑-而不是固定的宽度-高度,但ASRelativeLayoutSpec允许您考虑相对位置-而不是绝对位置。
- ASOverlayLayoutSpec:拉伸布局规格以覆盖另一个规格。
- 还有其他一些布局规范
ASDK的布局将上述所有布局规格组合在一起,以定义屏幕的布局。
为什么这个? 自动版式仍然存在。
ASDK设计其布局系统时,目标之一是使其足够简单,不仅运行速度快,而且易于实现。
与AutoLayout相比,ASDK要求所有节点必须具有固有大小或显式设置其大小。 例如,ASImageNode需要显式设置.preferedSize
。
与AutoLayout相比,ASDK不允许您在具有父级以上父级的子节点之间定义约束。 例如,您不能说:“我不知道图像的尺寸,但要使其宽度等于其父级的宽度”。 而且也无法定义子节点之间的大小约束。
以上两个要求使布局计算更加简单。 ASLayoutSpec的calculateLayoutThatFits:
方法只需要执行一次即可从子节点获取所有信息,然后计算最终帧,而无需关心父级的约束。
//ASRatioLayoutSpec.mm
-(ASLayout *)calculateLayoutThatFits:(ASSizeRange)constrainedSize
{
...
//选择最接近所需比例的尺寸。
const auto &bestSize = ...;
const ASSizeRange childRange =(bestSize == sizeOptions.end())吗? constrainedSize:ASSizeRangeIntersect(constrainedSize,ASSizeRangeMake(* bestSize,* bestSize));
const CGSize parentSize =(bestSize == sizeOptions.end())吗? ASLayoutElementParentSizeUndefined:* bestSize;
ASLayout * sublayout = [ self .child layoutThatFits:childRange parentSize:parentSize];
sublayout.position = CGPointZero;
返回 [ASLayout layoutWithLayoutElement: self size:sublayout.size sublayouts:@ [sublayout]];
}
另一个目标是使ASDK的布局功能强大到足以定义甚至复杂的布局并支持多分辨率。 仅使用ASStackLayoutSpec,ASOverlayLayoutSpec,ASCenterLayoutSpec,我们就可以定义布局,例如Pinterest。
为什么LayoutSpec只是一个“规范”?
为了在主线程之外运行布局系统,ASDK需要从视图中删除布局规范。 返回到AutoLayout,当您创建约束时,需要使用2个UIViews对其进行初始化。 由于UIViews属于主线程,因此无法根据主线程计算布局。
另一个好处是,您无需在中间创建“容器” UIView,而只需对齐,间隔,覆盖……信息视图即可。 还记得当您将某些UIViews分组到一个容器视图中然后将该容器视图居中显示在屏幕上时吗?
如果您不使用ASDK进行布局怎么办
–减少单元格内容中的UIViews数量。
–减少单元格内容中的深度视图层次。
–手动预先计算单元格的高度(请参见此处),标签的大小,图像的大小(在下载模型页面后),将其缓存在模型中,然后在heightForCellAtIndex:和layoutSubViews:中使用(不要使用AutoLayout)。
–使用ASDK是最后的选择。
其他UI处理作品
主线程 文本栅格化
ASDK团队付出了巨大的努力来构建自己的TextKit引擎。 TextKit引擎计算文本的框架并将其绘制到CoreGraphic位图中,然后返回主线程进行渲染。
如果您不使用ASDK,该怎么办:
您将所有TextKit文件夹从ASDK复制到您的项目=]]。 但要注意许可:v
CornerRadius详细信息 :
在Pinterest主屏幕中查看Pin的图像? 剪裁成4个角以显示该系列的白色背景。
_photoNode.willDisplayNodeContentWithRenderingContext = ^(CGContextRef上下文){
CGRect范围= CGContextGetClipBoundingBox(context);
[[UIBezierPath bezierPathWithRoundedRect:bounds cornerRadius:10] addClip];
};
这种方法称为预合成的Alpha角。 缺点是:由于GPU的alpha混合以及集合内容的白色背景,因此引入的开销很小。
另一种方法是将集合的白色背景合成到图像中,称为预合成的不透明角。 ASDK通过在UIImage+ASConvenience.m
生成4个叠加角的方法来支持它:
+(UIImage *)as_resizableRoundedImageWithCornerRadius:(CGFloat)cornerRadius cornerColor :( 可为空的 UIColor *)cornerColor fillColor:(UIColor *)fillColor AS_WARN_UNUSED_RESULT;
_photoNode.willDisplayNodeContentWithRenderingContext = ^(CGContextRef上下文){
CGRect范围= CGContextGetClipBoundingBox(context);
UIImage * overlay = [UIImage as_resizableRoundedImageWithCornerRadius:10 cornerColor:[UIColor whiteColor] fillColor:[UIColor clearColor]];
[overdrawInRect:bounds];
[[UIBezierPath bezierPathWithRoundedRect:bounds cornerRadius:10] addClip];
};
ew,今天足够了。 让我们休息一下,吃点东西,看地精电影。
关于ASDK的本系列文章的第2部分中有什么内容?
在第2部分中,我将在以下内容中回顾ASDK:体系结构,模式,预加载,自动子节点管理。
阅读更多
如果您想学习如何使用ASDK,请查看raywenderlich.com上的两部分教程:
https://www.raywenderlich.com/124311/asyncdisplaykit-2-0-tutorial-getting-started
在UITableViews中完美平滑滚动
关于在iOS最常用的构建基块 medium.com中达到60 FPS的优化的故事 圆角倒角
关于圆角处理,许多开发人员都坚持使用CALayer的.cornerRadius属性。 不幸的是,这… asyncdisplaykit.org