StateView是一个UIView替代品,当数据变化时,它会自动更新自己。
内容
StateView是UIView的子类,它采用现代思维和灵感,从Facebook对React和DOM所做的工作中汲取灵感,使显示和更新视图变得更加简单、简单和愉快。
使用StateView……
当您创建第一个StateView时,您将熟悉
您可以使用
props 和state 都允许类型为Any
的值,以鼓励您保留和传递任何适用于您的值。
当您在render()
内部向StateView添加第一个子视图时,您会熟悉place()
的使用。
您可以使用place()
将子视图添加到您的StateView中。然后,您的StateView将自动调用addSubview
和removeSubview
,您无需手动操作。
在render()
中,只需查看您的state
和任何传入的props
,然后编写如下代码...
override func render() {
if let selectedImage = self.state["selectedImage"] as? UIImage {
place(ImageViewWithTags.self, "image") { make in
make.size.equalTo(self)
make.center.equalTo(self)
}
} else {
place(PlaceholderImageView.self, "placeholder") { make in
make.size.equalTo(self)
make.center.equalTo(self)
}
}
}
如果在state
中,键“selectedImage”包含一个UIImage,则放置一个‘ImageViewWithTags’,此键名为“image”,并提供一些AutoLayout约束(使用名为SnapKit的优秀库)。如果在state
中,“selectedImage”为nil或完全缺失,则使用占位符ImageView代替。
简单地更新数据,视图将自动更新。
更改state
中“selectedImage”的值,此StateView将显示或隐藏名为ImageViewWithTags的另一个自定义StateView。您的StateView将自动调用addSubview
和removeSubview
以渲染更新的视图。
这样使用render()
和place()
,是使用StateView最有趣的方面之一。
您用于决定添加到StateView的子视图的代码可以放在render()
中,这将使数据更改时运行。然后,将render()
的输出与上一轮render()
的输出进行比较,您的StateView仅组成差异部分。
您可以使用props
从一个StateView传递值到另一个StateView。您可以以此方式在StateView的state
中传播新的数据到其子视图。在这个例子中,要将state
中的新图片传递到ImageViewWithTags中,可以编写如下代码...
override func render() {
if let selectedImage = self.state["selectedImage"] as? UIImage {
let imageView = place(ImageViewWithTags.self, "image") { make in
make.size.equalTo(self)
make.center.equalTo(self)
}
imageView.prop(forKey: Home.image, is: selectedImage)
} else {
place(PlaceholderImageView.self, "placeholder") { make in
make.size.equalTo(self)
make.center.equalTo(self)
}
}
}
现在这个ImageViewWithTags实例将接收到props
中的selectedImage。ImageViewWithTags可以访问selectedImage的新值,在任何方法中,特别是在其自己的render方法中更新一个UIImageView。
ImageViewWithTags可以通过使用在这里使用的相同键来访问selectedImage的值,即Home.image
,这是一个枚举。您可以根据需要创建任意数量的自定义枚举来命名您的值。只要状态中的selectedImage有新的值,ImageViewWithTags就会接收到新值并更新自身。
放置函数中的第二个值是key
,用于帮助理解渲染间相同视图。key
的值可以是您想要的任何内容,只要那个StateView中的其他子视图没有相同的键。如果放置某个内容的key
在渲染间发生变化,由于没有使用新的key
放置的现有视图可以保留,StateView将从头开始渲染该子视图。
当您创建第一个StateView时,您将熟悉以下思路过程
state
中留下变量来描述这些不同变化。render()
中,当state
有该键的这个值时,我应该放置这个子视图,但如果它有该键的另一个值,我应该放置另一个。props
,因此我可以将此StateView接收到的两个props
传递给该StateView。state
中值的代码是什么?哦,这里的回调。我应该在这个StateView的state
中将此键的初始值添加,这样在回调返回之前,我的render
就有了一个具体的使用来决定显示什么。render
中是否有其他我应该添加的内容?当我的数据显示这样而不是那样时,有没有需要在视图中微妙不同的地方?有关StateView的完整文档和入门指南可在这里找到,以及入门指南。
Frame(Frame的GitHub链接)是使用StateView开发的首个应用。使用StateView,Frame只包含四个类,其中三个类的代码行数都不到一百行。
SwiftHub是一个iOS应用,用于展示GitHub上的Swift代码库。
当您使用StateView时,有一个ShadowView在幕后帮助理解哪些子视图可以保留,哪些可以去除,以及哪些可以在调用render()之间进行刷新。
每个StateView实例都对应一个ShadowView实例,它使用轻量级的结构和引用来记录视图层次结构及其所表示的数据。
render()和place()都紧密与StateView的ShadowView协作,以最少更改视图层次结构来更新屏幕上的显示。
当您的某个视图中的state发生变化时,ShadowView负责计算diff、添加或删除任何所需的或不再需要的子视图,并将props从StateView传递到其包含的StateView。
您可以通过CocoaPods安装StateView。
pod 'StateView'
StateView旨在给iOS开发者提供一个安全、简单的方式来观察视图自行更新。最重要的是,目标是让StateView易于使用。
任何使StateView包含的方法、参数和模式更简单的努力都备受赞赏。同样,对StateView性能的提升也很受欢迎。
如果您想做出贡献,请查看wiki中已知的Issue列表,或在此项目的Issues中发起新的对话!
StateView由Sahand Nayebaziz编写。StateView受到了React和DOM的启发。
StateView在MIT许可下发布。有关详细信息,请参阅LICENSE文件。