ViewConfigurator
设置视图的整洁方式!
动机和用法
一些iOS开发者喜欢使用Storyboard,而另一些则喜欢将所有视图和约束都在代码中创建。虽然我们不希望偏袒任何一种方法,但这个库是为后者准备的。
在代码中创建和配置视图时,需要写很多行代码。如果在viewDidLoad()中完成所有操作,将会导致一个浩瀚的方法。
Swift允许我们在声明视图的地方直接实例化和配置它们。甚至可以使用实例变量,如果您声明了视图是懒加载的。例如
struct ExampleColorModel {
let primaryColor: UIColor
let secondaryColor: UIColor
}
class ExampleViewController: UIViewController {
let model: ExampleColorModel = ExampleColorModel(primaryColor: .yellow, secondaryColor: .blue)
let myView: UIView = {
let view = UIView()
view.backgroundColor = .blue
view.alpha = 0.8
view.layer.cornerRadius = 8
view.layer.borderColor = UIColor.red.cgColor
view.layer.borderWidth = 0.5
view.frame = CGRect(x: 0, y: 0, width: 50, height: 50)
return view
}()
lazy var someLazyView: UIView = {
let view = UIView()
view.backgroundColor = self.model.primaryColor
view.alpha = 0.8
view.layer.cornerRadius = 8
view.layer.borderColor = self.model.secondaryColor.cgColor
view.layer.borderWidth = 0.5
view.frame = CGRect(x: 0, y: 0, width: 50, height: 50)
return view
}()
}
我们希望使用这个库达到更高的“Swift风格”。
我们的想法是创建可重用的ConfigurationSets,然后应用到实例上。
使用ViewConfigurator,我们的示例现在看起来像这样
struct ExampleColorModel {
let primaryColor: UIColor
let secondaryColor: UIColor
}
struct ExampleConfigurations {
static let standard = UIView.config
.alpha(0.8)
.cornerRadius(8)
.borderWidth(0.5)
.backgroundColor(.blue)
.borderColor(UIColor.red.cgColor)
.frame(CGRect(x: 0, y: 0, width: 50, height: 50))
}
class ExampleViewController: UIViewController {
let model: ExampleColorModel = ExampleColorModel(primaryColor: .yellow, secondaryColor: .blue)
let myView = UIView()
.apply(ExampleConfigurations.standard)
lazy var modelConfiguration = UIView.config
.backgroundColor(self.model.primaryColor)
.borderColor(self.model.secondaryColor.cgColor)
lazy var someLazyView = UIView()
.apply(ExampleConfigurations.standard)
.apply(self.modelConfiguration)
}
如果您有一个只使用一次的配置,也可以直接这样做,而无需事先创建配置对象。
lazy var anotherView = UIView().config
.backgroundColor(self.model.primaryColor)
.borderColor(self.model.secondaryColor.cgColor)
.finish()
还可以对配置进行分组
struct ExampleConfigurations {
static let standard = UIView.config
.alpha(0.8)
.cornerRadius(8)
.borderWidth(0.5)
static let shadow = UIView.config
.shadowColor(UIColor.yellow.cgColor)
.shadowOffset(CGSize(width: 3, height: 3))
static let standardWithShadow = standard
.append(shadow)
}
如果您的UIView子类有自定义属性,并且您想对它们进行配置,您可以使用通用的set方法。这将在配置期间调用一个自定义的闭包。请注意,在这样做时要小心。没有阻止您通过这种方式引入副作用,并且强烈不建议这样做。
static let custom = MyCustomView.config
.alpha(0.8)
.set({
$0.customProperty = "i am special"
})
更好的解决方案是扩展ConfigurationSet以支持您自定义的属性。
class MyViewSubclass: UIView {
var anotherConfiguration: Bool = false
}
extension ConfigurationSet where Base: MyViewSubclass {
func anotherConfiguration(_ newValue: Bool) -> Self {
return set { (configurable: MyViewSubclass) in
configurable.anotherConfiguration = newValue
}
}
}
需求
- iOS 8.0+
- Xcode 9.0+
- Swift 4+
安装
CocoaPods
CocoaPods 是 Cocoa 项目的依赖管理器。您可以使用以下命令进行安装
$ gem install cocoapods
要构建 ViewConfigurator 0.1.0+,需要 CocoaPods 1.1.0+。
要使用 CocoaPods 将 ViewConfigurator 集成到您的 Xcode 项目中,请在 Podfile
中指定它
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
use_frameworks!
pod 'ViewConfigurator', '~> 1.0.0'
然后,运行以下命令
$ pod install
Carthage
Carthage 是一个去中心化的依赖管理器,它可以自动化向 Cocoa 应用程序添加框架的过程。
您可以使用 Homebrew 通过以下命令安装 Carthage
$ brew update
$ brew install carthage
要使用 Carthage 将 ViewConfigurator 集成到您的 Xcode 项目中,请在 Cartfile
中指定它
github "ImagineOn/ViewConfigurator" ~> 1.0.0
Swift Package Manager
要将 Configurator 作为 Swift Package Manager 包使用,只需在您的 Package.swift 文件中添加以下内容。
import PackageDescription
let package = Package(
name: "ViewConfigurator",
dependencies: [
.Package(url: "https://github.com/imagineon/ViewConfigurator.git", "1.0.0")
]
)
手动
如果您不希望使用上述任何依赖管理器,您可以手动将配置器整合到您的项目中。
Git 子模块
- 打开终端,使用
cd
命令进入您的顶级项目目录,并且如果您的项目尚未初始化为 git 仓库,则运行以下命令
$ git init
- 通过运行以下命令将配置器添加为 git 子模块
$ git submodule add https://github.com/imagineon/ViewConfigurator.git
$ git submodule update --init --recursive
-
打开新的
ViewConfigurator
文件夹,并将ViewConfigurator.xcodeproj
拖入您的应用 Xcode 项目的 Project Navigator。它应该出现在您的应用蓝色项目图标之下。它是在所有其他 Xcode 组的上方还是下方并不重要。
-
在 Project Navigator 中选择
ViewConfigurator.xcodeproj
,并验证部署目标是否与您的应用目标相符。 -
接下来,在 Project Navigator(蓝色项目图标)中选择您的应用项目,转到目标配置窗口,并在侧边栏的“targets”标题下选择应用目标。
-
在该窗口的标签栏上,打开“General”面板。
-
在“Embedded Binaries”部分下点击
+
按钮。 -
您将看到两个不同的
ViewConfigurator.xcodeproj
文件夹,每个文件夹中都有一个不同的ViewConfigurator.framework
版本嵌套在“Products”文件夹中。您可以选择哪个“Products”文件夹并不重要。
-
选择
ViewConfigurator.framework
。 -
就这么多!
ViewConfigurator.framework
将自动添加为目标依赖,链接框架和内嵌框架,在复制文件的构建阶段中,这些都是您在模拟器和设备上构建所需的。
待办事项
在未来,我们希望提供一些方便的配置,例如使用 UIColor 进行 CGColor 配置,阴影配置集,以及像 ReactiveCocoa 这样的第三方库的扩展。我们还希望提供一个版本,它会在每次构建时生成,并能够配置自定义 UIView 子类添加的属性。目前,配置集的基类必须与应用的视图类型相同。允许对子类应用配置将会很方便。
贡献
库的大部分代码是在Sourcery (https://github.com/krzysztofzablocki/Sourcery/), SourceKitten (https://github.com/jpsim/SourceKitten) 框架和 Stencil 模板语言 (https://github.com/kylef/Stencil) 的帮助下生成的。Chain 框架在我们获取到SourceKitten分析UIKit的解决方案中发挥了巨大的作用。https://github.com/sidmani/Chain
代码生成
库的大部分部分是通过Sourcery分析UIKit的Swift界面生成的。这些界面是在SourceKitten的帮助下创建的。由于几个原因,我们不希望在每次构建时都重新生成。目前,我们无法区分只读属性和可设置属性,所以许多生成的代码将无法编译。
当前问题
在库生成过程中无法过滤只读属性。函数的代码生成是基于具有特定前缀(“set”,“add”,“remove”)的函数,可能还有其他的。对于“set”前缀,我们尝试从生成的函数中移除它,但Stencil的过滤能力仅允许替换。目前没有生成UIView子类列表。目前相关类型配置集之间的互操作性仅限于对子类的基类配置应用。目前还没有结合两个配置集的功能。
许可
ViewConfigurator是在MIT许可下发布的。有关详细信息,请参阅LICENSE。