├── .gitignore
├── .swift-version
├── LICENSE
├── NSImageColors
├── Info.plist
└── NSImageColors.h
├── Package.swift
├── README.md
├── UIImageColors.podspec
├── UIImageColors.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
└── xcshareddata
│ └── xcschemes
│ ├── NSImageColors.xcscheme
│ └── UIImageColors.xcscheme
├── UIImageColors
├── Sources
│ ├── UIImageColors.h
│ └── UIImageColors.swift
└── Supporting Files
│ └── Info.plist
├── UIImageColorsExample
├── Album.swift
├── AlbumViewCell.swift
├── AppDelegate.swift
├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ ├── Blue Nude II - Henri Matisse.imageset
│ │ ├── Blue Nude II - Henri Matisse.jpg
│ │ └── Contents.json
│ ├── Cafe Terrace at Night - Vincent Van Gogh.imageset
│ │ ├── Cafe Terrace at Night - Vincent Van Gogh.jpg
│ │ └── Contents.json
│ ├── Calvin Klein - Kaws.imageset
│ │ ├── Calvin Klein - Kaws.jpg
│ │ └── Contents.json
│ ├── Contents.json
│ ├── Le Reve - Pablo Picasso.imageset
│ │ ├── Contents.json
│ │ └── Le Reve - Pablo Picasso.jpg
│ ├── Les Demoiselles d'Avignon - Picasso.imageset
│ │ ├── Contents.json
│ │ └── Les Demoiselles d'Avignon - Picasso.jpg
│ ├── Mona Lisa - Leonardo da Vinci.imageset
│ │ ├── Contents.json
│ │ └── Mona Lisa - Leonardo da Vinci.jpg
│ ├── Nighthawks - Edward Hopper.imageset
│ │ ├── Contents.json
│ │ └── Nighthawks - Edward Hopper.jpg
│ ├── No. 210:No. 211 - Mark Rothko.imageset
│ │ ├── Contents.json
│ │ └── No. 210:No. 211 - Mark Rothko.jpg
│ ├── Number 1A - Jackson Pollock.imageset
│ │ ├── Contents.json
│ │ └── Number 1A - Jackson Pollock.jpg
│ ├── Self-portrait Spring 1887 - Vincent Van Gogh.imageset
│ │ ├── Contents.json
│ │ └── Self-portrait Spring 1887 - Vincent Van Gogh.jpg
│ ├── Skull - Jean-Michel Basquiat.imageset
│ │ ├── Contents.json
│ │ └── Skull - Jean-Michel Basquiat.jpg
│ ├── Woman I - Willem de Kooning.imageset
│ │ ├── Contents.json
│ │ └── Woman I - Willem de Kooning.jpg
│ └── play.imageset
│ │ ├── Contents.json
│ │ ├── play@1x.png
│ │ ├── play@2x.png
│ │ └── play@3x.png
├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
├── Info.plist
└── ViewController.swift
└── preview.png
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 |
3 | **/xcuserdata
4 | *.pbxuser
5 | *.mode1v3
6 | .swiftpm
7 |
--------------------------------------------------------------------------------
/.swift-version:
--------------------------------------------------------------------------------
1 | 3.0
2 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2015 Jathu Satkunarajah
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/NSImageColors/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 2.2.0
19 | CFBundleVersion
20 | $(CURRENT_PROJECT_VERSION)
21 | NSHumanReadableCopyright
22 | Copyright © 2019 Jathu Satkunarajah. All rights reserved.
23 |
24 |
25 |
--------------------------------------------------------------------------------
/NSImageColors/NSImageColors.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSImageColors.h
3 | // NSImageColors
4 | //
5 | // Created by Boy van Amstel on 20/01/2019.
6 | // Copyright © 2019 Jathu Satkunarajah. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | //! Project version number for NSImageColors.
12 | FOUNDATION_EXPORT double NSImageColorsVersionNumber;
13 |
14 | //! Project version string for NSImageColors.
15 | FOUNDATION_EXPORT const unsigned char NSImageColorsVersionString[];
16 |
17 | // In this header, you should import all the public headers of your framework using statements like #import
18 |
19 |
20 |
--------------------------------------------------------------------------------
/Package.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version:5.0
2 |
3 | import PackageDescription
4 |
5 | let package = Package(
6 | name: "UIImageColors",
7 | products: [
8 | .library(name: "UIImageColors", targets: ["UIImageColors"])
9 | ],
10 | targets: [
11 | .target(name: "UIImageColors", path: "UIImageColors")
12 | ]
13 | )
14 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 | 
3 |
4 | # UIImageColors
5 |
6 | iTunes style color fetcher for `UIImage` and `NSImage`. It fetches the most dominant and prominent colors.
7 |
8 | 
9 |
10 | ## Installation
11 |
12 | ### Manual
13 |
14 | Copy [UIImageColors.swift](UIImageColors/Sources/UIImageColors.swift) into your project.
15 |
16 | ### [Cocoapods](https://cocoapods.org)
17 |
18 | Add UIImageColors to your [`Podfile`](https://cocoapods.org/pods/UIImageColors):
19 |
20 | ```
21 | pod 'UIImageColors'
22 | ```
23 |
24 | ### [Carthage](https://github.com/Carthage/Carthage)
25 |
26 | Add UIImageColors to your `Cartfile`:
27 |
28 | ```
29 | github "jathu/UIImageColors"
30 | ```
31 |
32 | ## Example
33 |
34 | Asynchronous example:
35 |
36 | ```swift
37 | let image = UIImage(named: "yeezus.png")
38 |
39 | image.getColors { colors in
40 | backgroundView.backgroundColor = colors.background
41 | mainLabel.textColor = colors.primary
42 | secondaryLabel.textColor = colors.secondary
43 | detailLabel.textColor = colors.detail
44 | }
45 | ```
46 |
47 | Synchronous example:
48 |
49 | ```swift
50 | let colors = UIImage(named: "yeezus.png").getColors()
51 |
52 | backgroundView.backgroundColor = colors.background
53 | mainLabel.textColor = colors.primary
54 | secondaryLabel.textColor = colors.secondary
55 | detailLabel.textColor = colors.detail
56 | ```
57 |
58 | ## Image Methods
59 |
60 | ```swift
61 | getColors() -> UIImageColors?
62 | getColors(quality: ImageColorsQuality) -> UIImageColors?
63 | getColors(_ completion: (UIImageColors?) -> Void) -> Void
64 | getColors(quality: UIImageColorsQuality, _ completion: (UIImageColors?) -> Void) -> Void
65 | ```
66 |
67 | ## UIImageColors Objects
68 |
69 | `UIImageColors` is struct that contains four different `UIColor` (or `NSColor` on macOS) variables.
70 |
71 | ```swift
72 | public struct UIImageColors {
73 | public var background: UIColor!
74 | public var primary: UIColor!
75 | public var secondary: UIColor!
76 | public var detail: UIColor!
77 | }
78 | ```
79 |
80 | `UIImageColorsQuality` is a enum with four different qualities. The qualities refer to how much the original image is scaled down. `Lowest` implies smaller size and faster performance at the cost of quality colors. `High` implies larger size with slower performance with good colors. `Highest` implies no downscaling and very good colors, but it is very slow.
81 |
82 | The default is set to `high`.
83 |
84 | ```swift
85 | public enum UIImageColorsQuality: CGFloat {
86 | case lowest = 50 // 50px
87 | case low = 100 // 100px
88 | case high = 250 // 250px
89 | case highest = 0 // No scale
90 | }
91 | ```
92 |
93 | ## License
94 |
95 | The [license](https://github.com/jathu/UIImageColors/blob/master/LICENSE) is provided in the project folder. This is based on Panic's [OS X ColorArt](https://github.com/panicinc/ColorArt/#license).
96 |
97 | ------
98 | June 2015 - Toronto
99 |
--------------------------------------------------------------------------------
/UIImageColors.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |spec|
2 | spec.name = "UIImageColors"
3 | spec.version = "2.3.0"
4 | spec.license = "MIT"
5 | spec.summary = "iTunes style color fetcher for UIImage and NSImage."
6 | spec.homepage = "https://github.com/jathu/UIImageColors"
7 | spec.authors = { "Jathu Satkunarajah" => "https://twitter.com/jathu" }
8 | spec.source = { :git => "https://github.com/jathu/UIImageColors.git", :tag => spec.version }
9 |
10 | spec.ios.deployment_target = "8.0"
11 | spec.tvos.deployment_target = "9.0"
12 | spec.macos.deployment_target = "10.10"
13 | spec.source_files = "UIImageColors/Sources/*.swift"
14 | spec.requires_arc = true
15 | spec.pod_target_xcconfig = {
16 | "SWIFT_VERSION" => "5.0"
17 | }
18 | end
19 |
--------------------------------------------------------------------------------
/UIImageColors.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 035BC84A1DABA020006CA9BE /* UIImageColors.h in Headers */ = {isa = PBXBuildFile; fileRef = 035BC8491DABA020006CA9BE /* UIImageColors.h */; settings = {ATTRIBUTES = (Public, ); }; };
11 | 035BC84C1DABA027006CA9BE /* UIImageColors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 035BC84B1DABA027006CA9BE /* UIImageColors.swift */; };
12 | 8709D06E1FDC762E0007E717 /* AlbumViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8709D06D1FDC762E0007E717 /* AlbumViewCell.swift */; };
13 | 871ED4461FD0B2E50062BC12 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 871ED4451FD0B2DC0062BC12 /* Foundation.framework */; };
14 | 871ED4471FD0B2EF0062BC12 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 871ED4451FD0B2DC0062BC12 /* Foundation.framework */; };
15 | 871ED4481FD0C12F0062BC12 /* UIImageColors.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 035BC83D1DAB9FED006CA9BE /* UIImageColors.framework */; };
16 | 871ED4491FD0C12F0062BC12 /* UIImageColors.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 035BC83D1DAB9FED006CA9BE /* UIImageColors.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
17 | 87A73EC81FD0913A00EE147D /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87A73EC71FD0913A00EE147D /* AppDelegate.swift */; };
18 | 87A73ECA1FD0913A00EE147D /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87A73EC91FD0913A00EE147D /* ViewController.swift */; };
19 | 87A73ECD1FD0913A00EE147D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 87A73ECB1FD0913A00EE147D /* Main.storyboard */; };
20 | 87A73ECF1FD0913A00EE147D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 87A73ECE1FD0913A00EE147D /* Assets.xcassets */; };
21 | 87A73ED21FD0913A00EE147D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 87A73ED01FD0913A00EE147D /* LaunchScreen.storyboard */; };
22 | 87A73ED81FD092CD00EE147D /* Album.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87A73ED71FD092CD00EE147D /* Album.swift */; };
23 | B57E060F21F484E0001D5009 /* NSImageColors.h in Headers */ = {isa = PBXBuildFile; fileRef = B57E060D21F484E0001D5009 /* NSImageColors.h */; settings = {ATTRIBUTES = (Public, ); }; };
24 | B57E061721F48517001D5009 /* UIImageColors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 035BC84B1DABA027006CA9BE /* UIImageColors.swift */; };
25 | B57E061821F4851B001D5009 /* UIImageColors.h in Headers */ = {isa = PBXBuildFile; fileRef = 035BC8491DABA020006CA9BE /* UIImageColors.h */; settings = {ATTRIBUTES = (Public, ); }; };
26 | /* End PBXBuildFile section */
27 |
28 | /* Begin PBXContainerItemProxy section */
29 | 871ED44A1FD0C12F0062BC12 /* PBXContainerItemProxy */ = {
30 | isa = PBXContainerItemProxy;
31 | containerPortal = 035BC8341DAB9FED006CA9BE /* Project object */;
32 | proxyType = 1;
33 | remoteGlobalIDString = 035BC83C1DAB9FED006CA9BE;
34 | remoteInfo = UIImageColors;
35 | };
36 | /* End PBXContainerItemProxy section */
37 |
38 | /* Begin PBXCopyFilesBuildPhase section */
39 | 871ED44C1FD0C12F0062BC12 /* Embed Frameworks */ = {
40 | isa = PBXCopyFilesBuildPhase;
41 | buildActionMask = 2147483647;
42 | dstPath = "";
43 | dstSubfolderSpec = 10;
44 | files = (
45 | 871ED4491FD0C12F0062BC12 /* UIImageColors.framework in Embed Frameworks */,
46 | );
47 | name = "Embed Frameworks";
48 | runOnlyForDeploymentPostprocessing = 0;
49 | };
50 | /* End PBXCopyFilesBuildPhase section */
51 |
52 | /* Begin PBXFileReference section */
53 | 035BC83D1DAB9FED006CA9BE /* UIImageColors.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = UIImageColors.framework; sourceTree = BUILT_PRODUCTS_DIR; };
54 | 035BC8491DABA020006CA9BE /* UIImageColors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIImageColors.h; sourceTree = ""; };
55 | 035BC84B1DABA027006CA9BE /* UIImageColors.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIImageColors.swift; sourceTree = ""; };
56 | 035BC84E1DABA02E006CA9BE /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
57 | 8709D06D1FDC762E0007E717 /* AlbumViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlbumViewCell.swift; sourceTree = ""; };
58 | 871ED4451FD0B2DC0062BC12 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
59 | 87A73EC51FD0913A00EE147D /* UIImageColorsExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = UIImageColorsExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
60 | 87A73EC71FD0913A00EE147D /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
61 | 87A73EC91FD0913A00EE147D /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
62 | 87A73ECC1FD0913A00EE147D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
63 | 87A73ECE1FD0913A00EE147D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
64 | 87A73ED11FD0913A00EE147D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
65 | 87A73ED31FD0913A00EE147D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
66 | 87A73ED71FD092CD00EE147D /* Album.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Album.swift; sourceTree = ""; };
67 | B57E060B21F484E0001D5009 /* NSImageColors.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = NSImageColors.framework; sourceTree = BUILT_PRODUCTS_DIR; };
68 | B57E060D21F484E0001D5009 /* NSImageColors.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NSImageColors.h; sourceTree = ""; };
69 | B57E060E21F484E0001D5009 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
70 | /* End PBXFileReference section */
71 |
72 | /* Begin PBXFrameworksBuildPhase section */
73 | 035BC8391DAB9FED006CA9BE /* Frameworks */ = {
74 | isa = PBXFrameworksBuildPhase;
75 | buildActionMask = 2147483647;
76 | files = (
77 | 871ED4461FD0B2E50062BC12 /* Foundation.framework in Frameworks */,
78 | );
79 | runOnlyForDeploymentPostprocessing = 0;
80 | };
81 | 87A73EC21FD0913A00EE147D /* Frameworks */ = {
82 | isa = PBXFrameworksBuildPhase;
83 | buildActionMask = 2147483647;
84 | files = (
85 | 871ED4481FD0C12F0062BC12 /* UIImageColors.framework in Frameworks */,
86 | 871ED4471FD0B2EF0062BC12 /* Foundation.framework in Frameworks */,
87 | );
88 | runOnlyForDeploymentPostprocessing = 0;
89 | };
90 | B57E060821F484E0001D5009 /* Frameworks */ = {
91 | isa = PBXFrameworksBuildPhase;
92 | buildActionMask = 2147483647;
93 | files = (
94 | );
95 | runOnlyForDeploymentPostprocessing = 0;
96 | };
97 | /* End PBXFrameworksBuildPhase section */
98 |
99 | /* Begin PBXGroup section */
100 | 035BC8331DAB9FED006CA9BE = {
101 | isa = PBXGroup;
102 | children = (
103 | B57E05F121F48157001D5009 /* UIImageColors */,
104 | 87A73EC61FD0913A00EE147D /* UIImageColorsExample */,
105 | B57E060C21F484E0001D5009 /* NSImageColors */,
106 | 035BC83E1DAB9FED006CA9BE /* Products */,
107 | 871ED4441FD0B2DC0062BC12 /* Frameworks */,
108 | );
109 | sourceTree = "";
110 | };
111 | 035BC83E1DAB9FED006CA9BE /* Products */ = {
112 | isa = PBXGroup;
113 | children = (
114 | 035BC83D1DAB9FED006CA9BE /* UIImageColors.framework */,
115 | 87A73EC51FD0913A00EE147D /* UIImageColorsExample.app */,
116 | B57E060B21F484E0001D5009 /* NSImageColors.framework */,
117 | );
118 | name = Products;
119 | sourceTree = "";
120 | };
121 | 035BC8481DABA020006CA9BE /* Sources */ = {
122 | isa = PBXGroup;
123 | children = (
124 | 035BC8491DABA020006CA9BE /* UIImageColors.h */,
125 | 035BC84B1DABA027006CA9BE /* UIImageColors.swift */,
126 | );
127 | name = Sources;
128 | path = UIImageColors/Sources;
129 | sourceTree = SOURCE_ROOT;
130 | };
131 | 035BC84D1DABA02E006CA9BE /* Supporting Files */ = {
132 | isa = PBXGroup;
133 | children = (
134 | 035BC84E1DABA02E006CA9BE /* Info.plist */,
135 | );
136 | name = "Supporting Files";
137 | path = "UIImageColors/Supporting Files";
138 | sourceTree = SOURCE_ROOT;
139 | };
140 | 871ED4441FD0B2DC0062BC12 /* Frameworks */ = {
141 | isa = PBXGroup;
142 | children = (
143 | 871ED4451FD0B2DC0062BC12 /* Foundation.framework */,
144 | );
145 | name = Frameworks;
146 | sourceTree = "";
147 | };
148 | 87A73EC61FD0913A00EE147D /* UIImageColorsExample */ = {
149 | isa = PBXGroup;
150 | children = (
151 | 87A73EC71FD0913A00EE147D /* AppDelegate.swift */,
152 | 87A73EC91FD0913A00EE147D /* ViewController.swift */,
153 | 8709D06D1FDC762E0007E717 /* AlbumViewCell.swift */,
154 | 87A73ED71FD092CD00EE147D /* Album.swift */,
155 | 87A73ECB1FD0913A00EE147D /* Main.storyboard */,
156 | 87A73ECE1FD0913A00EE147D /* Assets.xcassets */,
157 | 87A73ED01FD0913A00EE147D /* LaunchScreen.storyboard */,
158 | 87A73ED31FD0913A00EE147D /* Info.plist */,
159 | );
160 | path = UIImageColorsExample;
161 | sourceTree = "";
162 | };
163 | B57E05F121F48157001D5009 /* UIImageColors */ = {
164 | isa = PBXGroup;
165 | children = (
166 | 035BC8481DABA020006CA9BE /* Sources */,
167 | 035BC84D1DABA02E006CA9BE /* Supporting Files */,
168 | );
169 | path = UIImageColors;
170 | sourceTree = "";
171 | };
172 | B57E060C21F484E0001D5009 /* NSImageColors */ = {
173 | isa = PBXGroup;
174 | children = (
175 | B57E060D21F484E0001D5009 /* NSImageColors.h */,
176 | B57E060E21F484E0001D5009 /* Info.plist */,
177 | );
178 | path = NSImageColors;
179 | sourceTree = "";
180 | };
181 | /* End PBXGroup section */
182 |
183 | /* Begin PBXHeadersBuildPhase section */
184 | 035BC83A1DAB9FED006CA9BE /* Headers */ = {
185 | isa = PBXHeadersBuildPhase;
186 | buildActionMask = 2147483647;
187 | files = (
188 | 035BC84A1DABA020006CA9BE /* UIImageColors.h in Headers */,
189 | );
190 | runOnlyForDeploymentPostprocessing = 0;
191 | };
192 | B57E060621F484E0001D5009 /* Headers */ = {
193 | isa = PBXHeadersBuildPhase;
194 | buildActionMask = 2147483647;
195 | files = (
196 | B57E061821F4851B001D5009 /* UIImageColors.h in Headers */,
197 | B57E060F21F484E0001D5009 /* NSImageColors.h in Headers */,
198 | );
199 | runOnlyForDeploymentPostprocessing = 0;
200 | };
201 | /* End PBXHeadersBuildPhase section */
202 |
203 | /* Begin PBXNativeTarget section */
204 | 035BC83C1DAB9FED006CA9BE /* UIImageColors */ = {
205 | isa = PBXNativeTarget;
206 | buildConfigurationList = 035BC8451DAB9FED006CA9BE /* Build configuration list for PBXNativeTarget "UIImageColors" */;
207 | buildPhases = (
208 | 035BC8381DAB9FED006CA9BE /* Sources */,
209 | 035BC8391DAB9FED006CA9BE /* Frameworks */,
210 | 035BC83A1DAB9FED006CA9BE /* Headers */,
211 | 035BC83B1DAB9FED006CA9BE /* Resources */,
212 | );
213 | buildRules = (
214 | );
215 | dependencies = (
216 | );
217 | name = UIImageColors;
218 | productName = UIImageColors;
219 | productReference = 035BC83D1DAB9FED006CA9BE /* UIImageColors.framework */;
220 | productType = "com.apple.product-type.framework";
221 | };
222 | 87A73EC41FD0913A00EE147D /* UIImageColorsExample */ = {
223 | isa = PBXNativeTarget;
224 | buildConfigurationList = 87A73ED61FD0913A00EE147D /* Build configuration list for PBXNativeTarget "UIImageColorsExample" */;
225 | buildPhases = (
226 | 87A73EC11FD0913A00EE147D /* Sources */,
227 | 87A73EC21FD0913A00EE147D /* Frameworks */,
228 | 87A73EC31FD0913A00EE147D /* Resources */,
229 | 871ED44C1FD0C12F0062BC12 /* Embed Frameworks */,
230 | );
231 | buildRules = (
232 | );
233 | dependencies = (
234 | 871ED44B1FD0C12F0062BC12 /* PBXTargetDependency */,
235 | );
236 | name = UIImageColorsExample;
237 | productName = UIImageColorsExample;
238 | productReference = 87A73EC51FD0913A00EE147D /* UIImageColorsExample.app */;
239 | productType = "com.apple.product-type.application";
240 | };
241 | B57E060A21F484E0001D5009 /* NSImageColors */ = {
242 | isa = PBXNativeTarget;
243 | buildConfigurationList = B57E061421F484E0001D5009 /* Build configuration list for PBXNativeTarget "NSImageColors" */;
244 | buildPhases = (
245 | B57E060621F484E0001D5009 /* Headers */,
246 | B57E060721F484E0001D5009 /* Sources */,
247 | B57E060821F484E0001D5009 /* Frameworks */,
248 | B57E060921F484E0001D5009 /* Resources */,
249 | );
250 | buildRules = (
251 | );
252 | dependencies = (
253 | );
254 | name = NSImageColors;
255 | productName = NSImageColors;
256 | productReference = B57E060B21F484E0001D5009 /* NSImageColors.framework */;
257 | productType = "com.apple.product-type.framework";
258 | };
259 | /* End PBXNativeTarget section */
260 |
261 | /* Begin PBXProject section */
262 | 035BC8341DAB9FED006CA9BE /* Project object */ = {
263 | isa = PBXProject;
264 | attributes = {
265 | LastSwiftUpdateCheck = 1010;
266 | LastUpgradeCheck = 1010;
267 | ORGANIZATIONNAME = "Jathu Satkunarajah";
268 | TargetAttributes = {
269 | 035BC83C1DAB9FED006CA9BE = {
270 | CreatedOnToolsVersion = 8.0;
271 | LastSwiftMigration = 1010;
272 | ProvisioningStyle = Automatic;
273 | };
274 | 87A73EC41FD0913A00EE147D = {
275 | CreatedOnToolsVersion = 9.1;
276 | LastSwiftMigration = 1010;
277 | ProvisioningStyle = Automatic;
278 | };
279 | B57E060A21F484E0001D5009 = {
280 | CreatedOnToolsVersion = 10.1;
281 | ProvisioningStyle = Automatic;
282 | };
283 | };
284 | };
285 | buildConfigurationList = 035BC8371DAB9FED006CA9BE /* Build configuration list for PBXProject "UIImageColors" */;
286 | compatibilityVersion = "Xcode 3.2";
287 | developmentRegion = English;
288 | hasScannedForEncodings = 0;
289 | knownRegions = (
290 | English,
291 | en,
292 | Base,
293 | );
294 | mainGroup = 035BC8331DAB9FED006CA9BE;
295 | productRefGroup = 035BC83E1DAB9FED006CA9BE /* Products */;
296 | projectDirPath = "";
297 | projectRoot = "";
298 | targets = (
299 | 035BC83C1DAB9FED006CA9BE /* UIImageColors */,
300 | B57E060A21F484E0001D5009 /* NSImageColors */,
301 | 87A73EC41FD0913A00EE147D /* UIImageColorsExample */,
302 | );
303 | };
304 | /* End PBXProject section */
305 |
306 | /* Begin PBXResourcesBuildPhase section */
307 | 035BC83B1DAB9FED006CA9BE /* Resources */ = {
308 | isa = PBXResourcesBuildPhase;
309 | buildActionMask = 2147483647;
310 | files = (
311 | );
312 | runOnlyForDeploymentPostprocessing = 0;
313 | };
314 | 87A73EC31FD0913A00EE147D /* Resources */ = {
315 | isa = PBXResourcesBuildPhase;
316 | buildActionMask = 2147483647;
317 | files = (
318 | 87A73ED21FD0913A00EE147D /* LaunchScreen.storyboard in Resources */,
319 | 87A73ECF1FD0913A00EE147D /* Assets.xcassets in Resources */,
320 | 87A73ECD1FD0913A00EE147D /* Main.storyboard in Resources */,
321 | );
322 | runOnlyForDeploymentPostprocessing = 0;
323 | };
324 | B57E060921F484E0001D5009 /* Resources */ = {
325 | isa = PBXResourcesBuildPhase;
326 | buildActionMask = 2147483647;
327 | files = (
328 | );
329 | runOnlyForDeploymentPostprocessing = 0;
330 | };
331 | /* End PBXResourcesBuildPhase section */
332 |
333 | /* Begin PBXSourcesBuildPhase section */
334 | 035BC8381DAB9FED006CA9BE /* Sources */ = {
335 | isa = PBXSourcesBuildPhase;
336 | buildActionMask = 2147483647;
337 | files = (
338 | 035BC84C1DABA027006CA9BE /* UIImageColors.swift in Sources */,
339 | );
340 | runOnlyForDeploymentPostprocessing = 0;
341 | };
342 | 87A73EC11FD0913A00EE147D /* Sources */ = {
343 | isa = PBXSourcesBuildPhase;
344 | buildActionMask = 2147483647;
345 | files = (
346 | 87A73ECA1FD0913A00EE147D /* ViewController.swift in Sources */,
347 | 87A73EC81FD0913A00EE147D /* AppDelegate.swift in Sources */,
348 | 8709D06E1FDC762E0007E717 /* AlbumViewCell.swift in Sources */,
349 | 87A73ED81FD092CD00EE147D /* Album.swift in Sources */,
350 | );
351 | runOnlyForDeploymentPostprocessing = 0;
352 | };
353 | B57E060721F484E0001D5009 /* Sources */ = {
354 | isa = PBXSourcesBuildPhase;
355 | buildActionMask = 2147483647;
356 | files = (
357 | B57E061721F48517001D5009 /* UIImageColors.swift in Sources */,
358 | );
359 | runOnlyForDeploymentPostprocessing = 0;
360 | };
361 | /* End PBXSourcesBuildPhase section */
362 |
363 | /* Begin PBXTargetDependency section */
364 | 871ED44B1FD0C12F0062BC12 /* PBXTargetDependency */ = {
365 | isa = PBXTargetDependency;
366 | target = 035BC83C1DAB9FED006CA9BE /* UIImageColors */;
367 | targetProxy = 871ED44A1FD0C12F0062BC12 /* PBXContainerItemProxy */;
368 | };
369 | /* End PBXTargetDependency section */
370 |
371 | /* Begin PBXVariantGroup section */
372 | 87A73ECB1FD0913A00EE147D /* Main.storyboard */ = {
373 | isa = PBXVariantGroup;
374 | children = (
375 | 87A73ECC1FD0913A00EE147D /* Base */,
376 | );
377 | name = Main.storyboard;
378 | sourceTree = "";
379 | };
380 | 87A73ED01FD0913A00EE147D /* LaunchScreen.storyboard */ = {
381 | isa = PBXVariantGroup;
382 | children = (
383 | 87A73ED11FD0913A00EE147D /* Base */,
384 | );
385 | name = LaunchScreen.storyboard;
386 | sourceTree = "";
387 | };
388 | /* End PBXVariantGroup section */
389 |
390 | /* Begin XCBuildConfiguration section */
391 | 035BC8431DAB9FED006CA9BE /* Debug */ = {
392 | isa = XCBuildConfiguration;
393 | buildSettings = {
394 | ALWAYS_SEARCH_USER_PATHS = NO;
395 | CLANG_ANALYZER_NONNULL = YES;
396 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
397 | CLANG_CXX_LIBRARY = "libc++";
398 | CLANG_ENABLE_MODULES = YES;
399 | CLANG_ENABLE_OBJC_ARC = YES;
400 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
401 | CLANG_WARN_BOOL_CONVERSION = YES;
402 | CLANG_WARN_COMMA = YES;
403 | CLANG_WARN_CONSTANT_CONVERSION = YES;
404 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
405 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
406 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
407 | CLANG_WARN_EMPTY_BODY = YES;
408 | CLANG_WARN_ENUM_CONVERSION = YES;
409 | CLANG_WARN_INFINITE_RECURSION = YES;
410 | CLANG_WARN_INT_CONVERSION = YES;
411 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
412 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
413 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
414 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
415 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
416 | CLANG_WARN_STRICT_PROTOTYPES = YES;
417 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
418 | CLANG_WARN_SUSPICIOUS_MOVES = YES;
419 | CLANG_WARN_UNREACHABLE_CODE = YES;
420 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
421 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
422 | COPY_PHASE_STRIP = NO;
423 | CURRENT_PROJECT_VERSION = 1;
424 | DEBUG_INFORMATION_FORMAT = dwarf;
425 | ENABLE_STRICT_OBJC_MSGSEND = YES;
426 | ENABLE_TESTABILITY = YES;
427 | GCC_C_LANGUAGE_STANDARD = gnu99;
428 | GCC_DYNAMIC_NO_PIC = NO;
429 | GCC_NO_COMMON_BLOCKS = YES;
430 | GCC_OPTIMIZATION_LEVEL = 0;
431 | GCC_PREPROCESSOR_DEFINITIONS = (
432 | "DEBUG=1",
433 | "$(inherited)",
434 | );
435 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
436 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
437 | GCC_WARN_UNDECLARED_SELECTOR = YES;
438 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
439 | GCC_WARN_UNUSED_FUNCTION = YES;
440 | GCC_WARN_UNUSED_VARIABLE = YES;
441 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
442 | MTL_ENABLE_DEBUG_INFO = YES;
443 | ONLY_ACTIVE_ARCH = YES;
444 | SDKROOT = iphoneos;
445 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
446 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
447 | SWIFT_VERSION = 5.0;
448 | TARGETED_DEVICE_FAMILY = "1,2";
449 | VERSIONING_SYSTEM = "apple-generic";
450 | VERSION_INFO_PREFIX = "";
451 | };
452 | name = Debug;
453 | };
454 | 035BC8441DAB9FED006CA9BE /* Release */ = {
455 | isa = XCBuildConfiguration;
456 | buildSettings = {
457 | ALWAYS_SEARCH_USER_PATHS = NO;
458 | CLANG_ANALYZER_NONNULL = YES;
459 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
460 | CLANG_CXX_LIBRARY = "libc++";
461 | CLANG_ENABLE_MODULES = YES;
462 | CLANG_ENABLE_OBJC_ARC = YES;
463 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
464 | CLANG_WARN_BOOL_CONVERSION = YES;
465 | CLANG_WARN_COMMA = YES;
466 | CLANG_WARN_CONSTANT_CONVERSION = YES;
467 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
468 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
469 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
470 | CLANG_WARN_EMPTY_BODY = YES;
471 | CLANG_WARN_ENUM_CONVERSION = YES;
472 | CLANG_WARN_INFINITE_RECURSION = YES;
473 | CLANG_WARN_INT_CONVERSION = YES;
474 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
475 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
476 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
477 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
478 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
479 | CLANG_WARN_STRICT_PROTOTYPES = YES;
480 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
481 | CLANG_WARN_SUSPICIOUS_MOVES = YES;
482 | CLANG_WARN_UNREACHABLE_CODE = YES;
483 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
484 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
485 | COPY_PHASE_STRIP = NO;
486 | CURRENT_PROJECT_VERSION = 1;
487 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
488 | ENABLE_NS_ASSERTIONS = NO;
489 | ENABLE_STRICT_OBJC_MSGSEND = YES;
490 | GCC_C_LANGUAGE_STANDARD = gnu99;
491 | GCC_NO_COMMON_BLOCKS = YES;
492 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
493 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
494 | GCC_WARN_UNDECLARED_SELECTOR = YES;
495 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
496 | GCC_WARN_UNUSED_FUNCTION = YES;
497 | GCC_WARN_UNUSED_VARIABLE = YES;
498 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
499 | MTL_ENABLE_DEBUG_INFO = NO;
500 | SDKROOT = iphoneos;
501 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
502 | SWIFT_VERSION = 5.0;
503 | TARGETED_DEVICE_FAMILY = "1,2";
504 | VALIDATE_PRODUCT = YES;
505 | VERSIONING_SYSTEM = "apple-generic";
506 | VERSION_INFO_PREFIX = "";
507 | };
508 | name = Release;
509 | };
510 | 035BC8461DAB9FED006CA9BE /* Debug */ = {
511 | isa = XCBuildConfiguration;
512 | buildSettings = {
513 | CLANG_ENABLE_MODULES = YES;
514 | CODE_SIGN_IDENTITY = "";
515 | DEFINES_MODULE = YES;
516 | DEVELOPMENT_TEAM = "";
517 | DYLIB_COMPATIBILITY_VERSION = 1;
518 | DYLIB_CURRENT_VERSION = 1;
519 | DYLIB_INSTALL_NAME_BASE = "@rpath";
520 | INFOPLIST_FILE = "$(SRCROOT)/UIImageColors/Supporting Files/Info.plist";
521 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
522 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
523 | PRODUCT_BUNDLE_IDENTIFIER = me.jathu.UIImageColors;
524 | PRODUCT_NAME = "$(TARGET_NAME)";
525 | SKIP_INSTALL = YES;
526 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
527 | SWIFT_SWIFT3_OBJC_INFERENCE = Default;
528 | SWIFT_VERSION = 5.0;
529 | };
530 | name = Debug;
531 | };
532 | 035BC8471DAB9FED006CA9BE /* Release */ = {
533 | isa = XCBuildConfiguration;
534 | buildSettings = {
535 | CLANG_ENABLE_MODULES = YES;
536 | CODE_SIGN_IDENTITY = "";
537 | DEFINES_MODULE = YES;
538 | DEVELOPMENT_TEAM = "";
539 | DYLIB_COMPATIBILITY_VERSION = 1;
540 | DYLIB_CURRENT_VERSION = 1;
541 | DYLIB_INSTALL_NAME_BASE = "@rpath";
542 | INFOPLIST_FILE = "$(SRCROOT)/UIImageColors/Supporting Files/Info.plist";
543 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
544 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
545 | PRODUCT_BUNDLE_IDENTIFIER = me.jathu.UIImageColors;
546 | PRODUCT_NAME = "$(TARGET_NAME)";
547 | SKIP_INSTALL = YES;
548 | SWIFT_SWIFT3_OBJC_INFERENCE = Default;
549 | SWIFT_VERSION = 5.0;
550 | };
551 | name = Release;
552 | };
553 | 87A73ED41FD0913A00EE147D /* Debug */ = {
554 | isa = XCBuildConfiguration;
555 | buildSettings = {
556 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
557 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
558 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
559 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
560 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
561 | CLANG_WARN_COMMA = YES;
562 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
563 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
564 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
565 | CLANG_WARN_STRICT_PROTOTYPES = YES;
566 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
567 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
568 | CODE_SIGN_IDENTITY = "iPhone Developer";
569 | CODE_SIGN_STYLE = Automatic;
570 | DEVELOPMENT_TEAM = "";
571 | GCC_C_LANGUAGE_STANDARD = gnu11;
572 | INFOPLIST_FILE = UIImageColorsExample/Info.plist;
573 | IPHONEOS_DEPLOYMENT_TARGET = 11.1;
574 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
575 | PRODUCT_BUNDLE_IDENTIFIER = com.jathu.UIImageColorsExample;
576 | PRODUCT_NAME = "$(TARGET_NAME)";
577 | SWIFT_SWIFT3_OBJC_INFERENCE = Default;
578 | SWIFT_VERSION = 5.0;
579 | TARGETED_DEVICE_FAMILY = "1,2";
580 | };
581 | name = Debug;
582 | };
583 | 87A73ED51FD0913A00EE147D /* Release */ = {
584 | isa = XCBuildConfiguration;
585 | buildSettings = {
586 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
587 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
588 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
589 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
590 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
591 | CLANG_WARN_COMMA = YES;
592 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
593 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
594 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
595 | CLANG_WARN_STRICT_PROTOTYPES = YES;
596 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
597 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
598 | CODE_SIGN_IDENTITY = "iPhone Developer";
599 | CODE_SIGN_STYLE = Automatic;
600 | DEVELOPMENT_TEAM = "";
601 | GCC_C_LANGUAGE_STANDARD = gnu11;
602 | INFOPLIST_FILE = UIImageColorsExample/Info.plist;
603 | IPHONEOS_DEPLOYMENT_TARGET = 11.1;
604 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
605 | PRODUCT_BUNDLE_IDENTIFIER = com.jathu.UIImageColorsExample;
606 | PRODUCT_NAME = "$(TARGET_NAME)";
607 | SWIFT_SWIFT3_OBJC_INFERENCE = Default;
608 | SWIFT_VERSION = 5.0;
609 | TARGETED_DEVICE_FAMILY = "1,2";
610 | };
611 | name = Release;
612 | };
613 | B57E061521F484E0001D5009 /* Debug */ = {
614 | isa = XCBuildConfiguration;
615 | buildSettings = {
616 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
617 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
618 | CLANG_ENABLE_OBJC_WEAK = YES;
619 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
620 | CODE_SIGN_IDENTITY = "-";
621 | CODE_SIGN_STYLE = Automatic;
622 | COMBINE_HIDPI_IMAGES = YES;
623 | DEFINES_MODULE = YES;
624 | DYLIB_COMPATIBILITY_VERSION = 1;
625 | DYLIB_CURRENT_VERSION = 1;
626 | DYLIB_INSTALL_NAME_BASE = "@rpath";
627 | FRAMEWORK_VERSION = A;
628 | GCC_C_LANGUAGE_STANDARD = gnu11;
629 | INFOPLIST_FILE = NSImageColors/Info.plist;
630 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
631 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
632 | MACOSX_DEPLOYMENT_TARGET = 10.11;
633 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
634 | MTL_FAST_MATH = YES;
635 | PRODUCT_BUNDLE_IDENTIFIER = com.jathu.NSImageColors;
636 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
637 | SDKROOT = macosx;
638 | SKIP_INSTALL = YES;
639 | SWIFT_VERSION = 5.0;
640 | };
641 | name = Debug;
642 | };
643 | B57E061621F484E0001D5009 /* Release */ = {
644 | isa = XCBuildConfiguration;
645 | buildSettings = {
646 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
647 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
648 | CLANG_ENABLE_OBJC_WEAK = YES;
649 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
650 | CODE_SIGN_IDENTITY = "-";
651 | CODE_SIGN_STYLE = Automatic;
652 | COMBINE_HIDPI_IMAGES = YES;
653 | DEFINES_MODULE = YES;
654 | DYLIB_COMPATIBILITY_VERSION = 1;
655 | DYLIB_CURRENT_VERSION = 1;
656 | DYLIB_INSTALL_NAME_BASE = "@rpath";
657 | FRAMEWORK_VERSION = A;
658 | GCC_C_LANGUAGE_STANDARD = gnu11;
659 | INFOPLIST_FILE = NSImageColors/Info.plist;
660 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
661 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
662 | MACOSX_DEPLOYMENT_TARGET = 10.11;
663 | MTL_FAST_MATH = YES;
664 | PRODUCT_BUNDLE_IDENTIFIER = com.jathu.NSImageColors;
665 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
666 | SDKROOT = macosx;
667 | SKIP_INSTALL = YES;
668 | SWIFT_VERSION = 5.0;
669 | };
670 | name = Release;
671 | };
672 | /* End XCBuildConfiguration section */
673 |
674 | /* Begin XCConfigurationList section */
675 | 035BC8371DAB9FED006CA9BE /* Build configuration list for PBXProject "UIImageColors" */ = {
676 | isa = XCConfigurationList;
677 | buildConfigurations = (
678 | 035BC8431DAB9FED006CA9BE /* Debug */,
679 | 035BC8441DAB9FED006CA9BE /* Release */,
680 | );
681 | defaultConfigurationIsVisible = 0;
682 | defaultConfigurationName = Release;
683 | };
684 | 035BC8451DAB9FED006CA9BE /* Build configuration list for PBXNativeTarget "UIImageColors" */ = {
685 | isa = XCConfigurationList;
686 | buildConfigurations = (
687 | 035BC8461DAB9FED006CA9BE /* Debug */,
688 | 035BC8471DAB9FED006CA9BE /* Release */,
689 | );
690 | defaultConfigurationIsVisible = 0;
691 | defaultConfigurationName = Release;
692 | };
693 | 87A73ED61FD0913A00EE147D /* Build configuration list for PBXNativeTarget "UIImageColorsExample" */ = {
694 | isa = XCConfigurationList;
695 | buildConfigurations = (
696 | 87A73ED41FD0913A00EE147D /* Debug */,
697 | 87A73ED51FD0913A00EE147D /* Release */,
698 | );
699 | defaultConfigurationIsVisible = 0;
700 | defaultConfigurationName = Release;
701 | };
702 | B57E061421F484E0001D5009 /* Build configuration list for PBXNativeTarget "NSImageColors" */ = {
703 | isa = XCConfigurationList;
704 | buildConfigurations = (
705 | B57E061521F484E0001D5009 /* Debug */,
706 | B57E061621F484E0001D5009 /* Release */,
707 | );
708 | defaultConfigurationIsVisible = 0;
709 | defaultConfigurationName = Release;
710 | };
711 | /* End XCConfigurationList section */
712 | };
713 | rootObject = 035BC8341DAB9FED006CA9BE /* Project object */;
714 | }
715 |
--------------------------------------------------------------------------------
/UIImageColors.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/UIImageColors.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/UIImageColors.xcodeproj/xcshareddata/xcschemes/NSImageColors.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
34 |
35 |
45 |
46 |
52 |
53 |
54 |
55 |
56 |
57 |
63 |
64 |
70 |
71 |
72 |
73 |
75 |
76 |
79 |
80 |
81 |
--------------------------------------------------------------------------------
/UIImageColors.xcodeproj/xcshareddata/xcschemes/UIImageColors.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
34 |
35 |
45 |
46 |
52 |
53 |
54 |
55 |
56 |
57 |
63 |
64 |
70 |
71 |
72 |
73 |
75 |
76 |
79 |
80 |
81 |
--------------------------------------------------------------------------------
/UIImageColors/Sources/UIImageColors.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIImageColors.h
3 | // UIImageColors
4 | //
5 | // Created by Suyeol Jeon on 10/10/2016.
6 | // Copyright © 2016 Jathu Satkunarajah (@jathu) - Toronto. All rights reserved.
7 | //
8 |
9 | #if TARGET_OS_MAC
10 | #import
11 | #else
12 | #import
13 | #endif
14 |
15 | //! Project version number for UIImageColors.
16 | FOUNDATION_EXPORT double UIImageColorsVersionNumber;
17 |
18 | //! Project version string for UIImageColors.
19 | FOUNDATION_EXPORT const unsigned char UIImageColorsVersionString[];
20 |
21 | // In this header, you should import all the public headers of your framework using statements like #import
22 |
23 |
24 |
--------------------------------------------------------------------------------
/UIImageColors/Sources/UIImageColors.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIImageColors.swift
3 | // https://github.com/jathu/UIImageColors
4 | //
5 | // Created by Jathu Satkunarajah (@jathu) on 2015-06-11 - Toronto
6 | // Based on Cocoa version by Panic Inc. - Portland
7 | //
8 |
9 | #if os(OSX)
10 | import AppKit
11 | public typealias UIImage = NSImage
12 | public typealias UIColor = NSColor
13 | #else
14 | import UIKit
15 | #endif
16 |
17 | public struct UIImageColors {
18 | public var background: UIColor!
19 | public var primary: UIColor!
20 | public var secondary: UIColor!
21 | public var detail: UIColor!
22 |
23 | public init(background: UIColor, primary: UIColor, secondary: UIColor, detail: UIColor) {
24 | self.background = background
25 | self.primary = primary
26 | self.secondary = secondary
27 | self.detail = detail
28 | }
29 | }
30 |
31 | public enum UIImageColorsQuality: CGFloat {
32 | case lowest = 50 // 50px
33 | case low = 100 // 100px
34 | case high = 250 // 250px
35 | case highest = 0 // No scale
36 | }
37 |
38 | fileprivate struct UIImageColorsCounter {
39 | let color: Double
40 | let count: Int
41 | init(color: Double, count: Int) {
42 | self.color = color
43 | self.count = count
44 | }
45 | }
46 |
47 | /*
48 | Extension on double that replicates UIColor methods. We DO NOT want these
49 | exposed outside of the library because they don't make sense outside of the
50 | context of UIImageColors.
51 | */
52 | fileprivate extension Double {
53 |
54 | private var r: Double {
55 | return fmod(floor(self/1000000),1000000)
56 | }
57 |
58 | private var g: Double {
59 | return fmod(floor(self/1000),1000)
60 | }
61 |
62 | private var b: Double {
63 | return fmod(self,1000)
64 | }
65 |
66 | var isDarkColor: Bool {
67 | return (r*0.2126) + (g*0.7152) + (b*0.0722) < 127.5
68 | }
69 |
70 | var isBlackOrWhite: Bool {
71 | return (r > 232 && g > 232 && b > 232) || (r < 23 && g < 23 && b < 23)
72 | }
73 |
74 | func isDistinct(_ other: Double) -> Bool {
75 | let _r = self.r
76 | let _g = self.g
77 | let _b = self.b
78 | let o_r = other.r
79 | let o_g = other.g
80 | let o_b = other.b
81 |
82 | return (fabs(_r-o_r) > 63.75 || fabs(_g-o_g) > 63.75 || fabs(_b-o_b) > 63.75)
83 | && !(fabs(_r-_g) < 7.65 && fabs(_r-_b) < 7.65 && fabs(o_r-o_g) < 7.65 && fabs(o_r-o_b) < 7.65)
84 | }
85 |
86 | func with(minSaturation: Double) -> Double {
87 | // Ref: https://en.wikipedia.org/wiki/HSL_and_HSV
88 |
89 | // Convert RGB to HSV
90 |
91 | let _r = r/255
92 | let _g = g/255
93 | let _b = b/255
94 | var H, S, V: Double
95 | let M = fmax(_r,fmax(_g, _b))
96 | var C = M-fmin(_r,fmin(_g, _b))
97 |
98 | V = M
99 | S = V == 0 ? 0:C/V
100 |
101 | if minSaturation <= S {
102 | return self
103 | }
104 |
105 | if C == 0 {
106 | H = 0
107 | } else if _r == M {
108 | H = fmod((_g-_b)/C, 6)
109 | } else if _g == M {
110 | H = 2+((_b-_r)/C)
111 | } else {
112 | H = 4+((_r-_g)/C)
113 | }
114 |
115 | if H < 0 {
116 | H += 6
117 | }
118 |
119 | // Back to RGB
120 |
121 | C = V*minSaturation
122 | let X = C*(1-fabs(fmod(H,2)-1))
123 | var R, G, B: Double
124 |
125 | switch H {
126 | case 0...1:
127 | R = C
128 | G = X
129 | B = 0
130 | case 1...2:
131 | R = X
132 | G = C
133 | B = 0
134 | case 2...3:
135 | R = 0
136 | G = C
137 | B = X
138 | case 3...4:
139 | R = 0
140 | G = X
141 | B = C
142 | case 4...5:
143 | R = X
144 | G = 0
145 | B = C
146 | case 5..<6:
147 | R = C
148 | G = 0
149 | B = X
150 | default:
151 | R = 0
152 | G = 0
153 | B = 0
154 | }
155 |
156 | let m = V-C
157 |
158 | return (floor((R + m)*255)*1000000)+(floor((G + m)*255)*1000)+floor((B + m)*255)
159 | }
160 |
161 | func isContrasting(_ color: Double) -> Bool {
162 | let bgLum = (0.2126*r)+(0.7152*g)+(0.0722*b)+12.75
163 | let fgLum = (0.2126*color.r)+(0.7152*color.g)+(0.0722*color.b)+12.75
164 | if bgLum > fgLum {
165 | return 1.6 < bgLum/fgLum
166 | } else {
167 | return 1.6 < fgLum/bgLum
168 | }
169 | }
170 |
171 | var uicolor: UIColor {
172 | return UIColor(red: CGFloat(r)/255, green: CGFloat(g)/255, blue: CGFloat(b)/255, alpha: 1)
173 | }
174 |
175 | var pretty: String {
176 | return "\(Int(self.r)), \(Int(self.g)), \(Int(self.b))"
177 | }
178 | }
179 |
180 | extension UIImage {
181 | #if os(OSX)
182 | private func resizeForUIImageColors(newSize: CGSize) -> UIImage? {
183 | let frame = CGRect(origin: .zero, size: newSize)
184 | guard let representation = bestRepresentation(for: frame, context: nil, hints: nil) else {
185 | return nil
186 | }
187 | let result = NSImage(size: newSize, flipped: false, drawingHandler: { (_) -> Bool in
188 | return representation.draw(in: frame)
189 | })
190 |
191 | return result
192 | }
193 | #else
194 | private func resizeForUIImageColors(newSize: CGSize) -> UIImage? {
195 | UIGraphicsBeginImageContextWithOptions(newSize, false, 0)
196 | defer {
197 | UIGraphicsEndImageContext()
198 | }
199 | self.draw(in: CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height))
200 | guard let result = UIGraphicsGetImageFromCurrentImageContext() else {
201 | fatalError("UIImageColors.resizeForUIImageColors failed: UIGraphicsGetImageFromCurrentImageContext returned nil.")
202 | }
203 |
204 | return result
205 | }
206 | #endif
207 |
208 | public func getColors(quality: UIImageColorsQuality = .high, _ completion: @escaping (UIImageColors?) -> Void) {
209 | DispatchQueue.global().async {
210 | let result = self.getColors(quality: quality)
211 | DispatchQueue.main.async {
212 | completion(result)
213 | }
214 | }
215 | }
216 |
217 | public func getColors(quality: UIImageColorsQuality = .high) -> UIImageColors? {
218 | var scaleDownSize: CGSize = self.size
219 | if quality != .highest {
220 | if self.size.width < self.size.height {
221 | let ratio = self.size.height/self.size.width
222 | scaleDownSize = CGSize(width: quality.rawValue/ratio, height: quality.rawValue)
223 | } else {
224 | let ratio = self.size.width/self.size.height
225 | scaleDownSize = CGSize(width: quality.rawValue, height: quality.rawValue/ratio)
226 | }
227 | }
228 |
229 | guard let resizedImage = self.resizeForUIImageColors(newSize: scaleDownSize) else { return nil }
230 |
231 | #if os(OSX)
232 | guard let cgImage = resizedImage.cgImage(forProposedRect: nil, context: nil, hints: nil) else { return nil }
233 | #else
234 | guard let cgImage = resizedImage.cgImage else { return nil }
235 | #endif
236 |
237 | let width: Int = cgImage.width
238 | let height: Int = cgImage.height
239 |
240 | let threshold = Int(CGFloat(height)*0.01)
241 | var proposed: [Double] = [-1,-1,-1,-1]
242 |
243 | guard let data = CFDataGetBytePtr(cgImage.dataProvider!.data) else {
244 | fatalError("UIImageColors.getColors failed: could not get cgImage data.")
245 | }
246 |
247 | let imageColors = NSCountedSet(capacity: width*height)
248 | for x in 0.. ComparisonResult in
258 | let m = main as! UIImageColorsCounter, o = other as! UIImageColorsCounter
259 | if m.count < o.count {
260 | return .orderedDescending
261 | } else if m.count == o.count {
262 | return .orderedSame
263 | } else {
264 | return .orderedAscending
265 | }
266 | }
267 |
268 | var enumerator = imageColors.objectEnumerator()
269 | var sortedColors = NSMutableArray(capacity: imageColors.count)
270 | while let K = enumerator.nextObject() as? Double {
271 | let C = imageColors.count(for: K)
272 | if threshold < C {
273 | sortedColors.add(UIImageColorsCounter(color: K, count: C))
274 | }
275 | }
276 | sortedColors.sort(comparator: sortedColorComparator)
277 |
278 | var proposedEdgeColor: UIImageColorsCounter
279 | if 0 < sortedColors.count {
280 | proposedEdgeColor = sortedColors.object(at: 0) as! UIImageColorsCounter
281 | } else {
282 | proposedEdgeColor = UIImageColorsCounter(color: 0, count: 1)
283 | }
284 |
285 | if proposedEdgeColor.color.isBlackOrWhite && 0 < sortedColors.count {
286 | for i in 1.. 0.3 {
289 | if !nextProposedEdgeColor.color.isBlackOrWhite {
290 | proposedEdgeColor = nextProposedEdgeColor
291 | break
292 | }
293 | } else {
294 | break
295 | }
296 | }
297 | }
298 | proposed[0] = proposedEdgeColor.color
299 |
300 | enumerator = imageColors.objectEnumerator()
301 | sortedColors.removeAllObjects()
302 | sortedColors = NSMutableArray(capacity: imageColors.count)
303 | let findDarkTextColor = !proposed[0].isDarkColor
304 |
305 | while var K = enumerator.nextObject() as? Double {
306 | K = K.with(minSaturation: 0.15)
307 | if K.isDarkColor == findDarkTextColor {
308 | let C = imageColors.count(for: K)
309 | sortedColors.add(UIImageColorsCounter(color: K, count: C))
310 | }
311 | }
312 | sortedColors.sort(comparator: sortedColorComparator)
313 |
314 | for color in sortedColors {
315 | let color = (color as! UIImageColorsCounter).color
316 |
317 | if proposed[1] == -1 {
318 | if color.isContrasting(proposed[0]) {
319 | proposed[1] = color
320 | }
321 | } else if proposed[2] == -1 {
322 | if !color.isContrasting(proposed[0]) || !proposed[1].isDistinct(color) {
323 | continue
324 | }
325 | proposed[2] = color
326 | } else if proposed[3] == -1 {
327 | if !color.isContrasting(proposed[0]) || !proposed[2].isDistinct(color) || !proposed[1].isDistinct(color) {
328 | continue
329 | }
330 | proposed[3] = color
331 | break
332 | }
333 | }
334 |
335 | let isDarkBackground = proposed[0].isDarkColor
336 | for i in 1...3 {
337 | if proposed[i] == -1 {
338 | proposed[i] = isDarkBackground ? 255255255:0
339 | }
340 | }
341 |
342 | return UIImageColors(
343 | background: proposed[0].uicolor,
344 | primary: proposed[1].uicolor,
345 | secondary: proposed[2].uicolor,
346 | detail: proposed[3].uicolor
347 | )
348 | }
349 | }
350 |
351 |
--------------------------------------------------------------------------------
/UIImageColors/Supporting Files/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 2.3.0
19 | CFBundleVersion
20 | $(CURRENT_PROJECT_VERSION)
21 | NSPrincipalClass
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/UIImageColorsExample/Album.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Album.swift
3 | // UIImageColorsExample
4 | //
5 | // Created by Jathu Satkunarajah on 2017-11-30 - Toronto
6 | // Copyright © 2017 Jathu Satkunarajah. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | struct Album {
12 | let albumImage: UIImage?
13 | let albumName: String
14 | let artistName: String
15 | let year: Int
16 |
17 | public init(albumImage: UIImage?, albumName: String, artistName: String, year: Int) {
18 | self.albumImage = albumImage
19 | self.albumName = albumName
20 | self.artistName = artistName
21 | self.year = year
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/UIImageColorsExample/AlbumViewCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AlbumViewCell.swift
3 | // UIImageColorsExample
4 | //
5 | // Created by Jathu Satkunarajah on 2017-11-30 - Toronto
6 | // Copyright © 2017 Jathu Satkunarajah. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class AlbumViewCell: UICollectionViewCell {
12 |
13 | let imageView: UIImageView = {
14 | let i = UIImageView()
15 | i.translatesAutoresizingMaskIntoConstraints = false
16 | i.contentMode = .scaleAspectFill
17 | i.layer.masksToBounds = true
18 | return i
19 | }()
20 |
21 | override init(frame: CGRect) {
22 | super.init(frame: frame)
23 |
24 | // Add subview
25 | self.contentView.addSubview(self.imageView)
26 |
27 | // Constraints
28 | NSLayoutConstraint.activate([
29 | self.imageView.topAnchor.constraint(equalTo: self.contentView.topAnchor),
30 | self.imageView.trailingAnchor.constraint(equalTo: self.contentView.trailingAnchor),
31 | self.imageView.bottomAnchor.constraint(equalTo: self.contentView.bottomAnchor),
32 | self.imageView.leadingAnchor.constraint(equalTo: self.contentView.leadingAnchor),
33 | ])
34 | }
35 |
36 | required init?(coder aDecoder: NSCoder) {
37 | fatalError("init(coder:) has not been implemented")
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/UIImageColorsExample/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // UIImageColorsExample
4 | //
5 | // Created by Jathu Satkunarajah on 2017-11-30 - Toronto
6 | // Copyright © 2017 Jathu Satkunarajah. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
17 |
18 | // Override storyboard
19 | self.window = UIWindow(frame: UIScreen.main.bounds)
20 | self.window?.makeKeyAndVisible()
21 | self.window?.rootViewController = ViewController()
22 |
23 | return true
24 | }
25 |
26 |
27 | }
28 |
29 |
--------------------------------------------------------------------------------
/UIImageColorsExample/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/UIImageColorsExample/Assets.xcassets/Blue Nude II - Henri Matisse.imageset/Blue Nude II - Henri Matisse.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jathu/UIImageColors/f064be8ee0b03158e61135e6c384aee18d7a5414/UIImageColorsExample/Assets.xcassets/Blue Nude II - Henri Matisse.imageset/Blue Nude II - Henri Matisse.jpg
--------------------------------------------------------------------------------
/UIImageColorsExample/Assets.xcassets/Blue Nude II - Henri Matisse.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "Blue Nude II - Henri Matisse.jpg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/UIImageColorsExample/Assets.xcassets/Cafe Terrace at Night - Vincent Van Gogh.imageset/Cafe Terrace at Night - Vincent Van Gogh.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jathu/UIImageColors/f064be8ee0b03158e61135e6c384aee18d7a5414/UIImageColorsExample/Assets.xcassets/Cafe Terrace at Night - Vincent Van Gogh.imageset/Cafe Terrace at Night - Vincent Van Gogh.jpg
--------------------------------------------------------------------------------
/UIImageColorsExample/Assets.xcassets/Cafe Terrace at Night - Vincent Van Gogh.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "Cafe Terrace at Night - Vincent Van Gogh.jpg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/UIImageColorsExample/Assets.xcassets/Calvin Klein - Kaws.imageset/Calvin Klein - Kaws.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jathu/UIImageColors/f064be8ee0b03158e61135e6c384aee18d7a5414/UIImageColorsExample/Assets.xcassets/Calvin Klein - Kaws.imageset/Calvin Klein - Kaws.jpg
--------------------------------------------------------------------------------
/UIImageColorsExample/Assets.xcassets/Calvin Klein - Kaws.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "Calvin Klein - Kaws.jpg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/UIImageColorsExample/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/UIImageColorsExample/Assets.xcassets/Le Reve - Pablo Picasso.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "Le Reve - Pablo Picasso.jpg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/UIImageColorsExample/Assets.xcassets/Le Reve - Pablo Picasso.imageset/Le Reve - Pablo Picasso.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jathu/UIImageColors/f064be8ee0b03158e61135e6c384aee18d7a5414/UIImageColorsExample/Assets.xcassets/Le Reve - Pablo Picasso.imageset/Le Reve - Pablo Picasso.jpg
--------------------------------------------------------------------------------
/UIImageColorsExample/Assets.xcassets/Les Demoiselles d'Avignon - Picasso.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "Les Demoiselles d'Avignon - Picasso.jpg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/UIImageColorsExample/Assets.xcassets/Les Demoiselles d'Avignon - Picasso.imageset/Les Demoiselles d'Avignon - Picasso.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jathu/UIImageColors/f064be8ee0b03158e61135e6c384aee18d7a5414/UIImageColorsExample/Assets.xcassets/Les Demoiselles d'Avignon - Picasso.imageset/Les Demoiselles d'Avignon - Picasso.jpg
--------------------------------------------------------------------------------
/UIImageColorsExample/Assets.xcassets/Mona Lisa - Leonardo da Vinci.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "Mona Lisa - Leonardo da Vinci.jpg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/UIImageColorsExample/Assets.xcassets/Mona Lisa - Leonardo da Vinci.imageset/Mona Lisa - Leonardo da Vinci.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jathu/UIImageColors/f064be8ee0b03158e61135e6c384aee18d7a5414/UIImageColorsExample/Assets.xcassets/Mona Lisa - Leonardo da Vinci.imageset/Mona Lisa - Leonardo da Vinci.jpg
--------------------------------------------------------------------------------
/UIImageColorsExample/Assets.xcassets/Nighthawks - Edward Hopper.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "Nighthawks - Edward Hopper.jpg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/UIImageColorsExample/Assets.xcassets/Nighthawks - Edward Hopper.imageset/Nighthawks - Edward Hopper.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jathu/UIImageColors/f064be8ee0b03158e61135e6c384aee18d7a5414/UIImageColorsExample/Assets.xcassets/Nighthawks - Edward Hopper.imageset/Nighthawks - Edward Hopper.jpg
--------------------------------------------------------------------------------
/UIImageColorsExample/Assets.xcassets/No. 210:No. 211 - Mark Rothko.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "No. 210:No. 211 - Mark Rothko.jpg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/UIImageColorsExample/Assets.xcassets/No. 210:No. 211 - Mark Rothko.imageset/No. 210:No. 211 - Mark Rothko.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jathu/UIImageColors/f064be8ee0b03158e61135e6c384aee18d7a5414/UIImageColorsExample/Assets.xcassets/No. 210:No. 211 - Mark Rothko.imageset/No. 210:No. 211 - Mark Rothko.jpg
--------------------------------------------------------------------------------
/UIImageColorsExample/Assets.xcassets/Number 1A - Jackson Pollock.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "Number 1A - Jackson Pollock.jpg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/UIImageColorsExample/Assets.xcassets/Number 1A - Jackson Pollock.imageset/Number 1A - Jackson Pollock.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jathu/UIImageColors/f064be8ee0b03158e61135e6c384aee18d7a5414/UIImageColorsExample/Assets.xcassets/Number 1A - Jackson Pollock.imageset/Number 1A - Jackson Pollock.jpg
--------------------------------------------------------------------------------
/UIImageColorsExample/Assets.xcassets/Self-portrait Spring 1887 - Vincent Van Gogh.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "Self-portrait Spring 1887 - Vincent Van Gogh.jpg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/UIImageColorsExample/Assets.xcassets/Self-portrait Spring 1887 - Vincent Van Gogh.imageset/Self-portrait Spring 1887 - Vincent Van Gogh.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jathu/UIImageColors/f064be8ee0b03158e61135e6c384aee18d7a5414/UIImageColorsExample/Assets.xcassets/Self-portrait Spring 1887 - Vincent Van Gogh.imageset/Self-portrait Spring 1887 - Vincent Van Gogh.jpg
--------------------------------------------------------------------------------
/UIImageColorsExample/Assets.xcassets/Skull - Jean-Michel Basquiat.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "Skull - Jean-Michel Basquiat.jpg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/UIImageColorsExample/Assets.xcassets/Skull - Jean-Michel Basquiat.imageset/Skull - Jean-Michel Basquiat.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jathu/UIImageColors/f064be8ee0b03158e61135e6c384aee18d7a5414/UIImageColorsExample/Assets.xcassets/Skull - Jean-Michel Basquiat.imageset/Skull - Jean-Michel Basquiat.jpg
--------------------------------------------------------------------------------
/UIImageColorsExample/Assets.xcassets/Woman I - Willem de Kooning.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "Woman I - Willem de Kooning.jpg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/UIImageColorsExample/Assets.xcassets/Woman I - Willem de Kooning.imageset/Woman I - Willem de Kooning.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jathu/UIImageColors/f064be8ee0b03158e61135e6c384aee18d7a5414/UIImageColorsExample/Assets.xcassets/Woman I - Willem de Kooning.imageset/Woman I - Willem de Kooning.jpg
--------------------------------------------------------------------------------
/UIImageColorsExample/Assets.xcassets/play.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "play@1x.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "play@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "play@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/UIImageColorsExample/Assets.xcassets/play.imageset/play@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jathu/UIImageColors/f064be8ee0b03158e61135e6c384aee18d7a5414/UIImageColorsExample/Assets.xcassets/play.imageset/play@1x.png
--------------------------------------------------------------------------------
/UIImageColorsExample/Assets.xcassets/play.imageset/play@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jathu/UIImageColors/f064be8ee0b03158e61135e6c384aee18d7a5414/UIImageColorsExample/Assets.xcassets/play.imageset/play@2x.png
--------------------------------------------------------------------------------
/UIImageColorsExample/Assets.xcassets/play.imageset/play@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jathu/UIImageColors/f064be8ee0b03158e61135e6c384aee18d7a5414/UIImageColorsExample/Assets.xcassets/play.imageset/play@3x.png
--------------------------------------------------------------------------------
/UIImageColorsExample/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/UIImageColorsExample/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/UIImageColorsExample/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UILaunchStoryboardName
24 | LaunchScreen
25 | UIMainStoryboardFile
26 | Main
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 | UIViewControllerBasedStatusBarAppearance
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/UIImageColorsExample/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // UIImageColorsExample
4 | //
5 | // Created by Jathu Satkunarajah on 2017-11-30 - Toronto
6 | // Copyright © 2017 Jathu Satkunarajah. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import UIImageColors
11 |
12 | class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
13 |
14 | let albums: [Album] = [
15 | Album(albumImage: #imageLiteral(resourceName: "Calvin Klein - Kaws"), albumName: "Calvin Klein", artistName: "Kaws", year: 1999),
16 | Album(albumImage: #imageLiteral(resourceName: "Cafe Terrace at Night - Vincent Van Gogh"), albumName: "Cafe Terrace at Night", artistName: "Vincent Van Gogh", year: 1888),
17 | Album(albumImage: #imageLiteral(resourceName: "Woman I - Willem de Kooning"), albumName: "Woman I", artistName: "Willem de Kooning", year: 1952),
18 | Album(albumImage: #imageLiteral(resourceName: "Skull - Jean-Michel Basquiat"), albumName: "Skull", artistName: "Jean-Michel Basquiat", year: 1981),
19 | Album(albumImage: #imageLiteral(resourceName: "Les Demoiselles d'Avignon - Picasso"), albumName: "Les Demoiselles d'Avignon", artistName: "Pablo Picasso", year: 1907),
20 | Album(albumImage: #imageLiteral(resourceName: "Le Reve - Pablo Picasso"), albumName: "Le Rêve", artistName: "Pablo Picasso", year: 1932),
21 | Album(albumImage: #imageLiteral(resourceName: "Mona Lisa - Leonardo da Vinci"), albumName: "Mona Lisa", artistName: "Leonardo da Vinci", year: 1503),
22 | Album(albumImage: #imageLiteral(resourceName: "No. 210:No. 211 - Mark Rothko"), albumName: "No. 210/211 Orange", artistName: "Mark Rothko", year: 1960),
23 | Album(albumImage: #imageLiteral(resourceName: "Blue Nude II - Henri Matisse"), albumName: "Blue Nude II", artistName: "Henri Matisse", year: 1952),
24 | Album(albumImage: #imageLiteral(resourceName: "Nighthawks - Edward Hopper"), albumName: "Nighthawks", artistName: "Edward Hopper", year: 1942),
25 | Album(albumImage: #imageLiteral(resourceName: "Number 1A - Jackson Pollock"), albumName: "Number 1A", artistName: "Jackson Pollock", year: 1948),
26 | Album(albumImage: #imageLiteral(resourceName: "Self-portrait Spring 1887 - Vincent Van Gogh"), albumName: "Self-Portrait", artistName: "Vincent Van Gogh", year: 1887),
27 | ]
28 |
29 | private let cellID = "cellID"
30 | private let cellSizeFactor: CGFloat = 0.8
31 | private lazy var cellSize: CGSize = {
32 | let w = self.view.frame.width
33 | return CGSize(width: w*self.cellSizeFactor, height: w)
34 | }()
35 | private lazy var cellSpacing: CGFloat = {
36 | return self.view.frame.width*((1-self.cellSizeFactor)/4)
37 | }()
38 | private lazy var collectionView: UICollectionView = {
39 | let l = UICollectionViewFlowLayout()
40 | l.scrollDirection = .horizontal
41 | l.minimumInteritemSpacing = 0
42 | l.minimumLineSpacing = self.cellSpacing
43 | let c = UICollectionView(frame: .zero, collectionViewLayout: l)
44 | c.translatesAutoresizingMaskIntoConstraints = false
45 | c.isScrollEnabled = true
46 | c.isPagingEnabled = false
47 | c.showsHorizontalScrollIndicator = false
48 | c.showsVerticalScrollIndicator = false
49 | c.backgroundColor = .clear
50 | c.register(AlbumViewCell.self, forCellWithReuseIdentifier: self.cellID)
51 | c.dataSource = self
52 | c.delegate = self
53 | return c
54 | }()
55 |
56 | private let mainLabel: UILabel = {
57 | let l = UILabel()
58 | l.translatesAutoresizingMaskIntoConstraints = false
59 | l.textAlignment = .left
60 | l.numberOfLines = 2
61 | l.font = UIFont.systemFont(ofSize: 25, weight: UIFont.Weight.regular)
62 | return l
63 | }()
64 |
65 | private let secondaryLabel: UILabel = {
66 | let l = UILabel()
67 | l.translatesAutoresizingMaskIntoConstraints = false
68 | l.textAlignment = .left
69 | l.numberOfLines = 1
70 | l.font = UIFont.systemFont(ofSize: 20, weight: UIFont.Weight.regular)
71 | return l
72 | }()
73 |
74 | private let detailLabel: UILabel = {
75 | let l = UILabel()
76 | l.translatesAutoresizingMaskIntoConstraints = false
77 | l.textAlignment = .left
78 | l.numberOfLines = 1
79 | l.font = UIFont.systemFont(ofSize: 15, weight: UIFont.Weight.regular)
80 | return l
81 | }()
82 |
83 | private var selectedIndex: IndexPath?
84 | private var timer: Timer?
85 | private let playButton: UIButton = {
86 | let b = UIButton()
87 | b.translatesAutoresizingMaskIntoConstraints = false
88 | b.setImage(#imageLiteral(resourceName: "play").withRenderingMode(.alwaysTemplate), for: .normal)
89 | b.tintColor = .white
90 | return b
91 | }()
92 |
93 | override var prefersStatusBarHidden: Bool {
94 | return true
95 | }
96 |
97 | override func viewDidLoad() {
98 | super.viewDidLoad()
99 | self.view.backgroundColor = .white
100 |
101 | // Add subviews
102 | self.view.addSubview(self.collectionView)
103 | self.view.addSubview(self.mainLabel)
104 | self.view.addSubview(self.secondaryLabel)
105 | self.view.addSubview(self.detailLabel)
106 | self.view.addSubview(self.playButton)
107 |
108 | // Constraints
109 | NSLayoutConstraint.activate([
110 | self.collectionView.widthAnchor.constraint(equalTo: self.view.widthAnchor),
111 | self.collectionView.heightAnchor.constraint(equalTo: self.view.heightAnchor, multiplier: 0.6),
112 | self.collectionView.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
113 | self.collectionView.centerYAnchor.constraint(equalTo: self.view.centerYAnchor),
114 |
115 | self.mainLabel.widthAnchor.constraint(equalTo: self.view.widthAnchor, multiplier: self.cellSizeFactor),
116 | self.mainLabel.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
117 | self.mainLabel.bottomAnchor.constraint(equalTo: self.collectionView.topAnchor),
118 |
119 | self.secondaryLabel.widthAnchor.constraint(equalTo: self.mainLabel.widthAnchor),
120 | self.secondaryLabel.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
121 | self.secondaryLabel.topAnchor.constraint(equalTo: self.collectionView.bottomAnchor),
122 |
123 | self.detailLabel.widthAnchor.constraint(equalTo: self.mainLabel.widthAnchor),
124 | self.detailLabel.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
125 | self.detailLabel.topAnchor.constraint(equalTo: self.secondaryLabel.bottomAnchor),
126 |
127 | self.playButton.widthAnchor.constraint(equalToConstant: 24),
128 | self.playButton.heightAnchor.constraint(equalToConstant: 24),
129 | self.playButton.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -12),
130 | self.playButton.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: -12),
131 | ])
132 |
133 | // Set up play button
134 | self.playButton.addTarget(self, action: #selector(setupPlayTimer), for: .touchUpInside)
135 |
136 | // Update view
137 | self.selectedIndex = IndexPath(item: 0, section: 0)
138 | self.updateView(with: self.albums[0])
139 | }
140 |
141 | @objc func setupPlayTimer() {
142 | if self.timer == nil {
143 | self.timer = Timer.scheduledTimer(timeInterval: 2, target: self, selector: #selector(startPlaying), userInfo: nil, repeats: true)
144 | self.playButton.isHidden = true
145 | }
146 | }
147 |
148 | @objc func startPlaying() {
149 | if let index = self.selectedIndex {
150 | self.selectedIndex = IndexPath(item: (index.item+1)%self.albums.count, section: 0)
151 | self.goTo(indexPath: self.selectedIndex)
152 | }
153 | }
154 |
155 | func goTo(indexPath: IndexPath?) {
156 | if let index = indexPath {
157 | self.collectionView.scrollToItem(at: index, at: .centeredHorizontally, animated: true)
158 | self.updateView(with: self.albums[index.item])
159 | }
160 | }
161 |
162 | // Mark: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout
163 |
164 | func numberOfSections(in collectionView: UICollectionView) -> Int {
165 | return 1
166 | }
167 |
168 | func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
169 | return self.albums.count
170 | }
171 |
172 | func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
173 | let cell = collectionView.dequeueReusableCell(withReuseIdentifier: self.cellID, for: indexPath) as! AlbumViewCell
174 | cell.imageView.image = self.albums[indexPath.item].albumImage
175 | return cell
176 | }
177 |
178 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
179 | return self.cellSize
180 | }
181 |
182 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
183 | return UIEdgeInsets(top: 0, left: self.cellSpacing*2, bottom: 0, right: self.cellSpacing*2)
184 | }
185 |
186 | func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
187 | if let _ = self.timer {
188 | self.timer?.invalidate()
189 | self.timer = nil
190 | self.playButton.isHidden = false
191 | }
192 | }
193 |
194 | func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
195 | let rect = CGRect(origin: self.collectionView.contentOffset, size: self.collectionView.bounds.size)
196 | let mid = CGPoint(x: rect.midX, y: rect.midY)
197 | DispatchQueue.main.async {
198 | var smallestDiff = CGFloat.greatestFiniteMagnitude
199 | for index in self.collectionView.indexPathsForVisibleItems {
200 | if let cell = self.collectionView.cellForItem(at: index) {
201 | let diff = abs((cell.frame.origin.x+(cell.frame.width/2))-mid.x)
202 | if diff < smallestDiff {
203 | smallestDiff = diff
204 | self.selectedIndex = index
205 | }
206 | }
207 | }
208 |
209 | self.goTo(indexPath: self.selectedIndex)
210 | }
211 | }
212 |
213 | private func updateView(with album: Album) {
214 | album.albumImage?.getColors(quality: .high) { colors in
215 | guard let colors = colors else { return }
216 |
217 | UIView.animate(withDuration: 0.15, animations: {
218 | self.view.backgroundColor = colors.background
219 |
220 | self.mainLabel.text = album.albumName
221 | self.mainLabel.textColor = colors.primary
222 |
223 | self.secondaryLabel.text = album.artistName
224 | self.secondaryLabel.textColor = colors.secondary
225 |
226 | self.detailLabel.text = "\(album.year)"
227 | self.detailLabel.textColor = colors.detail
228 |
229 | self.playButton.tintColor = colors.detail
230 | })
231 | }
232 | }
233 | }
234 |
235 |
--------------------------------------------------------------------------------
/preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jathu/UIImageColors/f064be8ee0b03158e61135e6c384aee18d7a5414/preview.png
--------------------------------------------------------------------------------