Flex Color Picker
Swift 5 编写的可hackable颜色选择器库,易于扩展和定制。它旨在通过稳定、高质量的代码提供优秀的用户体验和性能。包含HSB和RGB颜色模型的控制。
功能
- 支持HSB 和 RGB颜色模型,以及环形和矩形色调/饱和度调色板
- 如果需要快速、简单的解决方案,则有现成可用的视图控制器
- 在需要灵活性时,可以自由组合、省略或添加自己的选择器组件
- 文档齐全
- 高度可定制
- 支持故事板,带有设计时预览和在故事板中直接进行定制
- 库由小型类和 robust、易于理解的代码组成
- 无需子类化特定控制器即可使用
- 可hackable:协议用于添加自定义选择器控件,公开的类准备好用于子类化
使用案例
- 即插即用的颜色选择器,无需额外配置即可使用
- 支持自动布局和从故事板直接修改组件定位的敏捷库
- 提供了允许添加自己的滑块、调色板和预览或修改现有调色板的框架,而无需更改库的代码
- 自由组合上述三种方法,以获得所需的定制级别
安装
Swift Package Manager
在XCode 11及以上版本,点击文件 → Swift Packages → 添加包依赖... → 选择要添加FlexColorPicker的目标 → 输入https://github.com/RastislavMirek/FlexColorPicker
,按下一步 → 设置版本首选项并确认。
或者,如果您使用Package.swift,只需添加以下依赖项。
dependencies: [
.package(url: "https://github.com/RastislavMirek/FlexColorPicker.git", from: "1.3.1")
]
CocoaPods
将此添加到您的Podfile中
pod 'FlexColorPicker'
您也可以使用以下命令尝试Demo项目
pod try FlexColorPicker
直接安装
如果您不是CocoaPods或SPM用户,可以使用此命令从仓库克隆颜色选择器
git clone https://github.com/RastislavMirek/FlexColorPicker
或者,您可以从发行版下载最新的ZIP文件。
然后,在XCode中打开克隆的/下载的项目,并编译FlexColorPicker目标。FlexColorPicker.framework文件将在产品目录下创建。在XCode中打开您要添加颜色选择器的项目,选择项目文件,在左侧选择您应用程序的目标,选择通用选项卡,并在嵌入的二元文件部分添加FlexColorPicker.framework。
基本用法(即插即用)
将颜色选择器添加到项目最快、最简单的方式是使用DefaultColorPickerViewController
。您可以通过Storyboard或代码添加它。在这两种情况下,您都需要实现ColorPickerDelegate
协议,以便在用户使用DefaultColorPickerViewController
选择颜色时接收更新。
// MyController is the controller that presents DefaultColorPickerViewController
extension MyController: ColorPickerDelegate {
func colorPicker(_ colorPicker: ColorPickerController, selectedColor: UIColor, usingControl: ColorControl) {
// code to handle that user selected a color without confirmed it yet (may change selected color)
}
func colorPicker(_ colorPicker: ColorPickerController, confirmedColor: UIColor, usingControl: ColorControl) {
// code to handle that user has confirmed selected color
}
}
ColorPickerDelegate
中的两个函数都是可选的。您可以选择使用其中一个或同时使用这两个函数。
通过Storyboard添加
在Storyboard中,可以通过指定视图控制器的类为DefaultColorPickerViewController
来使用FlexColorPicker。这需要在右面板的Custom Class下,在Identity Inspector中进行设置。Storyboard支持通过Attributes Inspector对控制器进行基本自定义。DefaultColorPickerViewController
的委托只能在代码中设置。
class MyController {
@IBOutlet var pickerController: ColorPickerController!
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let destinationColorPicker = segue.destination as? ColorPickerControllerProtocol {
destinationColorPicker.delegate = self
}
}
}
通过代码添加
如果使用导航控制器,可以按以下方式显示DefaultColorPickerViewController
:
let colorPickerController = DefaultColorPickerViewController()
colorPickerController.delegate = self
navigationController?.pushViewController(colorPickerController, animated: true)
请将上述代码片段的第三行替换为以下代码以显示颜色选择器模态窗体
let navigationController = UINavigationController(rootViewController: colorPickerController)
present(navigationController, animated: true, completion: nil)
所有上述代码都应该放置在触发颜色选择器显示的处理程序中(例如,“Pick Color”按钮的处理器)。
如果您愿意,可以使用以下代码将DefaultColorPickerViewController
设置为使用矩形版而非圆形色调饱和度面板。请参阅本页第三张动画图片中的示例。
colorPickerController.useRadialPalette = false
您还可以设置3个其他属性,这些属性会影响使用矩形面板时颜色选择器的外观(rectangularPaletteBorderOn
、rectangularPaletteHueHorizontalInPortrait
和rectangularPaletteHueHorizontalInLandscape
)。详见代码文档。如需更多自定义,请参阅下面的自定义部分。
自定义使用
DefaultColorPickerViewController
是一个即插即用选项(参见 基本用法),具有有限的定制化。它是一个方便的“即用型”视图控制器,它利用了 FlexColorPicker 的 颜色控件 和 颜色选择控制器。 颜色控件 是 UIView
,通常继承自 UIControl
,允许用户选择所需的颜色,而 颜色选择控制器 则管理这些控件。如果需要比 DefaultColorPickerViewController
提供的更多灵活性,您可以直接使用它们。
- 如果需要自定义 颜色控件 的布局,请阅读 自定义布局。
- 如果需要自定义 颜色控件 的外观或行为,请阅读 []。
- 如果需要同时自定义 颜色控件 的布局以及外观和行为,请合并上述两种方法。
自定义布局
所提供的 颜色控件 包括色调/饱和度调色板(圆形或矩形)、用于饱和度、亮度和 RGB 分量的滑块以及选择的颜色预览控件。
自定义控件和行为
可以通过实现 ColorControl
协议来添加其他控件。
可用的颜色控件
每个 颜色控件 都有一些属性(其中一些可以在故事板中设置),可用来自定义该控件的外观和感觉。以下是包括的 颜色控件 列表
ColorPreviewWithHex
RadialPaletteControl
RectangularPaletteControl
SaturationSliderControl
BrightnessSliderControl
RedSliderControl
GreenSliderControl
BlueSliderControl
如果您想自定义颜色选择器,您可以选择并布置您所需的 颜色控件,如果需要,设置其属性,并通过将它们添加到同一个 颜色选择控制器 来将它们连接起来。
连接颜色控件
在故事板上布局 颜色控件 并将其类设置在 标识检查器 中,将其设置为所需使用的控件类。例如,将 标识检查器 中的 class 字段设置为文本 "RadialPaletteControl"。然后设置控制器类为 CustomColorPickerViewController
,打开其 连接检查器(如 此图像 右侧所示)并将相应端口连接到控件。这也可以通过将 颜色控件 分配给 CustomColorPickerViewController
的适当属性来在代码中简单地完成。
如果您不能对 CustomColorPickerViewController
进行子类化(例如,因为您控制器是其他类的子类),请改用 ColorPickerController
。它也可以作为界面构建器的自定义对象在故事板中使用。它具有与 CustomColorPickerViewController
相同的属性(实际上,CustomColorPickerViewController
只是 ColorPickerController
的便捷包装)。您还可以通过 ColorPickerController.addControl(:)
将 颜色控件 添加到其中,这样您就不限于属性。
一旦添加到 颜色选择器控制器(例如 ColorPickerController
),颜色控件 将与其他由同一控制器管理的控件同步,共同选择单个颜色。
扩展与覆写
FlexColorPicker旨在以最少的努力进行调整和扩展。您可以通过实现 ColorControl
协议或扩展以下可子类化的类来添加您自己的 颜色控件
AbstractColorControl
- 如果可能的话始终子类化它AdjustedHitBoxColorControl
- 为控件提供扩展的击中框边距ColorSliderControl
- 例如,如果您需要除 HSB 或 RGB 之外的其他颜色模型的滑块ColorPaletteControl
- 如果您想创建其他颜色调板
在很多情况下,您不需要子类化 ColorSliderControl
或 ColorPaletteControl
。它们都依赖于它们的 颜色代理 来处理颜色更新、展示自身以及如何解释用户交互。因此,您可以通过分别实现 ColorSliderDelegate
或 ColorPaletteDelegate
协议来更改外观和行为,而无需更改控件本身的代码。
演示项目展示了两种方法(覆盖和组合)及其组合的示例,请随意检查。
当你直接子类化 AbstractColorControl
或 AdjustedHitBoxColorControl
(而不是通过 ColorSliderControl
或 ColorPaletteControl
)时,你可能需要重写 gestureRecognizerShouldBegin(:)
。默认情况下,不允许任何 UIPanGestureRecognizer
识别 AbstractColorControl
实例上的任何手势。根据你自定义颜色控制器的类型,你可能会想要在某些(或所有)情况下允许 UIPanGestureRecognizer
识别手势。例如,水平滑块会想要阻止 UIPanGestureRecognizer
识别水平拖拽手势,因为这意味着改变滑块的值。与此同时,它可能会允许 UIPanGestureRecognizer
识别任何垂直拖拽手势,因为用户可能想要滚动滑块的父视图(可能是 UIScrollView
),而不是改变滑块的值。
技巧 & 故障排除
所有 FlexColorPicker 类和函数都拥有详尽的内联文档。它将在你不确定某个类或函数的用途或用法时,为你提供帮助。
☛ 在 XCode 中单击 FlexColorPicker 任何类或函数的名称以显示详细文档。
在故事板中设置滑块控制器时,将其背景设置为透明是一个好习惯。由于对齐矩形(对齐矩形)比滑块的框架小,因此可以提供额外的点击区域边距以及背景框边框。因此,如果背景是纯白色,则可能会与其附近的其他视图重叠。
☛ 如果您不希望这种行为,在“属性检查器”中将点击区域内边距设置为 0,或者在代码中将 hitBoxInset
设置为 0
。
ColorPreviewWithHex
可以被点击。当它被点击时,ColorPickerController
会调用其委托上的 ColorPickerDelegate.colorPicker(_:selectedColor:usingControl:)
。
☛ 您可以通过将 ColorPreviewWithHex.tapToConfirm
设置为 false
向用户传达此功能或选择退出。
滚动 & 模态显示问题
当你创建自己的、不继承自 AbstractColorControl
的 颜色控制器,并用它们与模态显示的 UIViewController
一起使用时,在 iOS 13 中,它们的拖拽手势可能会与模态消失手势冲突。当它们是 UIScrollView
的子类时,也可能与滚动冲突。
☛ 通过将以下代码添加到你的自定义 颜色控制器 接收触摸的视图(在视图层次结构中最低的视图)来解决此问题
override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
return !(gestureRecognizer is UIPanGestureRecognizer)
}
所有提供的颜色控制实现(包括《AbstractColorControl》和《AdjustedHitBoxColorControl》)会覆盖gestureRecognizerShouldBegin(:)
方法,以确保当这些颜色控制嵌入到UIScrollView
内部或iOS 13模态视图控制器中时能够正常工作。这种实现防止当满足某些条件时,UIPanGestureRecognizer
实例识别任何手势。在某些罕见情况下,这可能会干扰到你添加到视图层次结构中的自定义UIPanGestureRecognizer
。
☛ 通过将你想与其UIPanGestureRecognizer
一起使用的颜色控制子类化,并覆盖gestureRecognizerShouldBegin(:)
方法以使手势被识别来解决这个问题。
当你在颜色控制(无论是你的自定义颜色控制还是提供的任何一个)中添加一个子视图时,该子视图启用了用户交互,并且颜色控制嵌入到UIScrollView
或iOS 13模态视图控制器中,你可能会在平移/滑动该子视图时遇到以下问题:意味着与你的颜色控制交互的平移/滑动可能被解释为滚动/取消控制器或反之亦然。
☛ 通过以下代码添加到你在颜色控制中添加的子视图中,并将委托设置为你自己的颜色控制来解决此问题
weak var delegate: LimitedGestureViewDelegate?
override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
guard let delegate = delegate else {
return !(gestureRecognizer is UIPanGestureRecognizer)
}
return delegate.gestureRecognizerShouldBegin(gestureRecognizer)
}
接触我们
如果你喜欢它,有疑问或想雇佣iOS开发者,请给我发消息
[我的名字,见个人资料] at [epytysae的反向拼写] dot [单词信息的头四个字母]
邮件将直接发送给FlexColorPicker的作者,加密的格式只是垃圾邮件保护。
建议、反馈、错误报告和pull requests非常欢迎。
感谢
滑块控制器的视觉效果受到了流行的Objective-C库HRColorPicker的启发。感谢使用FlexColorPicker!如果你只有3秒钟的时间给予反馈,请为这个存储库star。