Skip to content
This repository has been archived by the owner on Jun 8, 2020. It is now read-only.

Commit

Permalink
Merge pull request #5 from fernandodelrio/develop
Browse files Browse the repository at this point in the history
Finishing multiple color spaces
  • Loading branch information
fernandodelrio authored Dec 2, 2017
2 parents e40be9d + 70cff6a commit 22c8963
Show file tree
Hide file tree
Showing 9 changed files with 370 additions and 57 deletions.
33 changes: 11 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,7 @@ Since Xcode 9, we are able to define a color asset in the Assets catalog, allowi
3. In an existing project with no color assets defined, we need to group all the colors in the storyboards, manually create the asset colors and replace them everywhere.
# <a id="solution"></a> The solution

**SwiftColorGen** reads all storyboard files to find common **sRGB colors**, it creates them in a **.xcassets** folder and refer them in the storyboard. Then, it creates an **UIColor extension** allowing to access the same colors programmatically. It automatically puts a name to the colors found. The name will be the closest webcolor name, measuring the color distance between them. But, the user still can rename the colors and it will keep the storyboards updated.

**Currently, the tool only supports the sRGB color space, so remember to select it in the storyboard, when selecting a color and also in the Assets catalog or it may not work properly.**
**SwiftColorGen** reads all storyboard files to find common colors, it creates them in a **.xcassets** folder (without any duplications) and refer them back in the storyboard. Then, it creates an **UIColor extension** allowing to access the same colors programmatically. It automatically puts a name to the colors found. The name will be the closest webcolor name, measuring the color distance between them. But, the user still can rename the colors and it will keep the storyboards updated.

The rules for naming the colors dinamically:
- The closest web color name (https://en.wikipedia.org/wiki/Web_colors) is considered to name the color
Expand All @@ -39,28 +37,18 @@ SwiftColorGen is written in Swift and requires Swift to run. The project uses [A
That's the result of the code generation:

### Collecting the colors on Storyboard and generating the Assets
![Collecting Colors](https://github.com/fernandodelrio/SwiftColorGen/blob/master/Resources/Gif-Collecting-Colors0.4.0.gif)
![Collecting Colors](https://github.com/fernandodelrio/SwiftColorGen/blob/master/Resources/Gif-Collecting-Colors0.5.0.gif)

### Generating the Swift file
![Swift File](https://github.com/fernandodelrio/SwiftColorGen/blob/master/Resources/Gif-Swift0.4.0.gif)
![Swift File](https://github.com/fernandodelrio/SwiftColorGen/blob/master/Resources/Gif-Swift0.5.0.gif)

### Automatic renaming
![Automatic Renaming](https://github.com/fernandodelrio/SwiftColorGen/blob/master/Resources/Gif-Renaming0.4.0.gif)
![Automatic Renaming](https://github.com/fernandodelrio/SwiftColorGen/blob/master/Resources/Gif-Renaming0.5.0.gif)

### Custom colors + multiple replace
![Custom Colors](https://github.com/fernandodelrio/SwiftColorGen/blob/master/Resources/Gif-Custom-Color0.4.0.gif)

You can create your own extensions in a separated file to give a more semantic name to the colors:
![Custom Colors](https://github.com/fernandodelrio/SwiftColorGen/blob/master/Resources/Gif-Custom-Color0.5.0.gif)

```swift
extension UIColor {
class func defaultTextColor() -> UIColor {
return .deepPinkColor()
}
}
```

But you can also, simply rename the asset to the name you want, and the tool will keep the references updated. Here a complete video with the tool in action:
Here a complete video with the tool in action:

[![Demo](https://raw.githubusercontent.com/fernandodelrio/SwiftColorGen/master/Resources/Video-thumbnail0.4.0.png)](https://vimeo.com/244528270)

Expand Down Expand Up @@ -88,6 +76,8 @@ Example:
$ ./swiftcg -o Example/Generated.swift
```

**Notice that OS X 10.12 is required to run, because of a dependency from a NSColor method (used to convert between different color spaces)**

To test with the Example provided, call the **test.sh** script (it will update the files inside the Example folder):
```shell
$ chmod +x test.sh
Expand Down Expand Up @@ -116,10 +106,9 @@ $ pod install
4. Build your project and it's done. Remember to add the generated Swift file to Xcode, if it's not already there.

# TODO
1. Add support to other color spaces than the sRGB
2. Reduce the number of changes in the storyboards
3. Test on a larger project to see what will happen
4. Add tests
1. Reduce the number of changes in the storyboards
2. Test on a larger project to see what will happen
3. Add tests

# <a id="contributing"></a> Contributing
This project still on a initial stage of development. Feel free to contribute by testing it and reporting bugs. If you want to help developing it, checkout the TODO list. If you made some enhancement, open a pull request.
Expand Down
4 changes: 2 additions & 2 deletions SwiftColorGen.podspec
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
Pod::Spec.new do |s|
s.name = "SwiftColorGen"
s.version = "0.4.1"
s.version = "0.5.0"
s.summary = "A tool that generate code for Swift projects, designed to improve the maintainability of UIColors"
s.description = <<-DESC
A tool that generate code for Swift projects, designed to improve the maintainability of UIColors.
SwiftColorGen reads all storyboard files to find common sRGB colors.
SwiftColorGen reads all storyboard files to find common colors.
Then it creates those colors in a .xcassets folder and refer them in the storyboard.
Finally it creates a UIColor extension allowing to access the same colors programatically.
DESC
Expand Down
14 changes: 14 additions & 0 deletions SwiftColorGen.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
objects = {

/* Begin PBXBuildFile section */
D8138F601FD2DDB10088EB2A /* ColorSpaceManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8138F5F1FD2DDB10088EB2A /* ColorSpaceManager.swift */; };
D83734001FC8A44800B59423 /* AssetManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D83733FF1FC8A44800B59423 /* AssetManager.swift */; };
D83734021FC8A56500B59423 /* OutputFileManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D83734011FC8A56500B59423 /* OutputFileManager.swift */; };
D83734041FC8B5B800B59423 /* Asset.swift in Sources */ = {isa = PBXBuildFile; fileRef = D83734031FC8B5B800B59423 /* Asset.swift */; };
Expand Down Expand Up @@ -41,12 +42,14 @@
/* End PBXCopyFilesBuildPhase section */

/* Begin PBXFileReference section */
D8138F5F1FD2DDB10088EB2A /* ColorSpaceManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorSpaceManager.swift; sourceTree = "<group>"; };
D83733FF1FC8A44800B59423 /* AssetManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetManager.swift; sourceTree = "<group>"; };
D83734011FC8A56500B59423 /* OutputFileManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OutputFileManager.swift; sourceTree = "<group>"; };
D83734031FC8B5B800B59423 /* Asset.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Asset.swift; sourceTree = "<group>"; };
D879B3D81FC76C7A0095C592 /* CommandLine.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CommandLine.swift; sourceTree = "<group>"; };
D879B3D91FC76C7A0095C592 /* Option.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Option.swift; sourceTree = "<group>"; };
D879B3DA1FC76C7A0095C592 /* StringExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StringExtensions.swift; sourceTree = "<group>"; };
D88AAD501FD2F77F006F31F0 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
D89E2EE21FC1B10800CDC51C /* SwiftColorGen */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = SwiftColorGen; sourceTree = BUILT_PRODUCTS_DIR; };
D89E2EE51FC1B10800CDC51C /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = "<group>"; };
D89E2EEC1FC1B26200CDC51C /* ColorData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorData.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -89,12 +92,21 @@
path = CommandLineKit;
sourceTree = "<group>";
};
D88AAD4F1FD2F77E006F31F0 /* Frameworks */ = {
isa = PBXGroup;
children = (
D88AAD501FD2F77F006F31F0 /* AppKit.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
D89E2ED91FC1B10800CDC51C = {
isa = PBXGroup;
children = (
D89E2F221FC1D3B300CDC51C /* Example */,
D89E2EE41FC1B10800CDC51C /* SwiftColorGen */,
D89E2EE31FC1B10800CDC51C /* Products */,
D88AAD4F1FD2F77E006F31F0 /* Frameworks */,
);
sourceTree = "<group>";
};
Expand Down Expand Up @@ -148,6 +160,7 @@
D89E2F1F1FC1C2AB00CDC51C /* CLIManager.swift */,
D83733FF1FC8A44800B59423 /* AssetManager.swift */,
D83734011FC8A56500B59423 /* OutputFileManager.swift */,
D8138F5F1FD2DDB10088EB2A /* ColorSpaceManager.swift */,
);
path = Utils;
sourceTree = "<group>";
Expand Down Expand Up @@ -244,6 +257,7 @@
D89E2F1E1FC1B90900CDC51C /* PathManager.swift in Sources */,
D89E2EE61FC1B10800CDC51C /* main.swift in Sources */,
D89E2EED1FC1B26200CDC51C /* ColorData.swift in Sources */,
D8138F601FD2DDB10088EB2A /* ColorSpaceManager.swift in Sources */,
D83734021FC8A56500B59423 /* OutputFileManager.swift in Sources */,
D89E2F0E1FC1B34F00CDC51C /* Element.swift in Sources */,
D83734001FC8A44800B59423 /* AssetManager.swift in Sources */,
Expand Down
8 changes: 4 additions & 4 deletions SwiftColorGen/Model/ColorData.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,10 @@ class ColorData: Hashable {
}

static func ==(lhs: ColorData, rhs: ColorData) -> Bool {
return fabs(lhs.red-rhs.red) < 1e-15 &&
fabs(lhs.green-rhs.green) < 1e-15 &&
fabs(lhs.blue-rhs.blue) < 1e-15 &&
fabs(lhs.alpha-rhs.alpha) < 1e-15
return fabs(lhs.red-rhs.red) < 1e-4 &&
fabs(lhs.green-rhs.green) < 1e-4 &&
fabs(lhs.blue-rhs.blue) < 1e-4 &&
fabs(lhs.alpha-rhs.alpha) < 1e-4
}

var hashValue: Int {
Expand Down
58 changes: 31 additions & 27 deletions SwiftColorGen/Utils/ColorManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,21 @@ struct ColorManager {
static func getColors(xml: AEXMLElement) -> Set<ColorData> {
var colors: Set<ColorData> = Set<ColorData>()
func read(xml: AEXMLElement) {
if xml.name == "color",
let colorSpace = xml.attributes["customColorSpace"],
colorSpace == "sRGB",
let red = xml.attributes["red"],
let green = xml.attributes["green"],
let blue = xml.attributes["blue"],
let alpha = xml.attributes["alpha"] {
let color = ColorData()
color.red = Double(red) ?? 0.0
color.green = Double(green) ?? 0.0
color.blue = Double(blue) ?? 0.0
color.alpha = Double(alpha) ?? 0.0
colors.insert(color)
if xml.name == "color" {
ColorSpaceManager.convertToSRGB(xml: xml)
if let colorSpace = xml.attributes["customColorSpace"],
colorSpace == "sRGB",
let red = xml.attributes["red"],
let green = xml.attributes["green"],
let blue = xml.attributes["blue"],
let alpha = xml.attributes["alpha"] {
let color = ColorData()
color.red = Double(red) ?? 0.0
color.green = Double(green) ?? 0.0
color.blue = Double(blue) ?? 0.0
color.alpha = Double(alpha) ?? 0.0
colors.insert(color)
}
}
if xml.name != "namedColor" {
for child in xml.children {
Expand Down Expand Up @@ -71,20 +73,22 @@ struct ColorManager {
static func updateColors(xml: AEXMLElement, colors: Set<ColorData>) {
let generatorData = getColorsForGenerator(colors: colors)
func read(xml: AEXMLElement) {
if xml.name == "color",
let colorSpace = xml.attributes["customColorSpace"],
colorSpace == "sRGB",
let red = xml.attributes["red"],
let green = xml.attributes["green"],
let blue = xml.attributes["blue"],
let alpha = xml.attributes["alpha"] {
let color = ColorData()
color.red = Double(red) ?? 0.0
color.green = Double(green) ?? 0.0
color.blue = Double(blue) ?? 0.0
color.alpha = Double(alpha) ?? 0.0
if let data = (generatorData.filter { $0.color == color }.first) {
setColor(xml: xml, name: data.assetName)
if xml.name == "color" {
ColorSpaceManager.convertToSRGB(xml: xml)
if let colorSpace = xml.attributes["customColorSpace"],
colorSpace == "sRGB",
let red = xml.attributes["red"],
let green = xml.attributes["green"],
let blue = xml.attributes["blue"],
let alpha = xml.attributes["alpha"] {
let color = ColorData()
color.red = Double(red) ?? 0.0
color.green = Double(green) ?? 0.0
color.blue = Double(blue) ?? 0.0
color.alpha = Double(alpha) ?? 0.0
if let data = (generatorData.filter { $0.color == color }.first) {
setColor(xml: xml, name: data.assetName)
}
}
}
for child in xml.children {
Expand Down
Loading

0 comments on commit 22c8963

Please sign in to comment.