HandyUIKit
这个库的目的是提供我们认为 UIKit 框架本身就应该拥有的便捷的 UI 功能。因此,这个库旨在为日常编程中常见的任务提供解决方案,并尽可能遵循苹果框架中现有的命名约定。
如果您喜欢这个库,也请查看 HandySwift,它提供了在 Swift 标准库中没有包含的便捷功能。它包括非 UI 相关的添加。
安装
目前推荐通过 Carthage 安装此库。虽然Cocoapods可能也可以工作,但未进行测试。
当然,您也可以通过下载或使用 git submodules 手动将此框架包含到您的项目中。
使用方法
请查看UsageExamples.playground以获取提供的所有功能的完整列表。从.xcworkspace
内打开Playground以便使它工作。
功能概述
- 扩展
- NibLoadable
- IBDesignables
UIColor扩展
如果您正在使用RGB颜色系统来定义颜色,您肯定应该阅读以下这篇优秀博客,了解为什么RGB在大多数项目中都不是一个好的选择(当然,并不总是如此)为什么RGB几乎不是最佳选择。并且如果您认为您已经找到了使用HSB系统改变颜色亮度的方法,那么您也会在那里找到错误。诚实地讲,这篇文章值得一读。如果您不想的话,"亮度"是关键字,这是HandyUIKit整合到UIColor类中的原生HLC(或有时称为LCh)颜色系统的唯一最重要的原因。《HLC》是将LAB颜色空间转化为更易于人类理解的形式,它共享单值的优势,您需要更改它来正确改变指定颜色的感知亮度:《亮度`值。改变亮度可以节省您在处理应用中颜色的大量时间,就像博客文章中所描述的那样。
init(hue:luminance:chroma:)
使用给定的HLC(LCh)颜色初始化UIColor,并将它们标准化到0到1的范围。
let hlcaColor = UIColor(hue: 180/360, luminance: 30/100, chroma: 125/128, alpha: 1)
.hlca
返回包含命名HLCA参数的元组,便于访问。
hlcaColor.hlca.hue // => 0.5
hlcaColor.hlca.luminance // => 0.3
hlcaColor.hlca.chroma // => 0.97
hlcaColor.hlca.alpha // => 1.0
.rgba
返回包含命名RGBA参数的元组,便于访问。
let rgbaColor = UIColor(red: 0.1, green: 0.2, blue: 0.3, alpha: 0.4)
rgbaColor.rgba.red // => 0.1
rgbaColor.rgba.green // => 0.2
rgbaColor.rgba.blue // => 0.3
rgbaColor.rgba.alpha // => 0.4
.hsba
返回包含命名HSBA参数的元组,便于访问。
let hsbaColor = UIColor(hue: 0.1, saturation: 0.2, brightness: 0.3, alpha: 0.4)
hsbaColor.hsba.hue // => 0.1
hsbaColor.hsba.saturation // => 0.2
hsbaColor.hsba.brightness // => 0.3
hsbaColor.hsba.alpha // => 0.4
.change(可变属性, by:)
通过相加的方式使用指定差异更改单个属性来创建一个新的UIColor
对象。
color.rgba.blue // => 0.3
let newColor = color.change(.blue, by: 0.2)
newColor.rgba.blue // => 0.5
.change(可变属性, to:)
将单个属性值设置为指定值,创建一个新的UIColor
对象。
color.hlca.luminance // => 0.3
let newColor = color.change(.luminance, to: 0.8)
newColor.hlca.luminance // => 0.8
UIViewExtension
.toImage(size:)
可选调整结果大小,截取UIView内容的屏幕截图。
let view = UIView(frame: CGRect(width: 500, height: 500))
let subview = UIView(frame: CGRect(width: 200, height: 200))
view.addSubview(subview)
view.backgroundColor = .blue
subview.backgroundColor = .red
let fullSizeContent = view.toImage() // => <UIImage: width: 500, height: 500>
let downSizedContent = view.toImage(size: CGSize(width: 80, height: 80))
// => <UIImage: width: 80, height: 80>
.bindEdgesToSuperview()
为子视图添加约束,使其始终具有与父视图相同的尺寸和位置。
view.frame // => {x: 0, y: 0, w: 500, h: 500}
subview.frame // => {x: 150, y: 150, w: 200, h: 200}
subview.bindEdgesToSuperview()
view.layoutIfNeeded()
subview.frame // => {x: 0, y: 0, w: 500, h: 500}
CoreGraphicsExtensions
CGSize.inPixels / CGSize.inPixels(screen:)
返回一个新的CGSize对象,其宽度和高度转换为屏幕上的真实像素。
let size = CGSize(width: 100, height: 50)
size.inPixels // test this with a Retina screen target
// => {w 200 h 100}
size.inPixels(UIScreen.screens.last!) // pass a different screen
// => {w 50 h 25}
CGPoint.inPixels / CGPoint.inPixels(screen:)
返回一个新的CGPoint对象,其x和y坐标转换为屏幕上的真实像素。
let point = CGPoint(x: 100, y: 50)
point.inPixels // test this with a Retina screen target
// => {x 200 y 100}
let someScreen = UIScreen.screens.last!
point.inPixels(someScreen) // pass a different screen
// => {x 50 y 25}
CGRect.inPixels / CGRect.inPixels(screen:)
返回一个新的CGRect对象,其原点和尺寸转换为屏幕上的真实像素。
let rect = CGRect(x: 10, y: 20, width: 100, height: 50)
rect.inPixels // test this with a Retina screen target
// => {x 20 y 40 w 200 h 100}
let someScreen = UIScreen.screens.last!
rect.inPixels(someScreen) // pass a different screen
// => {x 5 y 10 w 50 h 25}
CGRect.init(size:) / CGRect.init(width:height:)
从原点为零创建一个具有给定大小的新CGRect对象。
let someSize = CGSize(width: 100, height: 50)
let originZeroRect1 = CGRect(size: someSize)
let originZeroRect2 = CGRect(width: 100, height: 50)
StringExtension
.height(forFixedWidth:font:)
计算并返回适合文本进入宽度受限矩形的所需高度。
let loremIpsum = "Lorem ipsum dolor sit amet, consectetur adipisici elit, sed eiusmod tempor incidunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquid ex ea commodi consequat. Quis aute iure reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint obcaecat cupiditat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
loremIpsum.height(forFixedWidth: 300, font: UIFont.systemFont(ofSize: 14, weight: UIFontWeightBold))
// => 183.77734375
.width(forFixedHeight:font:)
计算并返回适合文本进入高度受限矩形的所需宽度。
loremIpsum.width(forFixedHeight: 21, font: UIFont.systemFont(ofSize: 12, weight: UIFontWeightUltraLight))
// => 2351.0390625
.hyphenated()
一个带有对齐对齐和行中断模式的分行超文本字符串。
loremIpsum.hyphenated() // => a justified & hyphenated NSAttributedString object
.superscripted(font:) / .subscripted(font:) / .superAndSubscripted(font:)
使用结构^{上标文本}
和_{下标文本}
对字符串的文本添加上标和/或下标。
"x^{2}".superscripted(font: UIFont.systemFont(ofSize: 20, weight: .medium))
结果: x2
"CO_{2}".subscripted(font: UIFont.systemFont(ofSize: 20, weight: .medium))
结果: CO2
"_{20}Ca^{1,0}".superAndSubscripted(font: UIFont.systemFont(ofSize: 20, weight: .regular))
结果: 20Ca1,0
UIImageExtension
.toGrayscale()
创建图像的灰度版本。
let image = UIImage(named: "someImage")!
let grayscaleImage = image.toGrayscale()
UITableViewExtension
dequeueCell(ofType:, for:)
返回一个可重复使用的表格单元格,类型为 cellType
,以其类型名称作为重用标识符,并将其添加到表格中。
let cell = tableView.dequeueCell(ofType: MyUITableViewCell.self, for: indexPath)
dequeueHeaderFooterView(ofType:)
返回一个可重复使用的头部或底部视图,类型为 viewType
,以其类型名称作为重用标识符,并将其添加到表格中。
let view = tableView.dequeueHeaderFooterView(ofType: MyUITableHeaderFooterView.self)
registerCell(ofType:)
如果存在,则注册名为 cellType
的nib,或将类型为 cellType
的类注册为可重复使用的单元格。
tableView.registerCell(ofType: MyUITableViewCell.self)
registerHeaderFooterView(ofType:)
如果存在,则注册名称为 viewType
的 nib,或将类型为 viewType
的类注册为可重用头部/尾部视图。
tableView.registerHeaderFooterView(ofType: MyUITableHeaderFooterView.self)
UIWindowExtension
visibleViewController
如果窗口内有任何可访问的视图控制器,则返回当前可见的视图控制器。
visibleViewController(from:)
从给定的视图控制器开始,递归地遵循导航控制器、标签栏控制器和显示的模态视图控制器,以查找当前可见的视图控制器。
NibLoadable
这是一个辅助协议,可以使任何 UIView
子类符合要求。您可能想要这样做的情况是当您想在 XIB 文件中设计一个 UIView
子类时。在这种情况下,只需使视图类型符合 NibLoadable
,如下所示
class MyTableViewCell: UITableViewCell, NibLoadable {
// your code
}
默认情况下,NibLoadable
将查找与您的类型名称相同名称的文件,例如在项目中查找 MyTableViewCell.xib
并加载它。如果您需要,可以覆盖 static var nibName: String
来更改此行为。
您的视图必须在 XIB 文件中设置为 文件所有者
,还必须只有一个根 UIView
对象(这应该是 UIView
类型,而不是您的子类)。
现在您可以在子类中添加 IBOutlets
和 IBActions
,并在 XIB 文件中将它们连接到 File Owner
。
为了同时从代码和 Storyboards 加载数据,像这样在您的 init 方法中调用 loadFromNib()
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
loadFromNib()
}
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
loadFromNib()
}
这就完成了,现在您应该能够从代码和在 Storyboards 中加载 XIB 内部的自定义视图类型。对于 Storyboard 的使用,只需添加一个 UIView
对象,将其类型更改为您的视图子类,运行应用程序时应该一切正常。为了在 Interface Builder 中查看自定义视图,请将 @IBDesignable
添加到类声明前。
如果在 IBOutlets 加载后需要执行任何设置步骤,可以重写 nibDidLoad
,这在本视角上可以看作是视图控制器中 viewDidLoad
的等价物。
圆角视图
这是一个 IBDesignable
的 UIView
子类,它提供了在 Interface Builder 中设置的 cornerRadius
。只需在 IB 文件中添加一个 UIView
对象,并将其类型更改为 圆角视图
,您应该在属性检查器中看到 cornerRadius
。
模板按钮
这是一个 IBDesignable
的 UIButton
子类,它将自动通过将图像渲染模式设置为 .alwaysTemplate
,使 image
成为 tintColor
值的遮罩。
模板图像视图
这是一个 IBDesignable
的 UIImageView
子类,它将自动将 image
设置为 tintColor
值的遮罩,通过自动将图像渲染模式设置为 .alwaysTemplate
。
捐助
巴蒂·克劳奇(BartyCrouch)由奇哈特·古纳德(Cihat Gündüz)在业余时间为您呈现。如果您想感谢我并支持该项目的开发,请通过PayPal进行小额捐款。如果您也喜欢我的其他开源贡献和文章,请考虑通过成为GitHub的赞助商或Patreon的拥趸来激励我。
非常感谢您做出的任何捐赠,这真的非常有帮助!
贡献
请参阅文件CONTRIBUTING.md。
许可证
此库根据MIT许可证发布。有关详细信息,请参阅LICENSE文件。