ElegantColorPalette

platforms pod Carthage compatible Swift Package Manager compatible License: MIT

UIKit 和 SwiftUI 中缺少的优雅颜色选择器。

这些 GIF 来自 ElegantTimeline。为了更简单的演示,您可以查看此存储库中的 3 个演示项目中的任何一个。

简介

ElegantColorPalette 带有 24 种不同的主题,其灵感来自 TimePage,并且是更大的优雅演示存储库的一部分,例如:TimePage Clone

顶层视图是一个 SKView,它呈现一个颜色节点的 SKScene。颜色节点是 SKShapeNode 子类。对于更有经验的开发人员,他们是或者想要学习 SpriteKit,包含颜色节点的 SKScene 被公开,以便您进行更精细的调整。

特性

基本用法

对于 SwiftUI

import ElegantColorPalette

struct ExampleSwiftUIView: View {

    @State private var selectedColor: PaletteColor = .kiwiGreen

    var body: some View {
        ColorPaletteBindingView(selectedColor: $selectedColor, colors: PaletteColor.allColors)
    }

}

对于 UIKit(以编程方式)

import ElegantColorPalette

struct ExampleUIKitViewController: UIViewController {

    ...

    private lazy var paletteView: ColorPaletteView = {
        let paletteView = ColorPaletteView(colors: PaletteColor.allColors)
        paletteView.translatesAutoresizingMaskIntoConstraints = false
        return paletteView
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        ...
        
        view.addSubview(paletteView)
        NSLayoutConstraint.activate([
            ...
        ])

        paletteView
            .didSelectColor { [unowned self] color in
                ...
            }
    }

}

对于 UIKit(故事板和 XIB)

import ElegantColorPalette

struct ExampleUIKitViewController: UIViewController {

    ...
    
    @IBOutlet weak var paletteView: ColorPaletteView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        ...
        
        paletteView
            .update(withColors: PaletteColor.allColors)
            .didSelectColor { [unowned self] color in
                ...
            }
    }

}

自定义

PaletteColor

PaletteColor 表示单个节点的颜色模型。

public struct PaletteColor: Equatable {

    public let name: String
    public let uiColor: UIColor

    public var color: Color {
        uiColor.asColor
    }

}

由于您无法从 iOS 13 中的 Color 中获取 UIColor,因此您必须使用 UIColor 初始化 PaletteColor。 如果您支持浅色和深色主题,您需要通过资源束或其他方法(如计算属性)传递动态 UIColor

对于 SwiftUI 用户,PaletteColor 公开了一个 color 属性,方便您使用。

节点自定义

节点可以通过许多 节点修饰符函数轻松定制,这些函数公开了库本身。 您也可以通过 NodeStyleNodeModifier 制作自己的节点修饰符,就像您在 SwiftUI 中使用 ButtonStyleViewModifier 一样。

请参阅 NodeConfiguration 以更好地了解节点的各种状态,以确定何时最好应用您的修饰符。

以下示例演示了如何创建进一步自定义默认节点样式的自定义节点样式。 您必须将您的自定义修饰符应用于 defaultStyledNode,以便保留您在演示 gif 中看到的捕捉效果、突出显示的边框等。 但是,您可以随时从头开始并为不同状态设置自己的节点样式。

struct CustomNodeStyle: NodeStyle {

    func updateNode(configuration: Configuration) -> ColorNode {
        configuration.defaultStyledNode
            .radius(30)
            .font(name: "Thonburi")
    }

}

创建您自己的节点修饰符需要具备 SKNode 的先决知识。 让我们看一下 ScaleFadeModifier。 此修饰符负责通过 SKActions 缩放和淡化节点。

struct ScaleFadeModifier: NodeModifier {

    let scale: CGFloat
    let opacity: CGFloat
    let animationDuration: TimeInterval

    func body(content: Content) -> ColorNode {
        let scaleAction = SKAction.scale(to: scale, duration: animationDuration)
        let opacityAction = SKAction.fadeAlpha(to: opacity, duration: animationDuration)

        content.run(.group([scaleAction, opacityAction]))

        return content
    }

}

要使用您的自定义 NodeStyle,请将其传递到 nodeStyle 修饰符中

// For UIKit
ColorPaletteView(...)
    .nodeStyle(CustomNodeStyle())
     
// For SwiftUI
ColorPaletteBindingView(...)
    .nodeStyle(CustomNodeStyle())

焦点定制

使用 focus 自定义焦点动画的位置、速度或平滑率。

// For UIKit
ColorPaletteView(...)
    .focus(location: .zero, speed: 1600, rate: 0.2)
     
// For SwiftUI
ColorPaletteBindingView(...)
    .focus(location: .zero, speed: 1600, rate: 0.2)

使用 canMoveFocusedNode 自定义焦点节点是否可移动。

// For UIKit
ColorPaletteView(...)
    .canMoveFocusedNode(false)
     
// For SwiftUI
ColorPaletteBindingView(...)
    .canMoveFocusedNode(false)

对于 SwiftUI,您还可以自定义在选择新的调色板颜色时发生的绑定动画。

ColorPaletteBindingView(...)
    .bindingAnimation(.easeInOut)

场景定制

正如在引言中提到的,驱动视图的 SKScene 通过一个名为 paletteScene 的属性公开。 如果您有使用 SpriteKit 的经验,您可以篡改场景以获得更大的灵活性。

使用 spawnConfiguration 自定义允许节点产生的区域

// For UIKit
ColorPaletteView(...)
    .spawnConfiguration(widthRatio: 1, heightRatio: 1)
     
// For SwiftUI
ColorPaletteBindingView(...)
    .spawnConfiguration(widthRatio: 1, heightRatio: 1)

使用 rotation 自定义您希望节点围绕焦点位置旋转的速度

// For UIKit
ColorPaletteView(...)
    .rotation(multiplier: 4)
     
// For SwiftUI
ColorPaletteBindingView(...)
    .rotation(multiplier: 4)

事件

使用 didSelectColor 来响应所选调色板颜色的任何更改

// For UIKit
ColorPaletteView(...)
     .didSelectColor { paletteColor in
         // do something
     }
     
// For SwiftUI
ColorPaletteBindingView(...)
     .didSelectColor { paletteColor in
         // do something
     }

演示

有 3 个不同的演示,涵盖 UIKit 故事板、XIB 和编程实例化以及 SwiftUI。

要求

安装

ElegantColorPalette 不包含任何外部依赖项。

以下是当前支持的安装选项

手动

Sources 内部,将 ElegantColorPalette 文件夹拖到您的项目中。

CocoaPods

# Podfile
use_frameworks!

target 'YOUR_TARGET_NAME' do
    pod 'ElegantColorPalette', '~> 1.2'
end

替换 YOUR_TARGET_NAME,然后在 Podfile 目录中,键入

$ pod install

Carthage

将其添加到 Cartfile

github "ThasianX/ElegantColorPalette" ~> 1.2.0
$ carthage update

Swift Package Manager

使用 Xcode 11,转到 File -> Swift Packages -> Add Package Dependency 并输入 https://github.com/ThasianX/ElegantColorPalette

如果您使用的是 Package.swift,您也可以轻松地将 ElegantColorPalette 添加为依赖项。

// swift-tools-version:5.1

import PackageDescription

let package = Package(
  name: "TestProject",
  dependencies: [
    .package(url: "https://github.com/ThasianX/ElegantColorPalette", from: "1.2.0")
  ],
  targets: [
    .target(name: "TestProject", dependencies: ["ElegantColorPalette"])
  ]
)
$ swift build

贡献

如果您发现错误,或者想要建议新功能或增强功能,如果您能先搜索问题跟踪器,那就太好了;虽然我们不介意重复,但保持问题唯一有助于我们节省时间并整合精力。 如果您找不到您的问题,请随时提交新问题

许可

该项目已获得 MIT 许可 - 有关详细信息,请参阅 LICENSE 文件