TemplateKit 0.1.0

TemplateKit 0.1.0

测试已测试
Lang语言 SwiftSwift
许可 MIT
发布最后发布2016年11月
SwiftSwift 版本3.0
SPM支持 SPM

Matias Cudich 维护。



 
依赖
CSSParser~> 1.0
CSSLayout~> 1.0
 

TemplateKit

React 启发的 Swift 构建组件化用户界面框架。

特性
🐤 完全原生 - 使用 Swift 编写您的应用程序
📃 声明式 - 使用标记语言定义您的 UI
📦 组件 - 将功能封装到可复用块中
📐 布局 - Flexbox 布局,就像网页上一样
🖋 状态 - 自动将状态更改刷新到 UI
比较 - 仅刷新 UI 中的最小更新集
🚀 性能 - diffing 和布局在后台线程上运行
动画 - 内置支持动画任何属性

示例

您可以使用一种简单的标记语言定义您的 UI,这种语言吸取了 HTML 和 CSS 的灵感。该 UI 定义被渲染成原生元素的树。

Component.xml

<template>
  <style>
    #container > .button {
      color: #000;
    }

    #container > .button-selected {
      color: #f00;
    }
  </style>

  <box id="container">
    <text text="$properties.title" />
    <text text="Click me!" onTap="handleClick" classNames="$textClasses" />
  </box>
</template>

Component.swift

功能和使用状态封装成组件,这些组件如处理用户事件和刷新状态到 UI。组件有强类型的 StateProperties 值,这些值用于确定最终的 UIKit 中推出的内容。

struct ComponentState: State {
  var selected: Bool?
}

struct ComponentProperties: Properties {
  var core = CoreProperties()
  var title: String? = "This is a default title"
}

class MyComponent: CompositeComponent<ComponentState, ComponentProperties, UIView> {
  // Stored properties on the component are made available to template.
  var textClasses: String?

  // As are functions, referenced by their selector name.
  @objc func handleClick() {
    updateComponentState { state in
      state.selected = !state.selected
    }
  }

  override func render() -> Element {
    textClasses = state.selected ? "button" : "button-selected"

    return render("https://:8000/Component.xml")
  }
}

ViewController.swift

渲染组件就像调用一个 render 函数一样简单,该函数异步计算并刷新组件到提供容器视图。

override func viewDidLoad() {
  super.viewDidLoad()

  UIKitRenderer.render(component(MyComponent.self), container: self.view, context: self) { component in
    self.component = component
  }
}

查看包含的 示例 项目以获取如何使用 TemplateKit 的更多示例。

为什么使用TemplateKit?

Swift

因为您喜欢完全使用 Swift 编写应用程序。TemplateKit 是完全原生的且编译的。

声明式风格

以声明式风格编写用户界面可以更轻松地推理模型数据和用户操作如何影响渲染内容。提供开箱即用的XML支持。如果要添加自己的模板格式(例如,协议缓冲区),则可扩展。

组件

组件使得将应用程序功能封装成可重用的构建块变得容易。然后可以将这些块组合起来,以创建更复杂的界面。

布局

基于Flexbox的布局原语使用户能够使用类似于现代浏览器中的丰富布局系统。

异步渲染 & 性能

所有布局计算、文本大小调整、树差异处理、图像解码都在后台执行。这保持了主线程空闲以响应用户操作。只会将更新视图层次结构所需的最小更改集真正刷新到渲染视图中。

CSS

像在网页上一样使用样式表为组件设置样式。

动画

使用直观的API对布局、样式和任意属性进行动画处理。

实时重新加载

无需重新构建二进制文件或重启应用程序即可自动重新加载用户界面的更改。可在开发和生产环境中使用。

可扩展

添加自定义组件、自定义原生视图、自定义模板加载方案等。

易于尝试

将其插入到您的应用程序中的任何位置,用于渲染视图。与世界其余部分兼容良好。

要求

  • iOS 9.3+
  • Xcode 8.0+
  • Swift 3.0+

沟通

  • 如果 找到了错误,请打开一个问题。
  • 如果 有功能请求,请打开一个问题。
  • 如果 希望贡献力量,请提交拉取请求。

它是如何工作的?

在核心上,TemplateKit由ElementNode实例组成。Element用于描述节点的树,节点可以是实现Node接口的任何内容。节点用于提供和管理视图层次。

开箱即用,有几个Node实现,使得设置UI层次结构变得容易:如ComponentViewNode,以及一系列原生控件,如按钮、文本标签、文本字段等。

构建组件非常简单,只需继承Component、覆盖其render()函数,并决定其可能接受的属性集合并将其用作渲染的一部分。简单的render()需要返回一个Template,这可以通过程序构造,也可以通过XML文档(或其他自定义负载)。到达渲染组件到视图的时间时,您只需调用UIKitRenderer.render并将包含您的组件的渲染输出的视图传入。这会反过来调用您的组件实例中的render(),计算视图树的布局和样式,构建这个树,然后根据适当的情况将其布局和样式应用到上面。

当需要更新组件状态时,您可以在组件实现中调用updateState。此函数接受一个函数,该函数将当前的状态值传递给(每个Component可以声明一个State类型,就像它声明一个Properties类型一样)。然后,该函数会将组件的更新入列,这将导致组件重新渲染,考虑状态所做的任何更改。此更新是智能的,将渲染的视图树当前版本与建议的元素树进行比较。只有两个之间相等的变化会刷新到视图层。

不透明视图

如果您的UI中有部分以普通UIViews更容易处理,TemplateKit提供了一种简单封装,称为NodeViewNode,允许您将这些“不透明”视图作为TemplateKit管理的任何树的一部分包括在内。TemplateKit不会干涉,只是为您设置这些视图的frame,因此它们可以很好地位于您所组成的任何UI树中。

集合

TemplateKit提供可加载数据的子类,并异步调整大小和渲染Components到cell中的功能,只需进行一点配置就能使用UITableViewUICollectionView。表格和集合可以通过TableCollection组件使用,或者简单地将它们作为ViewNode实例包装。表格和集合组件具有内置的diff支持,因此数据源更新将导致所需的最小操作集,以使相应的UIKit视图反映数据更改。更多信息请见Diff.swift

这与React Native有什么不同?

TemplateKit是用Swift(以及一些C语言)实现的。如果您喜欢用Swift全部编写,那么这个框架可能适合您。

React Native依赖于一个非常经过测试的库(React),并且已经在一些流行的应用中发货一段时间了。这意味着它可能有很多待解决的问题,模板Kit还尚未面对,等等。

缺少什么?

很多。

尚不支持AppKit(尽管添加起来会很直接)。有很多的测试还没有写。性能测试还没有做。适用的完整CSS规范还没有支持。动画功能最基本。需要添加更多手势类型。等等。

如果您想添加某个东西,请提出功能请求或发送pull请求!

灵感来源

参见

如果TemplateKit不是您所寻找的,请查看以下其他优秀项目!