ASDKFluentExtensions 0.8.2

ASDKFluentExtensions 0.8.2

测试已测试
语言语言 Obj-CObjective C
许可证 MIT
发布最后发布2018年4月

Cesar Estebanez Tascon 维护。



  • 作者
  • Cesar Estebanez

ASDKFluentExtensions

ASDKFluentExtensions 是一组 Objective-C 分类,它为 Texture 提供了用于布局代码的流畅接口。这种流畅风格更直观,提高了可读性(更少需要查看视觉结构),并使布局更简洁且易于维护。它还允许布局规范和样式的 组合

想象一下你想要叠加一张图像和渐变。然后将渐变叠加到标题上,该标题必须位于渐变的右下角,并且有一些内边距。最后,整个内容的宽高比应该是 1。使用 ASDKFluentExtensions,你可以编写如下布局代码

override func layoutSpecThatFits(_ constrainedSize: ASSizeRange) -> ASLayoutSpec {
  return imageNode
    .withOverlay(gradientNode
      .withOverlay(titleNode
        .withRelativePosition(horizontal: .end, vertical: .end)
        .withInset(UIEdgeInsetsMake(.infinity, .infinity, 4, 4))))
    .withRatio(1)
}

ASDisplayNodeASLayoutSpec 子类都可以使用此流畅语法包裹在 ASLayoutSpec 中。只需开始键入 .with 并查找适当的补全

autocompletion with

所有 ASDKFluentExtensions 方法都返回一个遵守 ASLayoutElement 协议的对象,因此流畅布局可以相互链接。此外,对 style 属性的修改也可以与布局定义组合起来。这样,信息以有意义的方式流动。以下是如何修改 flexGrowalignSelf 的示例

func layoutSpecThatFits(_ constrainedSize: ASSizeRange) -> ASLayoutSpec {
  return ASStackLayoutSpec
    .vertical()
    .withSpacing(20)
    .withJustifyContent(.center)
    .withChildren([
      topSeparator
        .withFlexGrow(1.0),
      textNode
        .withAlignSelf(.center),
      bottomSeparator
        .withFlexGrow(1.0)
      ])
    .withInset(UIEdgeInsets(top: 60, left: 0, bottom: 60, right: 0))
}

ASDKFluentExtensions 还提供了对 ASStackLayoutSpecASAbsoluteLayoutSpec 的分类,使其能够以非常可读的风格将规格内联到布局代码中

func fluentLayoutSpecThatFits(_ constrainedSize: ASSizeRange) -> ASLayoutSpec {
  return ASAbsoluteLayoutSpec()
    .withSizing(.sizeToFit)
    .withChildren([
      photoNode
        .withPreferredSize(CGSize(width: 150, height: 150))
        .withLayoutPosition(CGPoint(x: 40 / 2.0, y: 40 / 2.0)),
      iconNode
        .withPreferredSize(CGSize(width: 40, height: 40))
        .withLayoutPosition(CGPoint(x: 150, y: 0))])
}

甚至有一个方便创建间距的分类!

let header = ASStackLayoutSpec().withChildren([userName, ASLayoutSpec.spacer(), lastTimeOnline])

最后,这是一个更复杂的示例,将知名示例 ASDKgram-Swift 中的 PhotoTableNodeCell 的布局代码重新编写为使用流畅布局

func layoutSpecThatFits(_ constrainedSize: ASSizeRange) -> ASLayoutSpec {
  return ASStackLayoutSpec
    .vertical()
    .withChildren([
      ASStackLayoutSpec()
        .withAlignItems(.center)
        .withChildren([
          avatarImageNode
            .withPreferredSize(CGSize(width: Constants.CellLayout.UserImageHeight, height: Constants.CellLayout.UserImageHeight))
            .withInset(Constants.CellLayout.InsetForAvatar),
          usernameLabel
            .withFlexShrink(1),
          ASLayoutSpec.spacer(),
          timeIntervalLabel
            .withSpacingBefore(Constants.CellLayout.HorizontalBuffer)
          ])
        .withInset(Constants.CellLayout.InsetForHeader),

      photoImageNode.withRatio(1),

      ASStackLayoutSpec
        .vertical()
        .withSpacing(Constants.CellLayout.VerticalBuffer)
        .withChildren([
          photoLikesLabel,
          photoDescriptionLabel])
        .withInset(Constants.CellLayout.InsetForFooter)
      ])
}

此布局从上到下连续读取。最外层的代码定义了一般结构,内部部分定义了细节。信息以有意义的方式流动,因此需要更少的视觉扫描。此外,添加、删除和重新组织规范(例如在调试或原型设计期间)更快。最后,请注意如何将样式属性的修改与布局规范组合(请参阅与布局规范定义内联的 withPreferredSizewithFlexShrink 的用法)。这避免了如何使代码视觉上流畅的干扰。

关于流畅接口的更多信息

如果你想要了解更多关于流畅API的,请务必查看这篇论文,其中Martin Fowler和Eric Evans首次提出了这个术语。

文档

在这个Texture的分支中有关于如何使用ASDKFluentExtensions来编写流畅布局代码的几个示例。这些示例是主Texture仓库中现有示例的克隆,经过修改以展示ASDKFluentExtensions。目的是让人们想要接近这种流畅语法的可以有一系列熟悉的示例可供参考。

这是目前可用示例的列表

安装

ASDKFluentExtensions目前支持Cocoapods和Carthage。

Cocoapods

你可以使用Cocoapods安装ASDKFluentExtensions。将以下pod添加到你的Podfile中

target 'MyApp' do
  pod "ASDKFluentExtensions"
end

然后运行以下命令

$ pod install

务必导入头文件

#import <ASDKFluentExtensions/ASDKFluentExtensions.h>

Carthage

从版本0.6开始,你可以使用Carthage构建ASDKFluentExtensions。将以下行添加到你的Cartfile中

github "cesteban/ASDKFluentExtensions" >= 0.6

然后构建框架

carthage update

最后,按常规将生成的框架添加到你的项目中。

讨论

ASDKFluentExtensions 是对 ASDisplayNodeASLayoutSpecASStackLayoutSpecASAbsoluteLayoutSpec 的一系列 Objective-C 分类,它创建并返回期望的布局规范,并将 self 作为子节点传递

- (ASOverlayLayoutSpec *)withOverlay:(id<ASLayoutElement>)overlay
{
  return [ASOverlayLayoutSpec overlayLayoutSpecWithChild:self overlay:overlay];
}

ASDKFluentExtensions 还提供了一系列分类来修改 ASDisplayNodeASLayoutSpecstyle 属性,返回 self

- (instancetype)withPreferredSize:(CGSize)preferredSize
{
    self.style.preferredSize = preferredSize;
    return self;
}

这使得布局和样式变得 可组合,并使 API 非常易于阅读

代码重复和 Swift 协议扩展

为了为 ASDisplayNodeASLayoutSpec 提供相同的功能,存在大量的代码重复。

这可以在 Swift 中通过在 ASLayoutElement 上使用协议扩展来避免,但这种情况下 API 将无法从 Objective-C 访问。另一方面,Texture 是一个纯 Objective-C 框架,因此使用 Swift 扩展它将引入限制。请查看这里 ASDKFluentExtensions 的原始 Swift 实现,非常早期就放弃了,转而使用当前的 Objective-C API。

贡献

发送您所有的反馈,并请贡献。对如何改进此组件的拉取请求和建议非常欢迎。