Skip to content

Commit b310ab1

Browse files
committed
Add basic SwiftUI color support
1 parent 077cf71 commit b310ab1

File tree

4 files changed

+105
-12
lines changed

4 files changed

+105
-12
lines changed

CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Change log
22

3+
## [Version 5.0.0](https://github.com/yannickl/DynamicColor/releases/tag/5.0.0)
4+
*Released on 2019-12-24.*
5+
6+
- [ADD] Basic SwiftUI color support
7+
38
## [Version 4.1.1](https://github.com/yannickl/DynamicColor/releases/tag/4.2.0)
49
*Released on 2019-09-15.*
510

Examples/DynamicColorExample.xcodeproj/project.pbxproj

+14
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,12 @@
112112
CEFBDAE81B1CE38D000E6F30 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CEFBDAE71B1CE38D000E6F30 /* Images.xcassets */; };
113113
CEFBDAEB1B1CE38D000E6F30 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = CEFBDAE91B1CE38D000E6F30 /* LaunchScreen.xib */; };
114114
CEFBDB191B1DE220000E6F30 /* ColorCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEFBDB181B1DE220000E6F30 /* ColorCellView.swift */; };
115+
F401F80023B242B7008FB683 /* SwiftUIColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = F401F7FF23B242B7008FB683 /* SwiftUIColor.swift */; };
116+
F401F80123B242B7008FB683 /* SwiftUIColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = F401F7FF23B242B7008FB683 /* SwiftUIColor.swift */; };
117+
F401F80223B242B7008FB683 /* SwiftUIColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = F401F7FF23B242B7008FB683 /* SwiftUIColor.swift */; };
118+
F401F80323B242B7008FB683 /* SwiftUIColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = F401F7FF23B242B7008FB683 /* SwiftUIColor.swift */; };
119+
F401F80423B242B7008FB683 /* SwiftUIColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = F401F7FF23B242B7008FB683 /* SwiftUIColor.swift */; };
120+
F401F80523B242B7008FB683 /* SwiftUIColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = F401F7FF23B242B7008FB683 /* SwiftUIColor.swift */; };
115121
/* End PBXBuildFile section */
116122

117123
/* Begin PBXContainerItemProxy section */
@@ -211,6 +217,7 @@
211217
CEFBDAE71B1CE38D000E6F30 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
212218
CEFBDAEA1B1CE38D000E6F30 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = "<group>"; };
213219
CEFBDB181B1DE220000E6F30 /* ColorCellView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ColorCellView.swift; sourceTree = "<group>"; };
220+
F401F7FF23B242B7008FB683 /* SwiftUIColor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftUIColor.swift; sourceTree = "<group>"; };
214221
/* End PBXFileReference section */
215222

216223
/* Begin PBXFrameworksBuildPhase section */
@@ -373,6 +380,7 @@
373380
CE4E1EFB1D818AB100D2AC35 /* DynamicGradient.swift */,
374381
CEF85A241C84EA5B00DD1A49 /* HSL.swift */,
375382
CE5D647A1D35074B005DEE4E /* Utils.swift */,
383+
F401F7FF23B242B7008FB683 /* SwiftUIColor.swift */,
376384
);
377385
name = Sources;
378386
path = ../Sources;
@@ -726,6 +734,7 @@
726734
CE86889A1E2C165D00207CAC /* DynamicColorSpace.swift in Sources */,
727735
CE8688921E2C165D00207CAC /* DynamicColor.swift in Sources */,
728736
CE86889C1E2C165D00207CAC /* HSL.swift in Sources */,
737+
F401F80123B242B7008FB683 /* SwiftUIColor.swift in Sources */,
729738
CE8688981E2C165D00207CAC /* DynamicColor+RGBA.swift in Sources */,
730739
CE8688961E2C165D00207CAC /* DynamicColor+Lab.swift in Sources */,
731740
CE8688901E2C165D00207CAC /* Array.swift in Sources */,
@@ -747,6 +756,7 @@
747756
CE8688BA1E2C1AF700207CAC /* DynamicColorSpace.swift in Sources */,
748757
CE8688B21E2C1AF700207CAC /* DynamicColor.swift in Sources */,
749758
CE8688BC1E2C1AF700207CAC /* HSL.swift in Sources */,
759+
F401F80223B242B7008FB683 /* SwiftUIColor.swift in Sources */,
750760
CE8688B81E2C1AF700207CAC /* DynamicColor+RGBA.swift in Sources */,
751761
CE8688B61E2C1AF700207CAC /* DynamicColor+Lab.swift in Sources */,
752762
CE8688B01E2C1AF700207CAC /* Array.swift in Sources */,
@@ -768,6 +778,7 @@
768778
CE8688D51E2C1B4800207CAC /* DynamicColorSpace.swift in Sources */,
769779
CE8688CD1E2C1B4800207CAC /* DynamicColor.swift in Sources */,
770780
CE8688D71E2C1B4800207CAC /* HSL.swift in Sources */,
781+
F401F80323B242B7008FB683 /* SwiftUIColor.swift in Sources */,
771782
CE8688D31E2C1B4800207CAC /* DynamicColor+RGBA.swift in Sources */,
772783
CE8688D11E2C1B4800207CAC /* DynamicColor+Lab.swift in Sources */,
773784
CE8688CB1E2C1B4800207CAC /* Array.swift in Sources */,
@@ -789,6 +800,7 @@
789800
CE4E1F051D819AEC00D2AC35 /* DynamicColorSpace.swift in Sources */,
790801
CE5D647B1D35074B005DEE4E /* Utils.swift in Sources */,
791802
CE8B86551D2991F000C5A670 /* DynamicColor+XYZ.swift in Sources */,
803+
F401F80023B242B7008FB683 /* SwiftUIColor.swift in Sources */,
792804
CEAF67871CA2D22E008DC3A2 /* DynamicColor+Deriving.swift in Sources */,
793805
CEF85A261C84EA5B00DD1A49 /* HSL.swift in Sources */,
794806
CE1BD0811DEA01E500E11D77 /* ContrastDisplayContext.swift in Sources */,
@@ -807,6 +819,7 @@
807819
CE5D64831D35230E005DEE4E /* DynamicColor+Lab.swift in Sources */,
808820
CEEB28E01BE27401001A74E8 /* ColorCellView.swift in Sources */,
809821
CEBD6FEE1D81CD9D00D75349 /* HeaderView.swift in Sources */,
822+
F401F80523B242B7008FB683 /* SwiftUIColor.swift in Sources */,
810823
CE4E1F071D819AEC00D2AC35 /* DynamicColorSpace.swift in Sources */,
811824
CE5D647D1D35074B005DEE4E /* Utils.swift in Sources */,
812825
CEAF67891CA2D22E008DC3A2 /* DynamicColor+Deriving.swift in Sources */,
@@ -832,6 +845,7 @@
832845
CE5D64821D35230E005DEE4E /* DynamicColor+Lab.swift in Sources */,
833846
CEFBDAE31B1CE38D000E6F30 /* ViewController.swift in Sources */,
834847
CE5D647C1D35074B005DEE4E /* Utils.swift in Sources */,
848+
F401F80423B242B7008FB683 /* SwiftUIColor.swift in Sources */,
835849
CE4E1EFD1D818AB100D2AC35 /* DynamicGradient.swift in Sources */,
836850
CEAF67881CA2D22E008DC3A2 /* DynamicColor+Deriving.swift in Sources */,
837851
CE4E1F121D81A6D900D2AC35 /* DynamicColor+HSB.swift in Sources */,

Sources/DynamicColor.swift

+9-12
Original file line numberDiff line numberDiff line change
@@ -55,16 +55,13 @@ public extension DynamicColor {
5555
- parameter hexString: A hexa-decimal color string representation.
5656
*/
5757
convenience init(hexString: String) {
58-
let hexString = hexString.trimmingCharacters(in: .whitespacesAndNewlines)
59-
let scanner = Scanner(string: hexString)
58+
let hexString = hexString.trimmingCharacters(in: .whitespacesAndNewlines)
59+
let scanner = Scanner(string: hexString)
60+
scanner.charactersToBeSkipped = CharacterSet(charactersIn: "#")
6061

61-
if hexString.hasPrefix("#") {
62-
scanner.scanLocation = 1
63-
}
64-
65-
var color: UInt32 = 0
62+
var color: UInt64 = 0
6663

67-
if scanner.scanHexInt32(&color) {
64+
if scanner.scanHexInt64(&color) {
6865
self.init(hex: color, useAlpha: hexString.count > 7)
6966
}
7067
else {
@@ -75,11 +72,11 @@ public extension DynamicColor {
7572
/**
7673
Creates a color from an hex integer (e.g. 0x3498db).
7774

78-
- parameter hex: A hexa-decimal UInt32 that represents a color.
79-
- parameter alphaChannel: If true the given hex-decimal UInt32 includes the alpha channel (e.g. 0xFF0000FF).
75+
- parameter hex: A hexa-decimal UInt64 that represents a color.
76+
- parameter alphaChannel: If true the given hex-decimal UInt64 includes the alpha channel (e.g. 0xFF0000FF).
8077
*/
81-
convenience init(hex: UInt32, useAlpha alphaChannel: Bool = false) {
82-
let mask = UInt32(0xFF)
78+
convenience init(hex: UInt64, useAlpha alphaChannel: Bool = false) {
79+
let mask = UInt64(0xFF)
8380
let cappedHex = !alphaChannel && hex > 0xffffff ? 0xffffff : hex
8481

8582
let r = cappedHex >> (alphaChannel ? 24 : 16) & mask

Sources/SwiftUIColor.swift

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
* DynamicColor
3+
*
4+
* Copyright 2015-present Yannick Loriot.
5+
* http://yannickloriot.com
6+
*
7+
* Permission is hereby granted, free of charge, to any person obtaining a copy
8+
* of this software and associated documentation files (the "Software"), to deal
9+
* in the Software without restriction, including without limitation the rights
10+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
* copies of the Software, and to permit persons to whom the Software is
12+
* furnished to do so, subject to the following conditions:
13+
*
14+
* The above copyright notice and this permission notice shall be included in
15+
* all copies or substantial portions of the Software.
16+
*
17+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23+
* THE SOFTWARE.
24+
*
25+
*/
26+
27+
import SwiftUI
28+
29+
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *)
30+
extension Color {
31+
// MARK: - Manipulating Hexa-decimal Values and Strings
32+
33+
/**
34+
Creates a color from an hex string (e.g. "#3498db"). The RGBA string are also supported (e.g. "#3498dbff").
35+
36+
If the given hex string is invalid the initialiser will create a black color.
37+
38+
- parameter hexString: A hexa-decimal color string representation.
39+
*/
40+
init(hexString: String) {
41+
let hexString = hexString.trimmingCharacters(in: .whitespacesAndNewlines)
42+
let scanner = Scanner(string: hexString)
43+
scanner.charactersToBeSkipped = CharacterSet(charactersIn: "#")
44+
45+
var color: UInt64 = 0
46+
47+
if scanner.scanHexInt64(&color) {
48+
self.init(hex: color, useOpacity: hexString.count > 7)
49+
}
50+
else {
51+
self.init(hex: 0x000000)
52+
}
53+
}
54+
55+
/**
56+
Creates a color from an hex integer (e.g. 0x3498db).
57+
58+
- parameter hex: A hexa-decimal UInt64 that represents a color.
59+
- parameter opacityChannel: If true the given hex-decimal UInt64 includes the opacity channel (e.g. 0xFF0000FF).
60+
*/
61+
init(hex: UInt64, useOpacity opacityChannel: Bool = false) {
62+
let mask = UInt64(0xFF)
63+
let cappedHex = !opacityChannel && hex > 0xffffff ? 0xffffff : hex
64+
65+
let r = cappedHex >> (opacityChannel ? 24 : 16) & mask
66+
let g = cappedHex >> (opacityChannel ? 16 : 8) & mask
67+
let b = cappedHex >> (opacityChannel ? 8 : 0) & mask
68+
let o = opacityChannel ? cappedHex & mask : 255
69+
70+
let red = Double(r) / 255.0
71+
let green = Double(g) / 255.0
72+
let blue = Double(b) / 255.0
73+
let opacity = Double(o) / 255.0
74+
75+
self.init(red: red, green: green, blue: blue, opacity: opacity)
76+
}
77+
}

0 commit comments

Comments
 (0)