SwiftyUI 1.8.0

SwiftyUI 1.8.0

维护者 haoking



SwiftyUI 1.8.0

  • 王昊晨

SwiftyUI Awesome

Build Status CocoaPods Compatible Platform Swift 4.0+

高性能且轻量级的 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文件。