高性能且轻量级的 UIView, UIImage, UIImageView, UILabel, UIButton 等组件。
特性
- SwiftyView GPU 渲染图像和颜色
- SwiftyColor — 从十六进制获取颜色,从 UIColor 获取 colorRGBA 值,从 Image 获取颜色
- UIImage 扩展用于膨胀/缩放/圆角
- 自动清除内存中的图像缓存
- SwiftyImageView 扩展 10+ 动画效果
- SwiftyImageView 比 UIImageView 高 150% 的性能,依赖于 UIView-package,Image-GPU 和 Image-Cache
- SwiftyLabel 比 UILabel 高 300% 的性能,依赖于 UIView-package 和 TextKit
- SwiftyButton 比UIButton 高 300% 的性能,依赖于 UIControl-package,TextKit 和 backgroundsImage-Advanced
- SwiftyToast 依赖于 globalCenter,可以在不重叠的情况下显示吐司。
- SwiftyAlert 包含 SuccessAlert,ErrorAlert,WarningAlert,InfoAlert,EditAlert 以及它们特殊的样式。
- 轻量级,几乎每个 UI 都有对应的类
- UI 加载线程安全
- Block-Package 使其使用更加方便
- 简单易用,所有 API 都与系统 API 一致
- SwiftyThreadPool 自动管理线程基于活跃的 CPU,并在内部运行 autorelease Runloop
- SwiftyPromise 是 PromiseKit 的轻量级版本,部分基于 JavaScript 的 A+ 规范,依赖于 ThreadPool,一个有趣的功能是它可以在一个 Promise 中在主线程和后台都使用
then
需求
- iOS 9.0+
- Xcode 9.0+ (Swift Package Manager 需要 Xcode 11.0+)
- Swift 4.2+
通信
- 如果您发现了缺陷,请提交问题。
- 如果您有功能请求,请提交问题。
- 如果您想贡献,请提交拉取请求。
安装
Swift Package Manager
Swift Package Manager 是一个用于管理 Swift 代码分发的工具。它与 Swift 构建系统集成,以自动化依赖项的下载、编译和链接过程。
需要 Xcode 11.0+。
要使用 Swift Package Manager 将 SwiftyUI 集成到您的 Xcode 项目中,将其添加到您的 Package.swift
文件的依赖项值中。
dependencies: [
.package(url: "https://github.com/haoking/SwiftyUI.git", .upToNextMajor(from: "1.0.0"))
]
CocoaPods
CocoaPods 是 Cocoa 项目的依赖项管理器。您可以使用以下命令安装它
$ gem install cocoapods
需要 CocoaPods 1.1+。
要使用 CocoaPods 将 SwiftyUI 集成到您的 Xcode 项目中,在您的 Podfile
中指定它。
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
use_frameworks!
target '<Your Target Name>' do
pod 'SwiftyUI'
end
然后,运行以下命令
$ pod install
使用方法
SwiftyView
SwiftyView 支持自动 GPU 渲染,展示颜色和图像。
import SwiftyUI
let myView : SwiftyView = SwiftyView().addTo(view)
myView.frame = CGRect.init(x: 50, y: 50, width: 100, height: 100)
您可以直接调用 UIView 的函数,它也拥有大多数 SwiftyView 的性能特性。
但若想获得完整的收益,我建议您使用 SwiftyView,实际上它继承自 UIView。
let myView : UIView = UIView()
view.addSubview(myView)
myView.frame = CGRect.init(x: 50, y: 50, width: 100, height: 100)
SwiftyColor
从十六进制获取颜色
从 UIColor 获取颜色RGBA值
import SwiftyUI
let myColor: UIColor = .hex(0xccff00) // .hex("333399")
let redFloat: CGFloat = myColor.redValue //greenValue, blueValue, alphaValue
从图像获取颜色,返回的 block 在主线程上执行
import SwiftyUI
myImage?.colors({ (background, primary, secondary, detail) in
print("background color: \(background)")
print("primary color: \(primary)")
print("secondary color: \(secondary)")
print("detail color: \(detail)")
})
UIImage 扩展
有几个 UIImage
扩展旨在使常见的图像处理操作尽可能简单。
图像扩充
let myImage : UIImage? = UIImage.load("aImage")
myImage.inflate()
在某些后台队列中扩充压缩图像格式(例如 PNG 或 JPEG)可以显著提高主线程上的绘制性能。
缩放
let myImage : UIImage? = UIImage.load("aImage")
let size = CGSize(width: 100.0, height: 100.0)
let scaledImage = myImage.reSize(to: size)
let scaledToFitImage = myImage.reSize(toFit: size)
let scaledToFillImage = myImage.reSize(toFill: size)
圆角
let myImage : UIImage? = UIImage.load("aImage")
let radius: CGFloat = 10.0
let roundedImage = myImage.rounded(withCornerRadius: radius)
let circularImage = myImage.roundedIntoCircle()
图片缓存
SwiftyUI中的ImageCachePool
充当了额外缓存层的作用。它是一个内存中的图片缓存,用于存储不超过给定内存容量的图片。当内存容量达到上限时,图片缓存会根据最后访问日期进行排序,然后连续清除最旧的图片,直到满足清除后的首选内存使用量。每次通过缓存访问图片时,都会更新图片的内部访问日期。
let imageCachePool : ImageCachePool = .defalut
添加/删除/获取图片
与ImageCache
协议API交互非常简单。
let imageCachePool : ImageCachePool = .defalut
let myImage : UIImage? = UIImage.load("aImage")
imageCachePool.add(myImage, withIdentifier: "myImage")
let cachedMyImage = imageCachePool.image(withIdentifier: "myImage")
imageCachePool.removeImage(withIdentifier: "myImage")
SwiftyImageView
SwiftyImageView继承了UIView和ImageSettable协议以及它们的扩展。同时还具备更好的性能。为SwiftyImagView
扩展提供基础。因为这些类、协议和扩展功能强大,所以SwiftyImagView
的API简洁、易于使用,并且功能丰富。
let myImage : UIImage? = UIImage.load("btnBG")
let myImageView : SwiftyImageView = SwiftyImageView(myImage).addTo(view)
myImageView.frame = CGRect.init(x: 50, y: 150 + 20, width: 100, height: 100)
SwiftyImageView 图片过渡
默认情况下,在ImageView上设置图片时没有图像过渡动画。如果您想添加交叉溶解或从底部翻转的动画,则需要指定有首选持续时间的ImageTransition
。
let myImage : UIImage? = UIImage.load("btnBG")
let myImageView : SwiftyImageView = SwiftyImageView(myImage).addTo(view)
myImageView.frame = CGRect.init(x: 50, y: 150 + 20, width: 100, height: 100)
let myTransition : SwiftyImageView.ImageTransition = .flipFromBottom(0.2)
myImageView.transition(myTransition, with: UIImage.load("aImage")!)
SwiftyLabel
SwiftyLabel的性能优于UILabel,可以像标准UI组件一样使用。同时,使用也比UILabel更简单。由于继承了UIView而不是UILabel,所以几乎没有多余的处理。它使用TextKit的功能来绘制字符。
let myLable : SwiftyLabel = SwiftyLabel("Label", .white, .blue).addTo(view)
myLable.frame = CGRect.init(x: 50, y: 300 + 20 + 20, width: 100, height: 100)
SwiftyButton
SwiftyButton的性能优于UIButton,可以像标准UI组件一样使用。它因为使用了block-package和错误双击忽略事件,使用起来比UIButton更简单。由于继承了UIControl而不是UIbutton,所以几乎没有多余的处理。它使用TextKit的功能来绘制字符和GPU的图像功能。
let myBtn : SwiftyButton = SwiftyButton("Button", myImage, ClosureWrapper({ [weak self] (btn) in
guard let strongSelf = self, let btn = btn else { return }
// do something
})).addTo(view)
myBtn.frame = CGRect(x: 50, y: 450 + 20 + 20 + 20, width: 100, height: 100)
SwiftyTimer
SwiftyTimer在RunLoop上运行。
Timer.every(1.0, ClosureWrapper({ (timer) in
print("Timer_every")
})).start()
Timer.after(5.0, ClosureWrapper({ (timer) in
print("Timer_after")
})).start()
SwiftyToast
SwiftyToast依赖于全局RunLoop中心,同时也显示无重叠的吐司。
SwiftyToast.load("This is a Toast")
SwiftyAlert
SwiftyAlert 包含 SuccessAlert,ErrorAlert,WarningAlert,InfoAlert,EditAlert 以及它们特殊的样式。
let alert: SwiftyAlertView = .create()
_ = alert.addTextField()
_ = alert.addButton("First Button", action: {
print("First Button tapped")
})
_ = alert.addButton("Second Button") {
print("Second button tapped")
}
let theAlert: SwiftyAlertViewResponder = alert.showSuccess("Congratulations", subTitle: "You've just displayed this awesome Pop Up View") //showError, showWarning, showInfo, showEdit
theAlert.setDismissBlock {
print("Alert Dismissed")
}
SwiftyThreadPool
ThreadPool用于管理线程,它依赖于活动的CPU,同时也释放Runloop内部的内存。
let myOperation : BlockOperation = .init {
print("task2----Thread:\(Thread.current)")
for i in 1...3
{
print("Task-------\(i)")
}
}
ThreadPool.defalut.add(myOperation)
SwiftyPromise
众所周知,PromiseKit及其故事。我也在我的代码中使用这个库。但它对我来说太重了,因此我基于JavaScript的A+规范,依赖于线程池,构建了PromiseKit的轻量级版本。
如果你不需要在Promise中从不同线程发送值,将会很简单。
Promise<Void>.firstly(with: nil, on: .background) {
print("Promise<Void>---task1----Thread:\(Thread.current)")
}.then(on: .main) {
print("Promise<Void>---task2----Thread:\(Thread.current)")
throw SimpleError()
}.then {
print("Promise<Void>---task3----Thread:\(Thread.current)")
}.always {
print("Promise<Void>---taskAlways----Thread:\(Thread.current)")
}.catch { (error) in
print("Promise<Void>---error\(String(describing: error))")
}
另外,如果你需要在Promise的不同线程中共享或发送值,你应该像下面这样编码:
Promise<String>.firstly(on: .background) { (update, _) in
print("task1----Thread:\(Thread.current)")
update("abc")
}.then { (update, str) in
print("thenthenthenthenthenthen----\(String(describing: str))") // abc
var str = str
str?.append("aaaaaaaa") // aaaaaaaaabc
update(str)
}.then(with: nil, on: .main) { (_, str) in
print("mainmainmainmainmainmainmain----\(String(describing: str))") // aaaaaaaaabc
}.catch()
待办事项列表
- CameraKit,它是一个轻量级相机框架。
- OpenGL 视频/图像处理。
- Metal 视频/图像处理。
- OpenCV 计算机视觉处理。
- Vision Framework 人脸检测。
许可协议
SwiftyUI遵循MIT许可协议发布。有关详细信息,请参阅LICENSE文件。