├── snapShot
├── 1.png
├── 2.png
├── 3.png
├── 4.png
├── 5.png
├── 6.png
├── 7.png
├── 8.png
├── 9.png
├── 10.png
├── logo.png
└── Banners.png
├── TGImage
├── TGImage
│ ├── Assets.xcassets
│ │ ├── Contents.json
│ │ ├── 2.imageset
│ │ │ ├── 2.png
│ │ │ └── Contents.json
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ ├── Info.plist
│ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ ├── AppDelegate.swift
│ ├── TGImage
│ │ └── TGImage.swift
│ └── ViewController.swift
├── TGImage.xcodeproj
│ ├── project.xcworkspace
│ │ └── contents.xcworkspacedata
│ └── project.pbxproj
└── TGImage.podspec
├── LICENSE
├── .gitignore
└── README.md
/snapShot/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/targetcloud/TGImage/HEAD/snapShot/1.png
--------------------------------------------------------------------------------
/snapShot/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/targetcloud/TGImage/HEAD/snapShot/2.png
--------------------------------------------------------------------------------
/snapShot/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/targetcloud/TGImage/HEAD/snapShot/3.png
--------------------------------------------------------------------------------
/snapShot/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/targetcloud/TGImage/HEAD/snapShot/4.png
--------------------------------------------------------------------------------
/snapShot/5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/targetcloud/TGImage/HEAD/snapShot/5.png
--------------------------------------------------------------------------------
/snapShot/6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/targetcloud/TGImage/HEAD/snapShot/6.png
--------------------------------------------------------------------------------
/snapShot/7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/targetcloud/TGImage/HEAD/snapShot/7.png
--------------------------------------------------------------------------------
/snapShot/8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/targetcloud/TGImage/HEAD/snapShot/8.png
--------------------------------------------------------------------------------
/snapShot/9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/targetcloud/TGImage/HEAD/snapShot/9.png
--------------------------------------------------------------------------------
/snapShot/10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/targetcloud/TGImage/HEAD/snapShot/10.png
--------------------------------------------------------------------------------
/snapShot/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/targetcloud/TGImage/HEAD/snapShot/logo.png
--------------------------------------------------------------------------------
/snapShot/Banners.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/targetcloud/TGImage/HEAD/snapShot/Banners.png
--------------------------------------------------------------------------------
/TGImage/TGImage/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/TGImage/TGImage/Assets.xcassets/2.imageset/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/targetcloud/TGImage/HEAD/TGImage/TGImage/Assets.xcassets/2.imageset/2.png
--------------------------------------------------------------------------------
/TGImage/TGImage.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/TGImage/TGImage/Assets.xcassets/2.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "2.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/TGImage/TGImage.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = "TGImage"
3 | s.version = "0.0.2"
4 | s.summary = "一款以最时髦的方式来使用UIImage的swift插件"
5 | s.homepage = "https://github.com/targetcloud/TGImage"
6 | s.license = "MIT"
7 | s.author = { "targetcloud" => "targetcloud@163.com" }
8 | s.platform = :ios, "8.0"
9 | s.source = { :git => "https://github.com/targetcloud/TGImage.git", :tag => s.version }
10 | s.source_files = "TGImage/TGImage/TGImage/**/*.{swift,h,m}"
11 | s.requires_arc = true
12 | end
13 |
--------------------------------------------------------------------------------
/TGImage/TGImage/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 | "info" : {
45 | "version" : 1,
46 | "author" : "xcode"
47 | }
48 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 targetcloud
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 |
--------------------------------------------------------------------------------
/TGImage/TGImage/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 | 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 |
38 |
39 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
4 |
5 | ## Build generated
6 | build/
7 | DerivedData/
8 |
9 | ## Various settings
10 | *.pbxuser
11 | !default.pbxuser
12 | *.mode1v3
13 | !default.mode1v3
14 | *.mode2v3
15 | !default.mode2v3
16 | *.perspectivev3
17 | !default.perspectivev3
18 | xcuserdata/
19 |
20 | ## Other
21 | *.moved-aside
22 | *.xccheckout
23 | *.xcscmblueprint
24 |
25 | ## Obj-C/Swift specific
26 | *.hmap
27 | *.ipa
28 | *.dSYM.zip
29 | *.dSYM
30 |
31 | ## Playgrounds
32 | timeline.xctimeline
33 | playground.xcworkspace
34 |
35 | # Swift Package Manager
36 | #
37 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
38 | # Packages/
39 | # Package.pins
40 | .build/
41 |
42 | # CocoaPods
43 | #
44 | # We recommend against adding the Pods directory to your .gitignore. However
45 | # you should judge for yourself, the pros and cons are mentioned at:
46 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
47 | #
48 | # Pods/
49 |
50 | # Carthage
51 | #
52 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
53 | # Carthage/Checkouts
54 |
55 | Carthage/Build
56 |
57 | # fastlane
58 | #
59 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
60 | # screenshots whenever they are needed.
61 | # For more information about the recommended setup visit:
62 | # https://docs.fastlane.tools/best-practices/source-control/#source-control
63 |
64 | fastlane/report.xml
65 | fastlane/Preview.html
66 | fastlane/screenshots
67 | fastlane/test_output
68 |
--------------------------------------------------------------------------------
/TGImage/TGImage/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 |
27 |
28 |
--------------------------------------------------------------------------------
/TGImage/TGImage/Base.lproj/Main.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 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/TGImage/TGImage/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // TGImage
4 | //
5 | // Created by targetcloud on 2017/6/30.
6 | // Copyright © 2017年 targetcloud. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
18 | // Override point for customization after application launch.
19 | return true
20 | }
21 |
22 | func applicationWillResignActive(_ application: UIApplication) {
23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
24 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
25 | }
26 |
27 | func applicationDidEnterBackground(_ application: UIApplication) {
28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
30 | }
31 |
32 | func applicationWillEnterForeground(_ application: UIApplication) {
33 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
34 | }
35 |
36 | func applicationDidBecomeActive(_ application: UIApplication) {
37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
38 | }
39 |
40 | func applicationWillTerminate(_ application: UIApplication) {
41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
42 | }
43 |
44 |
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # TGImage
4 |
5 | 一款以最时髦的方式来使用UIImage的swift插件
6 |
7 | 
8 | 
9 | 
10 | 
11 | 
12 |
13 |
14 | ## Features
15 | - [x] 支持链式编程
16 | - [x] 支持with 和size两种开启模式
17 | - [x] 支持+= 、+两种图片相加操作
18 | - [x] 用例丰富、快速使用
19 |
20 | ## Usage
21 |
22 | #### size开启模式
23 |
24 | ```swift
25 | UIImage.size() 或.resizable()
26 | .color .border .corner
27 | .image
28 | .position
29 | ```
30 |
31 | > ##### 其中size开启的是固定大小模式、resizable开启的是可变大小模式
32 | > ##### 其中color支持传入渐变色,如 gradient: [.lightGray, .white], locations: [0, 1], from: CGPoint(x: 0, y: 1), to: CGPoint(x: 0, y: 0)
33 | > ##### 其中border可以设置color、width、radius、alignment
34 | > ##### 其中corner可以分别设置4个角或统一设置四个角为同一个值
35 | > ##### 其中image用于生成 UIImage
36 | > ##### 其中position用于后面+或+=时用
37 |
38 | ##### 注意:按上面大的顺序链式编程,在size和image之间的color 、border 、corner没有顺序要求
39 |
40 |
41 | size开启方式
42 |
43 | ```swift
44 | UIImage.size(width: CGFloat, height: CGFloat)
45 | UIImage.size(_ size: CGSize)
46 | UIImage.resizable()
47 | ```
48 |
49 | #### with CGContext开启模式
50 |
51 | 支持UIImage.with类方式开启或image.with类实例开启
52 |
53 | 类方式是返回单图,实例方式开始是在实例图的基础再加上with图,实际是两图相加模式
54 |
55 |
56 | with开启方式
57 |
58 | ```swift
59 | UIImage.with(width: CGFloat, height: CGFloat, block: ContextBlock)//单
60 | image.with(size: CGSize, opaque: Bool = false, scale: CGFloat = 0, block: ContextBlock)//相加
61 | image.with(_ block: ContextBlock)//单
62 | ```
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 | #### 应用场景及Demo(以下图都是用代码绘制的哦)
72 |
73 | 在cell的某角上放一个某角载剪的渐变图
74 |
75 | 在某图上再画图
76 |
77 | 多个图相加放入容器图中
78 |
79 | …
80 |
81 | #### 1
82 |
83 | ```swift
84 | UIImageView(image: ({ () -> UIImage in
85 | var container = UIImage.size(width: 180, height: 20)
86 | .color(.clear)
87 | .image
88 | for i in 0..<7{
89 | let doti = UIImage.size(width: 20, height: 20)
90 | .color(gradient: [UIColor.randomColor(), UIColor.randomColor()], locations: [0, 1], from: CGPoint(x: 0, y: 0), to: CGPoint(x: 1, y: 1))
91 | .corner(radius: 10)
92 | .image
93 | .position(CGPoint(x: i * 20 + (i + 1) * 3, y: 0))
94 | container = container + doti
95 | }
96 | return container
97 | })())
98 | ```
99 |
100 |
101 |
102 |
103 | #### 2
104 |
105 | ```swift
106 | UIImageView(image: ({ () -> UIImage in
107 | var container = UIImage.size(width: 30, height: 120)
108 | .color(.clear)
109 | .image
110 | for i in 0..<4{
111 | let doti = UIImage.size(width: CGFloat(30 - i * 4), height: CGFloat(30 - i * 4))
112 | .color(gradient: [UIColor.randomColor(), UIColor.randomColor()], locations: [0, 1], from: CGPoint(x: 0, y: 0), to: CGPoint(x: 1, y: 1))
113 | .corner(radius: CGFloat(30 - i * 4) * 0.5)
114 | .image
115 | .position(CGPoint(x: i * 2, y: 30 * i + (i + 1) * 3))
116 | container += doti
117 | }
118 | return container
119 | })())
120 | ```
121 |
122 |
123 |
124 |
125 | #### 3
126 |
127 | ```swift
128 | UIImageView(image:
129 | UIImage.size(width: 27, height: 27)
130 | .corner(radius: 13.5)
131 | .color(.white)
132 | .border(color: .lightGray)
133 | .border(width: 2)
134 | .image
135 | .with({ context in
136 | context.setLineCap(.round)
137 | UIColor.lightGray.setStroke()
138 | context.setLineWidth(2)
139 | context.move(to: CGPoint(x: 6, y: 12))
140 | context.addLine(to: CGPoint(x: 9, y: 18))
141 | context.move(to: CGPoint(x: 9, y: 18))
142 | context.addLine(to: CGPoint(x: 21, y: 9))
143 | context.strokePath()
144 | })
145 | )
146 | ```
147 |
148 |
149 |
150 |
151 | #### 4
152 |
153 | ```swift
154 | UIImageView(image: UIImage.size(width: 100, height: 100)
155 | .color(gradient: [.green, .blue], locations: [0, 1], from: CGPoint(x: 0, y: 1), to: CGPoint(x: 0, y: 0))
156 | .border(gradient: [.red, .yellow], locations: [0, 1], from: CGPoint(x: 0, y: 0), to: CGPoint(x: 1, y: 0))
157 | .border(width: 5)
158 | .border(alignment: .outside)
159 | .corner(topLeft: 20)
160 | .corner(topRight: 50)
161 | .corner(bottomLeft: 50)
162 | .corner(bottomRight: 20)
163 | .image)
164 | ```
165 |
166 |
167 |
168 |
169 | #### 5
170 |
171 | ```swift
172 | UIImageView(image: ({ () -> UIImage in
173 | let background = UIImage.size(width: 120, height: 120)
174 | .color(gradient: [.black, .white], locations: [0, 1], from: CGPoint(x: 0, y: 0), to: CGPoint(x: 0, y: 1))
175 | .corner(radius: 13.5)
176 | .image
177 | let circle = UIImage.size(width: 106, height: 106)
178 | .color(.white)
179 | .corner(radius: 50)
180 | .image
181 | let center = UIImage.size(width: 8, height: 8)
182 | .color(.black)
183 | .corner(radius: 3)
184 | .image
185 | let clock = background + circle + center
186 | return clock.with { context in
187 | context.setLineCap(.round)
188 | UIColor.black.setStroke()
189 | context.setLineWidth(2)
190 | context.move(to: CGPoint(x: clock.size.width / 2, y: clock.size.height / 2))
191 | context.addLine(to: CGPoint(x: clock.size.width / 2 - 5, y: 15))
192 | context.move(to: CGPoint(x: clock.size.width / 2, y: clock.size.height / 2))
193 | context.addLine(to: CGPoint(x: clock.size.width - 25, y: clock.size.height / 2 - 3))
194 | context.strokePath()
195 | UIColor.red.setStroke()
196 | context.setLineWidth(1)
197 | context.move(to: CGPoint(x: clock.size.width / 2 + 8, y: clock.size.height / 2 - 7))
198 | context.addLine(to: CGPoint(x: 26, y: clock.size.height / 2 + 35))
199 | context.strokePath()
200 | UIColor.red.setFill()
201 | let rect = CGRect(x: clock.size.width / 2 - 1, y: clock.size.height / 2 - 1, width: 3, height: 3)
202 | context.fillEllipse(in: rect)
203 | }
204 | })())
205 | ```
206 |
207 |
208 |
209 |
210 | #### 6
211 |
212 | ```swift
213 | UIImageView(image:
214 | ({ () -> UIImage in
215 | let circle = UIImage.size(width: 8, height: 8)
216 | .color(.white)
217 | .corner(radius: 4)
218 | .image
219 | .position(CGPoint(x: 5, y: 5))
220 | return UIImage.size(width: UIScreen.main.bounds.width*0.5, height: 44)
221 | .color(gradient: [.red, .white], locations: [0, 1], from: CGPoint(x: 0, y: 0), to: CGPoint(x: 1, y: 1))
222 | .corner(bottomRight: 20)
223 | .image + circle
224 | })())
225 | ```
226 |
227 |
228 |
229 |
230 | ```swift
231 | UIImageView(image:
232 | ({ () -> UIImage in
233 | let circle = UIImage.size(width: 8, height: 8)
234 | .color(.white)
235 | .corner(radius: 4)
236 | .image
237 | .position(CGPoint(x: UIScreen.main.bounds.width * 0.5 - 15, y: 5))
238 | return UIImage.size(width: UIScreen.main.bounds.width*0.5, height: 44)
239 | .color(gradient: [.white, .lightGray], locations: [0, 1], from: CGPoint(x: 0, y: 0), to: CGPoint(x: 1, y: 1))
240 | .corner(bottomLeft: 20)
241 | .image + circle
242 | })())
243 | ```
244 |
245 |
246 |
247 |
248 | ```swift
249 | UIImageView(image:
250 | ({ () -> UIImage in
251 | return UIImage.size(width: UIScreen.main.bounds.width*0.5, height: 44)
252 | .color(gradient: [.white, UIColor.randomColor().withAlphaComponent(0.5)], locations: [0, 1], from: CGPoint(x: 0, y: 0), to: CGPoint(x: 1, y: 1))
253 | .corner(topLeft: 20)
254 | .image
255 | })())
256 | ```
257 |
258 |
259 |
260 |
261 | ```swift
262 | UIImageView(image:
263 | ({ () -> UIImage in
264 | return UIImage.size(width: UIScreen.main.bounds.width*0.5, height: 22)
265 | .color(gradient: [UIColor.randomColor(), .white], locations: [0, 1], from: CGPoint(x: 0, y: 0), to: CGPoint(x: 1, y: 1))
266 | .corner(topLeft: 10)
267 | .image
268 | })())
269 |
270 | UIImageView(image:
271 | ({ () -> UIImage in
272 | return UIImage.size(width: UIScreen.main.bounds.width*0.5, height: 22)
273 | .color(gradient: [.lightGray, .white], locations: [0, 1], from: CGPoint(x: 0, y: 0), to: CGPoint(x: 1, y: 1))
274 | .corner(bottomLeft: 10)
275 | .image
276 | })())
277 | ```
278 |
279 |
280 |
281 |
282 | #### 更多使用配置组合效果请download本项目或fork本项目查看
283 |
284 | ## Installation
285 | - 下载并拖动TGImage.swift到你的工程中
286 |
287 | - Cocoapods
288 | ```
289 | pod 'TGImage'
290 | ```
291 |
292 | ## Reference
293 | - http://blog.csdn.net/callzjy
294 | - https://github.com/targetcloud/baisibudejie
295 | - https://github.com/targetcloud/TGRefreshSwift
296 | - https://github.com/targetcloud/TGLabel
297 | - https://github.com/targetcloud/TGPhotoPicker
298 |
299 |
300 | 如果你觉得赞,请Star
301 |
302 |
--------------------------------------------------------------------------------
/TGImage/TGImage.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 6AC5392C1F0645D2007D1C37 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AC5392B1F0645D2007D1C37 /* AppDelegate.swift */; };
11 | 6AC5392E1F0645D2007D1C37 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AC5392D1F0645D2007D1C37 /* ViewController.swift */; };
12 | 6AC539311F0645D2007D1C37 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6AC5392F1F0645D2007D1C37 /* Main.storyboard */; };
13 | 6AC539331F0645D2007D1C37 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6AC539321F0645D2007D1C37 /* Assets.xcassets */; };
14 | 6AC539361F0645D2007D1C37 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6AC539341F0645D2007D1C37 /* LaunchScreen.storyboard */; };
15 | 6AC539411F0759CB007D1C37 /* TGImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AC539401F0759CB007D1C37 /* TGImage.swift */; };
16 | /* End PBXBuildFile section */
17 |
18 | /* Begin PBXFileReference section */
19 | 6AC539281F0645D2007D1C37 /* TGImage.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TGImage.app; sourceTree = BUILT_PRODUCTS_DIR; };
20 | 6AC5392B1F0645D2007D1C37 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
21 | 6AC5392D1F0645D2007D1C37 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
22 | 6AC539301F0645D2007D1C37 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
23 | 6AC539321F0645D2007D1C37 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
24 | 6AC539351F0645D2007D1C37 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
25 | 6AC539371F0645D2007D1C37 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
26 | 6AC539401F0759CB007D1C37 /* TGImage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TGImage.swift; sourceTree = ""; };
27 | /* End PBXFileReference section */
28 |
29 | /* Begin PBXFrameworksBuildPhase section */
30 | 6AC539251F0645D2007D1C37 /* Frameworks */ = {
31 | isa = PBXFrameworksBuildPhase;
32 | buildActionMask = 2147483647;
33 | files = (
34 | );
35 | runOnlyForDeploymentPostprocessing = 0;
36 | };
37 | /* End PBXFrameworksBuildPhase section */
38 |
39 | /* Begin PBXGroup section */
40 | 6AC5391F1F0645D2007D1C37 = {
41 | isa = PBXGroup;
42 | children = (
43 | 6AC5392A1F0645D2007D1C37 /* TGImage */,
44 | 6AC539291F0645D2007D1C37 /* Products */,
45 | );
46 | sourceTree = "";
47 | };
48 | 6AC539291F0645D2007D1C37 /* Products */ = {
49 | isa = PBXGroup;
50 | children = (
51 | 6AC539281F0645D2007D1C37 /* TGImage.app */,
52 | );
53 | name = Products;
54 | sourceTree = "";
55 | };
56 | 6AC5392A1F0645D2007D1C37 /* TGImage */ = {
57 | isa = PBXGroup;
58 | children = (
59 | 6AC5393F1F0759CB007D1C37 /* TGImage */,
60 | 6AC5392B1F0645D2007D1C37 /* AppDelegate.swift */,
61 | 6AC5392D1F0645D2007D1C37 /* ViewController.swift */,
62 | 6AC5392F1F0645D2007D1C37 /* Main.storyboard */,
63 | 6AC539321F0645D2007D1C37 /* Assets.xcassets */,
64 | 6AC539341F0645D2007D1C37 /* LaunchScreen.storyboard */,
65 | 6AC539371F0645D2007D1C37 /* Info.plist */,
66 | );
67 | path = TGImage;
68 | sourceTree = "";
69 | };
70 | 6AC5393F1F0759CB007D1C37 /* TGImage */ = {
71 | isa = PBXGroup;
72 | children = (
73 | 6AC539401F0759CB007D1C37 /* TGImage.swift */,
74 | );
75 | path = TGImage;
76 | sourceTree = "";
77 | };
78 | /* End PBXGroup section */
79 |
80 | /* Begin PBXNativeTarget section */
81 | 6AC539271F0645D2007D1C37 /* TGImage */ = {
82 | isa = PBXNativeTarget;
83 | buildConfigurationList = 6AC5393A1F0645D2007D1C37 /* Build configuration list for PBXNativeTarget "TGImage" */;
84 | buildPhases = (
85 | 6AC539241F0645D2007D1C37 /* Sources */,
86 | 6AC539251F0645D2007D1C37 /* Frameworks */,
87 | 6AC539261F0645D2007D1C37 /* Resources */,
88 | );
89 | buildRules = (
90 | );
91 | dependencies = (
92 | );
93 | name = TGImage;
94 | productName = TGImage;
95 | productReference = 6AC539281F0645D2007D1C37 /* TGImage.app */;
96 | productType = "com.apple.product-type.application";
97 | };
98 | /* End PBXNativeTarget section */
99 |
100 | /* Begin PBXProject section */
101 | 6AC539201F0645D2007D1C37 /* Project object */ = {
102 | isa = PBXProject;
103 | attributes = {
104 | LastSwiftUpdateCheck = 0830;
105 | LastUpgradeCheck = 0830;
106 | ORGANIZATIONNAME = targetcloud;
107 | TargetAttributes = {
108 | 6AC539271F0645D2007D1C37 = {
109 | CreatedOnToolsVersion = 8.3.3;
110 | ProvisioningStyle = Automatic;
111 | };
112 | };
113 | };
114 | buildConfigurationList = 6AC539231F0645D2007D1C37 /* Build configuration list for PBXProject "TGImage" */;
115 | compatibilityVersion = "Xcode 3.2";
116 | developmentRegion = English;
117 | hasScannedForEncodings = 0;
118 | knownRegions = (
119 | en,
120 | Base,
121 | );
122 | mainGroup = 6AC5391F1F0645D2007D1C37;
123 | productRefGroup = 6AC539291F0645D2007D1C37 /* Products */;
124 | projectDirPath = "";
125 | projectRoot = "";
126 | targets = (
127 | 6AC539271F0645D2007D1C37 /* TGImage */,
128 | );
129 | };
130 | /* End PBXProject section */
131 |
132 | /* Begin PBXResourcesBuildPhase section */
133 | 6AC539261F0645D2007D1C37 /* Resources */ = {
134 | isa = PBXResourcesBuildPhase;
135 | buildActionMask = 2147483647;
136 | files = (
137 | 6AC539361F0645D2007D1C37 /* LaunchScreen.storyboard in Resources */,
138 | 6AC539331F0645D2007D1C37 /* Assets.xcassets in Resources */,
139 | 6AC539311F0645D2007D1C37 /* Main.storyboard in Resources */,
140 | );
141 | runOnlyForDeploymentPostprocessing = 0;
142 | };
143 | /* End PBXResourcesBuildPhase section */
144 |
145 | /* Begin PBXSourcesBuildPhase section */
146 | 6AC539241F0645D2007D1C37 /* Sources */ = {
147 | isa = PBXSourcesBuildPhase;
148 | buildActionMask = 2147483647;
149 | files = (
150 | 6AC539411F0759CB007D1C37 /* TGImage.swift in Sources */,
151 | 6AC5392E1F0645D2007D1C37 /* ViewController.swift in Sources */,
152 | 6AC5392C1F0645D2007D1C37 /* AppDelegate.swift in Sources */,
153 | );
154 | runOnlyForDeploymentPostprocessing = 0;
155 | };
156 | /* End PBXSourcesBuildPhase section */
157 |
158 | /* Begin PBXVariantGroup section */
159 | 6AC5392F1F0645D2007D1C37 /* Main.storyboard */ = {
160 | isa = PBXVariantGroup;
161 | children = (
162 | 6AC539301F0645D2007D1C37 /* Base */,
163 | );
164 | name = Main.storyboard;
165 | sourceTree = "";
166 | };
167 | 6AC539341F0645D2007D1C37 /* LaunchScreen.storyboard */ = {
168 | isa = PBXVariantGroup;
169 | children = (
170 | 6AC539351F0645D2007D1C37 /* Base */,
171 | );
172 | name = LaunchScreen.storyboard;
173 | sourceTree = "";
174 | };
175 | /* End PBXVariantGroup section */
176 |
177 | /* Begin XCBuildConfiguration section */
178 | 6AC539381F0645D2007D1C37 /* Debug */ = {
179 | isa = XCBuildConfiguration;
180 | buildSettings = {
181 | ALWAYS_SEARCH_USER_PATHS = NO;
182 | CLANG_ANALYZER_NONNULL = YES;
183 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
184 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
185 | CLANG_CXX_LIBRARY = "libc++";
186 | CLANG_ENABLE_MODULES = YES;
187 | CLANG_ENABLE_OBJC_ARC = YES;
188 | CLANG_WARN_BOOL_CONVERSION = YES;
189 | CLANG_WARN_CONSTANT_CONVERSION = YES;
190 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
191 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
192 | CLANG_WARN_EMPTY_BODY = YES;
193 | CLANG_WARN_ENUM_CONVERSION = YES;
194 | CLANG_WARN_INFINITE_RECURSION = YES;
195 | CLANG_WARN_INT_CONVERSION = YES;
196 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
197 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
198 | CLANG_WARN_UNREACHABLE_CODE = YES;
199 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
200 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
201 | COPY_PHASE_STRIP = NO;
202 | DEBUG_INFORMATION_FORMAT = dwarf;
203 | ENABLE_STRICT_OBJC_MSGSEND = YES;
204 | ENABLE_TESTABILITY = YES;
205 | GCC_C_LANGUAGE_STANDARD = gnu99;
206 | GCC_DYNAMIC_NO_PIC = NO;
207 | GCC_NO_COMMON_BLOCKS = YES;
208 | GCC_OPTIMIZATION_LEVEL = 0;
209 | GCC_PREPROCESSOR_DEFINITIONS = (
210 | "DEBUG=1",
211 | "$(inherited)",
212 | );
213 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
214 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
215 | GCC_WARN_UNDECLARED_SELECTOR = YES;
216 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
217 | GCC_WARN_UNUSED_FUNCTION = YES;
218 | GCC_WARN_UNUSED_VARIABLE = YES;
219 | IPHONEOS_DEPLOYMENT_TARGET = 10.3;
220 | MTL_ENABLE_DEBUG_INFO = YES;
221 | ONLY_ACTIVE_ARCH = YES;
222 | SDKROOT = iphoneos;
223 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
224 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
225 | };
226 | name = Debug;
227 | };
228 | 6AC539391F0645D2007D1C37 /* Release */ = {
229 | isa = XCBuildConfiguration;
230 | buildSettings = {
231 | ALWAYS_SEARCH_USER_PATHS = NO;
232 | CLANG_ANALYZER_NONNULL = YES;
233 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
234 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
235 | CLANG_CXX_LIBRARY = "libc++";
236 | CLANG_ENABLE_MODULES = YES;
237 | CLANG_ENABLE_OBJC_ARC = YES;
238 | CLANG_WARN_BOOL_CONVERSION = YES;
239 | CLANG_WARN_CONSTANT_CONVERSION = YES;
240 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
241 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
242 | CLANG_WARN_EMPTY_BODY = YES;
243 | CLANG_WARN_ENUM_CONVERSION = YES;
244 | CLANG_WARN_INFINITE_RECURSION = YES;
245 | CLANG_WARN_INT_CONVERSION = YES;
246 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
247 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
248 | CLANG_WARN_UNREACHABLE_CODE = YES;
249 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
250 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
251 | COPY_PHASE_STRIP = NO;
252 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
253 | ENABLE_NS_ASSERTIONS = NO;
254 | ENABLE_STRICT_OBJC_MSGSEND = YES;
255 | GCC_C_LANGUAGE_STANDARD = gnu99;
256 | GCC_NO_COMMON_BLOCKS = YES;
257 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
258 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
259 | GCC_WARN_UNDECLARED_SELECTOR = YES;
260 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
261 | GCC_WARN_UNUSED_FUNCTION = YES;
262 | GCC_WARN_UNUSED_VARIABLE = YES;
263 | IPHONEOS_DEPLOYMENT_TARGET = 10.3;
264 | MTL_ENABLE_DEBUG_INFO = NO;
265 | SDKROOT = iphoneos;
266 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
267 | VALIDATE_PRODUCT = YES;
268 | };
269 | name = Release;
270 | };
271 | 6AC5393B1F0645D2007D1C37 /* Debug */ = {
272 | isa = XCBuildConfiguration;
273 | buildSettings = {
274 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
275 | INFOPLIST_FILE = TGImage/Info.plist;
276 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
277 | PRODUCT_BUNDLE_IDENTIFIER = net.targetcloud.TGImage;
278 | PRODUCT_NAME = "$(TARGET_NAME)";
279 | SWIFT_VERSION = 3.0;
280 | };
281 | name = Debug;
282 | };
283 | 6AC5393C1F0645D2007D1C37 /* Release */ = {
284 | isa = XCBuildConfiguration;
285 | buildSettings = {
286 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
287 | INFOPLIST_FILE = TGImage/Info.plist;
288 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
289 | PRODUCT_BUNDLE_IDENTIFIER = net.targetcloud.TGImage;
290 | PRODUCT_NAME = "$(TARGET_NAME)";
291 | SWIFT_VERSION = 3.0;
292 | };
293 | name = Release;
294 | };
295 | /* End XCBuildConfiguration section */
296 |
297 | /* Begin XCConfigurationList section */
298 | 6AC539231F0645D2007D1C37 /* Build configuration list for PBXProject "TGImage" */ = {
299 | isa = XCConfigurationList;
300 | buildConfigurations = (
301 | 6AC539381F0645D2007D1C37 /* Debug */,
302 | 6AC539391F0645D2007D1C37 /* Release */,
303 | );
304 | defaultConfigurationIsVisible = 0;
305 | defaultConfigurationName = Release;
306 | };
307 | 6AC5393A1F0645D2007D1C37 /* Build configuration list for PBXNativeTarget "TGImage" */ = {
308 | isa = XCConfigurationList;
309 | buildConfigurations = (
310 | 6AC5393B1F0645D2007D1C37 /* Debug */,
311 | 6AC5393C1F0645D2007D1C37 /* Release */,
312 | );
313 | defaultConfigurationIsVisible = 0;
314 | };
315 | /* End XCConfigurationList section */
316 | };
317 | rootObject = 6AC539201F0645D2007D1C37 /* Project object */;
318 | }
319 |
--------------------------------------------------------------------------------
/TGImage/TGImage/TGImage/TGImage.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TGImage.swift
3 | // TGImage
4 | //
5 | // Created by targetcloud on 2017/6/30.
6 | // Copyright © 2017年 targetcloud. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | public enum BorderAlignment {
12 | case inside
13 | case center
14 | case outside
15 | }
16 |
17 | public extension UIImage {
18 | public typealias ContextBlock = (CGContext) -> Void
19 |
20 | public class func with(width: CGFloat, height: CGFloat, block: ContextBlock) -> UIImage {
21 | return self.with(size: CGSize(width: width, height: height), block: block)
22 | }
23 |
24 | public class func with(size: CGSize, opaque: Bool = false, scale: CGFloat = 0, block: ContextBlock) -> UIImage {
25 | UIGraphicsBeginImageContextWithOptions(size, opaque, scale)
26 | let context = UIGraphicsGetCurrentContext()!
27 | block(context)
28 | let image = UIGraphicsGetImageFromCurrentImageContext()
29 | UIGraphicsEndImageContext()
30 | return image ?? UIImage()
31 | }
32 |
33 | public func with(size: CGSize, opaque: Bool = false, scale: CGFloat = 0, block: ContextBlock) -> UIImage {
34 | return self + UIImage.with(size:size,opaque:opaque,scale:scale,block:block)
35 | }
36 |
37 | public func with(_ block: ContextBlock) -> UIImage {
38 | return UIImage.with(size: self.size, opaque: false, scale: self.scale) { context in
39 | let rect = CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height)
40 | self.draw(in: rect)
41 | block(context)
42 | }
43 | }
44 |
45 | public func with(color: UIColor) -> UIImage {
46 | return UIImage.with(size: self.size) { context in
47 | context.translateBy(x: 0, y: self.size.height)
48 | context.scaleBy(x: 1, y: -1)
49 | context.setBlendMode(.normal)
50 | let rect = CGRect(origin: .zero, size: self.size)
51 | context.clip(to: rect, mask: self.cgImage!)
52 | color.setFill()
53 | context.fill(rect)
54 | }
55 | }
56 |
57 | public class func size(width: CGFloat, height: CGFloat) -> TGImagePresenter {
58 | return self.size(CGSize(width: width, height: height))
59 | }
60 |
61 | public class func size(_ size: CGSize) -> TGImagePresenter {
62 | let drawer = TGImagePresenter()
63 | drawer.size = .fixed(size)
64 | return drawer
65 | }
66 |
67 | public class func resizable() -> TGImagePresenter {
68 | let drawer = TGImagePresenter()
69 | drawer.size = .resizable
70 | return drawer
71 | }
72 |
73 | private struct AssociatedKeys {
74 | static var TGImagePositionKey = "TGImagePositionKey"
75 | }
76 |
77 | public var position: CGPoint{
78 | get {
79 | return objc_getAssociatedObject(self, &AssociatedKeys.TGImagePositionKey) as? CGPoint ?? CGPoint.zero
80 | }
81 | set(newValue) {
82 | if self.position != newValue{
83 | self.willChangeValue(forKey: "position")
84 | objc_setAssociatedObject(self, &AssociatedKeys.TGImagePositionKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
85 | self.didChangeValue(forKey: "position")
86 | }
87 | }
88 | }
89 |
90 | public func position(_ point:CGPoint) -> UIImage{
91 | self.position = point
92 | return self
93 | }
94 | }
95 |
96 | extension UIColor{
97 | public class func randomColor() -> UIColor{
98 | return UIColor(red: CGFloat(arc4random_uniform(255))/255.0, green: CGFloat(arc4random_uniform(255))/255.0, blue: CGFloat(arc4random_uniform(255))/255.0, alpha: 1.0)
99 | }
100 | }
101 |
102 | public func + (leftImage: UIImage, rigthImage: UIImage) -> UIImage {
103 | return leftImage.with { context in
104 |
105 | let leftRect = CGRect(x: 0, y: 0, width: leftImage.size.width, height: leftImage.size.height)
106 | var rightRect = CGRect(x: 0, y: 0, width: rigthImage.size.width, height: rigthImage.size.height)
107 |
108 | if rigthImage.position.x != 0 || rigthImage.position.y != 0{
109 | rightRect.origin.x = rigthImage.position.x
110 | rightRect.origin.y = rigthImage.position.y
111 | }else if leftRect.contains(rightRect) {
112 | rightRect.origin.x = (leftRect.size.width - rightRect.size.width) / 2
113 | rightRect.origin.y = (leftRect.size.height - rightRect.size.height) / 2
114 | } else {
115 | rightRect.size = leftRect.size
116 | }
117 |
118 | //print("\(String(describing: rigthImage.position.x )) \(String(describing: rigthImage.position.y ))")
119 | rigthImage.draw(in: rightRect)
120 | }
121 | }
122 |
123 | public func += (leftImage:inout UIImage, rigthImage: UIImage) {
124 | leftImage = leftImage + rigthImage
125 | }
126 |
127 | open class TGImagePresenter{
128 | public enum Size {
129 | case fixed(CGSize)
130 | case resizable
131 | }
132 |
133 | fileprivate static let defaultGradientLocations: [CGFloat] = [0, 1]
134 | fileprivate static let defaultGradientFrom: CGPoint = .zero
135 | fileprivate static let defaultGradientTo: CGPoint = CGPoint(x: 0, y: 1)
136 |
137 | fileprivate var colors: [UIColor] = [.clear]
138 | fileprivate var colorLocations: [CGFloat] = defaultGradientLocations
139 | fileprivate var colorStartPoint: CGPoint = defaultGradientFrom
140 | fileprivate var colorEndPoint: CGPoint = defaultGradientTo
141 | fileprivate var borderColors: [UIColor] = [.black]
142 | fileprivate var borderColorLocations: [CGFloat] = defaultGradientLocations
143 | fileprivate var borderColorStartPoint: CGPoint = defaultGradientFrom
144 | fileprivate var borderColorEndPoint: CGPoint = defaultGradientTo
145 | fileprivate var borderWidth: CGFloat = 0
146 | fileprivate var borderAlignment: BorderAlignment = .inside
147 | fileprivate var cornerRadiusTopLeft: CGFloat = 0
148 | fileprivate var cornerRadiusTopRight: CGFloat = 0
149 | fileprivate var cornerRadiusBottomLeft: CGFloat = 0
150 | fileprivate var cornerRadiusBottomRight: CGFloat = 0
151 |
152 | fileprivate var size: Size = .resizable
153 |
154 | private static var cachedImages = [String: UIImage]()
155 |
156 | private var cacheKey: String {
157 | var attributes = [String: String]()
158 | attributes["colors"] = String(self.colors.description.hashValue)
159 | attributes["colorLocations"] = String(self.colorLocations.description.hashValue)
160 | attributes["colorStartPoint"] = String(String(describing: self.colorStartPoint).hashValue)
161 | attributes["colorEndPoint"] = String(String(describing: self.colorEndPoint).hashValue)
162 | attributes["borderColors"] = String(self.borderColors.description.hashValue)
163 | attributes["borderColorLocations"] = String(self.borderColorLocations.description.hashValue)
164 | attributes["borderColorStartPoint"] = String(String(describing: self.borderColorStartPoint).hashValue)
165 | attributes["borderColorEndPoint"] = String(String(describing: self.borderColorEndPoint).hashValue)
166 | attributes["borderWidth"] = String(self.borderWidth.hashValue)
167 | attributes["borderAlignment"] = String(self.borderAlignment.hashValue)
168 | attributes["cornerRadiusTopLeft"] = String(self.cornerRadiusTopLeft.hashValue)
169 | attributes["cornerRadiusTopRight"] = String(self.cornerRadiusTopRight.hashValue)
170 | attributes["cornerRadiusBottomLeft"] = String(self.cornerRadiusBottomLeft.hashValue)
171 | attributes["cornerRadiusBottomRight"] = String(self.cornerRadiusBottomRight.hashValue)
172 |
173 | switch self.size {
174 | case .fixed(let size):
175 | attributes["size"] = "Fixed(\(size.width), \(size.height))"
176 | case .resizable:
177 | attributes["size"] = "Resizable"
178 | }
179 |
180 | var serializedAttributes = [String]()
181 | for key in attributes.keys.sorted() {
182 | if let value = attributes[key] {
183 | serializedAttributes.append("\(key):\(value)")
184 | }
185 | }
186 |
187 | let cacheKey = serializedAttributes.joined(separator: "|")
188 | return cacheKey
189 | }
190 |
191 | open func color(_ color: UIColor) -> Self {
192 | self.colors = [color]
193 | return self
194 | }
195 |
196 | open func color(gradient: [UIColor],locations: [CGFloat] = defaultGradientLocations,from startPoint: CGPoint = defaultGradientFrom,to endPoint: CGPoint = defaultGradientTo) -> Self {
197 | self.colors = gradient
198 | self.colorLocations = locations
199 | self.colorStartPoint = startPoint
200 | self.colorEndPoint = endPoint
201 | return self
202 | }
203 |
204 | open func border(color: UIColor) -> Self {
205 | self.borderColors = [color]
206 | return self
207 | }
208 |
209 | open func border(gradient: [UIColor],locations: [CGFloat] = defaultGradientLocations,from startPoint: CGPoint = defaultGradientFrom,to endPoint: CGPoint = defaultGradientTo
210 | ) -> Self {
211 | self.borderColors = gradient
212 | self.borderColorLocations = locations
213 | self.borderColorStartPoint = startPoint
214 | self.borderColorEndPoint = endPoint
215 | return self
216 | }
217 |
218 | open func border(width: CGFloat) -> Self {
219 | self.borderWidth = width
220 | return self
221 | }
222 |
223 | open func border(alignment: BorderAlignment) -> Self {
224 | self.borderAlignment = alignment
225 | return self
226 | }
227 |
228 | open func corner(radius: CGFloat) -> Self {
229 | return self.corner(topLeft: radius, topRight: radius, bottomLeft: radius, bottomRight: radius)
230 | }
231 |
232 | open func corner(topLeft: CGFloat) -> Self {
233 | self.cornerRadiusTopLeft = topLeft
234 | return self
235 | }
236 |
237 | open func corner(topRight: CGFloat) -> Self {
238 | self.cornerRadiusTopRight = topRight
239 | return self
240 | }
241 |
242 | open func corner(bottomLeft: CGFloat) -> Self {
243 | self.cornerRadiusBottomLeft = bottomLeft
244 | return self
245 | }
246 |
247 | open func corner(bottomRight: CGFloat) -> Self {
248 | self.cornerRadiusBottomRight = bottomRight
249 | return self
250 | }
251 |
252 | open func corner(topLeft: CGFloat, topRight: CGFloat, bottomLeft: CGFloat, bottomRight: CGFloat) -> Self {
253 | return self.corner(topLeft: topLeft).corner(topRight: topRight).corner(bottomLeft: bottomLeft).corner(bottomRight: bottomRight)
254 | }
255 |
256 | open var image: UIImage {
257 | switch self.size {
258 | case .fixed(let size):
259 | return self.imageWithSize(size)
260 | case .resizable:
261 | self.borderAlignment = .inside
262 | let cornerRadius = max(self.cornerRadiusTopLeft, self.cornerRadiusTopRight,self.cornerRadiusBottomLeft, self.cornerRadiusBottomRight)
263 | let capSize = ceil(max(cornerRadius, self.borderWidth))
264 | let imageSize = capSize * 2 + 1
265 | let image = self.imageWithSize(CGSize(width: imageSize, height: imageSize))
266 | let capInsets = UIEdgeInsets(top: capSize, left: capSize, bottom: capSize, right: capSize)
267 | return image.resizableImage(withCapInsets: capInsets)
268 | }
269 | }
270 |
271 | private func imageWithSize(_ size: CGSize, useCache: Bool = true) -> UIImage {
272 | if let cachedImage = type(of: self).cachedImages[self.cacheKey], useCache {
273 | return cachedImage
274 | }
275 |
276 | var imageSize = CGSize(width: size.width, height: size.height)
277 | var rect = CGRect()
278 | rect.size = imageSize
279 |
280 | switch self.borderAlignment {
281 | case .inside:
282 | rect.origin.x += self.borderWidth / 2
283 | rect.origin.y += self.borderWidth / 2
284 | rect.size.width -= self.borderWidth
285 | rect.size.height -= self.borderWidth
286 | case .center:
287 | rect.origin.x += self.borderWidth / 2
288 | rect.origin.y += self.borderWidth / 2
289 | imageSize.width += self.borderWidth
290 | imageSize.height += self.borderWidth
291 | case .outside:
292 | rect.origin.x += self.borderWidth / 2
293 | rect.origin.y += self.borderWidth / 2
294 | rect.size.width += self.borderWidth
295 | rect.size.height += self.borderWidth
296 | imageSize.width += self.borderWidth * 2
297 | imageSize.height += self.borderWidth * 2
298 | }
299 |
300 | let cornerRadius = max(self.cornerRadiusTopLeft, self.cornerRadiusTopRight,self.cornerRadiusBottomLeft, self.cornerRadiusBottomRight)
301 |
302 | let image = UIImage.with(size: imageSize) { context in
303 | let path: UIBezierPath
304 | if self.cornerRadiusTopLeft == self.cornerRadiusTopRight && self.cornerRadiusTopLeft == self.cornerRadiusBottomLeft && self.cornerRadiusTopLeft == self.cornerRadiusBottomRight && self.cornerRadiusTopLeft > 0 {
305 | path = UIBezierPath(roundedRect: rect, cornerRadius: self.cornerRadiusTopLeft)
306 | } else if cornerRadius > 0 {
307 | let startAngle = CGFloat.pi
308 | let topLeftCenter = CGPoint(x: self.cornerRadiusTopLeft + self.borderWidth / 2,y: self.cornerRadiusTopLeft + self.borderWidth / 2)
309 | let topRightCenter = CGPoint(x: imageSize.width - self.cornerRadiusTopRight - self.borderWidth / 2,y: self.cornerRadiusTopRight + self.borderWidth / 2)
310 | let bottomRightCenter = CGPoint(x: imageSize.width - self.cornerRadiusBottomRight - self.borderWidth / 2,y: imageSize.height - self.cornerRadiusBottomRight - self.borderWidth / 2)
311 | let bottomLeftCenter = CGPoint(x: self.cornerRadiusBottomLeft + self.borderWidth / 2,y: imageSize.height - self.cornerRadiusBottomLeft - self.borderWidth / 2)
312 | let mutablePath = UIBezierPath()
313 | self.cornerRadiusTopLeft > 0 ? mutablePath.addArc(withCenter: topLeftCenter,radius: self.cornerRadiusTopLeft,startAngle: startAngle,endAngle: 1.5 * startAngle,clockwise: true) : mutablePath.move(to: topLeftCenter)
314 | self.cornerRadiusTopRight > 0 ? mutablePath.addArc(withCenter: topRightCenter,radius: self.cornerRadiusTopRight,startAngle: 1.5 * startAngle,endAngle: 2 * startAngle,clockwise: true) : mutablePath.addLine(to: topRightCenter)
315 | self.cornerRadiusBottomRight > 0 ? mutablePath.addArc(withCenter: bottomRightCenter,radius: self.cornerRadiusBottomRight,startAngle: 2 * startAngle,endAngle: 2.5 * startAngle,clockwise: true) : mutablePath.addLine(to: bottomRightCenter)
316 | self.cornerRadiusBottomLeft > 0 ? mutablePath.addArc(withCenter: bottomLeftCenter,radius: self.cornerRadiusBottomLeft,startAngle: 2.5 * startAngle,endAngle: 3 * startAngle,clockwise: true) : mutablePath.addLine(to: bottomLeftCenter)
317 | self.cornerRadiusTopLeft > 0 ? mutablePath.addLine(to: CGPoint(x: self.borderWidth / 2, y: topLeftCenter.y)) : mutablePath.addLine(to: topLeftCenter)
318 | path = mutablePath
319 | }
320 | else {
321 | path = UIBezierPath(rect: rect)
322 | }
323 |
324 | context.saveGState()
325 | if self.colors.count <= 1 {
326 | self.colors.first?.setFill()
327 | path.fill()
328 | } else {
329 | let colorSpace = CGColorSpaceCreateDeviceRGB()
330 | let colors = self.colors.map { $0.cgColor } as CFArray
331 | if let gradient = CGGradient(colorsSpace: colorSpace, colors: colors, locations: self.colorLocations) {
332 | let startPoint = CGPoint(x: self.colorStartPoint.x * imageSize.width,y: self.colorStartPoint.y * imageSize.height)
333 | let endPoint = CGPoint(x: self.colorEndPoint.x * imageSize.width,y: self.colorEndPoint.y * imageSize.height)
334 | context.addPath(path.cgPath)
335 | context.clip()
336 | context.drawLinearGradient(gradient, start: startPoint, end: endPoint, options: [])
337 | }
338 | }
339 | context.restoreGState()
340 |
341 | context.saveGState()
342 | if self.borderColors.count <= 1 {
343 | self.borderColors.first?.setStroke()
344 | path.lineWidth = self.borderWidth
345 | path.stroke()
346 | } else {
347 | let colorSpace = CGColorSpaceCreateDeviceRGB()
348 | let colors = self.borderColors.map { $0.cgColor } as CFArray
349 | if let gradient = CGGradient(colorsSpace: colorSpace, colors: colors, locations: self.borderColorLocations) {
350 | let startPoint = CGPoint(x: self.borderColorStartPoint.x * imageSize.width,y: self.borderColorStartPoint.y * imageSize.height)
351 | let endPoint = CGPoint(x: self.borderColorEndPoint.x * imageSize.width,y: self.borderColorEndPoint.y * imageSize.height)
352 | context.addPath(path.cgPath)
353 | context.setLineWidth(self.borderWidth)
354 | context.replacePathWithStrokedPath()
355 | context.clip()
356 | context.drawLinearGradient(gradient, start: startPoint, end: endPoint, options: [])
357 | }
358 | }
359 | context.restoreGState()
360 | }
361 |
362 | if useCache {
363 | type(of: self).cachedImages[self.cacheKey] = image
364 | }
365 | return image
366 | }
367 | }
368 |
--------------------------------------------------------------------------------
/TGImage/TGImage/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // TGImage
4 | //
5 | // Created by targetcloud on 2017/6/30.
6 | // Copyright © 2017年 targetcloud. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ViewController: UIViewController {
12 |
13 | override func viewDidLoad() {
14 | super.viewDidLoad()
15 |
16 | let iv : UIImageView = UIImageView(image: UIImage.size(width: UIScreen.main.bounds.width, height: 20)
17 | .color(gradient: [.lightGray, .white], locations: [0, 1], from: CGPoint(x: 0, y: 1), to: CGPoint(x: 0, y: 0))
18 | .border(color: .gray)
19 | .border(width: 1)
20 | .corner(radius: 5)
21 | .image)
22 | iv.frame.origin = CGPoint(x: 0, y: 20)
23 | self.view.addSubview(iv)
24 |
25 | let iv2 : UIImageView = UIImageView(image: UIImage.size(width: UIScreen.main.bounds.width, height: 34)
26 | .color(.orange)
27 | .corner(bottomLeft: 10)
28 | .corner(bottomRight: 10)
29 | .image)
30 | iv2.frame.origin = CGPoint(x: 0, y: iv.frame.maxY+5)
31 | self.view.addSubview(iv2)
32 |
33 | let iv3 : UIImageView = UIImageView(image: UIImage.size(width: 100, height: 70)
34 | .color(gradient: [UIColor.randomColor(), .white], locations: [0, 1], from: CGPoint(x: 0, y: 0), to: CGPoint(x: 1, y: 0))
35 | .border(color: .darkGray)
36 | .border(width: 5)
37 | .border(alignment: .outside)
38 | .corner(topLeft: 1)
39 | .corner(bottomLeft: 20)
40 | .corner(topRight: 20)
41 | .corner(bottomRight: 30)
42 | .image)
43 | iv3.frame.origin = CGPoint(x: 0, y: iv2.frame.maxY+5)
44 | self.view.addSubview(iv3)
45 |
46 | let iv4 = UIImageView(image: UIImage.size(width: 100, height: 100)
47 | .color(gradient: [.green, .blue], locations: [0, 1], from: CGPoint(x: 0, y: 1), to: CGPoint(x: 0, y: 0))
48 | .border(gradient: [.red, .yellow], locations: [0, 1], from: CGPoint(x: 0, y: 0), to: CGPoint(x: 1, y: 0))
49 | .border(width: 5)
50 | .border(alignment: .outside)
51 | .corner(topLeft: 20)
52 | .corner(topRight: 50)
53 | .corner(bottomLeft: 50)
54 | .corner(bottomRight: 20)
55 | .image)
56 | iv4.frame.origin = CGPoint(x: 0, y: iv3.frame.maxY+5)
57 | self.view.addSubview(iv4)
58 |
59 | //let iv5 = UIImageView(image: UIImage(named: "2")!.with( { context in//左上
60 | let iv5 = UIImageView(image: UIImage(named: "2")!.with(size: CGSize(width: 50, height: 20)) { context in//(50 20)在2图的中央
61 | UIColor.red.setFill()
62 | context.fillEllipse(in: CGRect(x: 0, y: 0, width: 20, height: 20))//(20 20)根据情况确定在左上还是在中央的(50 20)限制区域
63 | })
64 | //)//左上
65 | iv5.frame.origin = CGPoint(x: 0, y: iv4.frame.maxY)
66 | self.view.addSubview(iv5)
67 |
68 | let iv6 = UIImageView(image: ({ () -> UIImage in
69 | let background = UIImage.size(width: 120, height: 120)
70 | .color(gradient: [.black, .white], locations: [0, 1], from: CGPoint(x: 0, y: 0), to: CGPoint(x: 0, y: 1))
71 | .corner(radius: 13.5)
72 | .image
73 | let circle = UIImage.size(width: 106, height: 106)
74 | .color(.white)
75 | .corner(radius: 50)
76 | .image
77 | let center = UIImage.size(width: 8, height: 8)
78 | .color(.black)
79 | .corner(radius: 3)
80 | .image
81 | let clock = background + circle + center
82 | return clock.with { context in
83 | context.setLineCap(.round)
84 | UIColor.black.setStroke()
85 | context.setLineWidth(2)
86 | context.move(to: CGPoint(x: clock.size.width / 2, y: clock.size.height / 2))
87 | context.addLine(to: CGPoint(x: clock.size.width / 2 - 5, y: 15))
88 | context.move(to: CGPoint(x: clock.size.width / 2, y: clock.size.height / 2))
89 | context.addLine(to: CGPoint(x: clock.size.width - 25, y: clock.size.height / 2 - 3))
90 | context.strokePath()
91 | UIColor.red.setStroke()
92 | context.setLineWidth(1)
93 | context.move(to: CGPoint(x: clock.size.width / 2 + 8, y: clock.size.height / 2 - 7))
94 | context.addLine(to: CGPoint(x: 26, y: clock.size.height / 2 + 35))
95 | context.strokePath()
96 | UIColor.red.setFill()
97 | let rect = CGRect(x: clock.size.width / 2 - 1, y: clock.size.height / 2 - 1, width: 3, height: 3)
98 | context.fillEllipse(in: rect)
99 | }
100 | })())
101 | iv6.frame.origin.y = iv5.frame.maxY
102 | self.view.addSubview(iv6)
103 |
104 | self.view.addSubview(({ () -> UIButton in
105 | let button = UIButton(frame: CGRect(x: 0, y: 0, width: 100, height: 44))
106 | button.setBackgroundImage(
107 | UIImage.resizable()
108 | .color(.lightGray)
109 | .border(gradient: [.red, .white], locations: [0, 1], from: CGPoint(x: 0, y: 0), to: CGPoint(x: 1, y: 1))
110 | .border(width: 2)
111 | .border(alignment: .outside)
112 | .corner(radius: 8)
113 | .image,
114 | for: .normal
115 | )
116 | button.frame.origin.y = iv6.frame.maxY+5
117 | return button
118 | })())
119 |
120 | let topLeftCorner = UIImageView(image:
121 | ({ () -> UIImage in
122 | return UIImage.size(width: UIScreen.main.bounds.width*0.5, height: 22)
123 | .color(gradient: [UIColor.randomColor(), .white], locations: [0, 1], from: CGPoint(x: 0, y: 0), to: CGPoint(x: 1, y: 1))
124 | .corner(topLeft: 10)
125 | .image
126 | })())
127 | topLeftCorner.frame.origin.y = self.view.bounds.height - 44
128 | self.view.addSubview(topLeftCorner)
129 |
130 | let bottomLeftCorner = UIImageView(image:
131 | ({ () -> UIImage in
132 | return UIImage.size(width: UIScreen.main.bounds.width*0.5, height: 22)
133 | .color(gradient: [.lightGray, .white], locations: [0, 1], from: CGPoint(x: 0, y: 0), to: CGPoint(x: 1, y: 1))
134 | .corner(bottomLeft: 10)
135 | .image
136 | })())
137 | bottomLeftCorner.frame.origin.y = self.view.bounds.height - 22
138 | self.view.addSubview(bottomLeftCorner)
139 |
140 | let iv7 = UIImageView(image: ({ () -> UIImage in
141 | let img = UIImage.size(width: 180, height: 50)
142 | .color(.black)
143 | .corner(radius: 5)
144 | .image
145 | let background = UIImage.size(width: 160, height: 40)
146 | .color(.white)
147 | .corner(radius: 5)
148 | .image
149 | let circle = UIImage.size(width: 8, height: 8)
150 | .color(.white)
151 | .corner(radius: 4)
152 | .image
153 | //.with(color: .red)
154 | .position(CGPoint(x: 2, y: 10))
155 |
156 | return img + background + circle
157 | })())
158 | iv7.frame.origin = CGPoint(x: UIScreen.main.bounds.width*0.5, y: iv2.frame.maxY+5)
159 | self.view.addSubview(iv7)
160 |
161 | let iv8 = UIImageView(image:
162 | ({ () -> UIImage in
163 | let circle = UIImage.size(width: 8, height: 8)
164 | .color(.white)
165 | .corner(radius: 4)
166 | .image
167 | .position(CGPoint(x: 5, y: 5))
168 | return UIImage.size(width: UIScreen.main.bounds.width*0.5, height: 44)
169 | .color(gradient: [.red, .white], locations: [0, 1], from: CGPoint(x: 0, y: 0), to: CGPoint(x: 1, y: 1))
170 | .corner(bottomRight: 20)
171 | .image + circle
172 | })())
173 | iv8.frame.origin.x = iv7.frame.origin.x
174 | iv8.frame.origin.y = iv7.frame.maxY + 5
175 | self.view.addSubview(iv8)
176 |
177 | let iv9 = UIImageView(image:
178 | ({ () -> UIImage in
179 | let circle = UIImage.size(width: 8, height: 8)
180 | .color(.white)
181 | .corner(radius: 4)
182 | .image
183 | .position(CGPoint(x: UIScreen.main.bounds.width * 0.5 - 15, y: 5))
184 | return UIImage.size(width: UIScreen.main.bounds.width*0.5, height: 44)
185 | .color(gradient: [.white, .lightGray], locations: [0, 1], from: CGPoint(x: 0, y: 0), to: CGPoint(x: 1, y: 1))
186 | .corner(bottomLeft: 20)
187 | .image + circle
188 | })())
189 | iv9.frame.origin.x = iv8.frame.origin.x
190 | iv9.frame.origin.y = iv8.frame.maxY + 5
191 | self.view.addSubview(iv9)
192 |
193 | let iv10 = UIImageView(image: ({ () -> UIImage in
194 | let img = UIImage.size(width: 180, height: 70)
195 | .color(.red)
196 | .corner(radius: 15)
197 | .image
198 | let circle = UIImage.size(width: 18, height: 18)
199 | .color(.white)
200 | .corner(radius: 9)
201 | .image
202 | .position(CGPoint(x: 10, y: 10))
203 | return img + circle
204 | })())
205 | iv10.frame.origin = CGPoint(x: UIScreen.main.bounds.width*0.5, y: iv9.frame.maxY+5)
206 | self.view.addSubview(iv10)
207 |
208 | //方yes
209 | let iv11 = UIImageView(image:
210 | UIImage.size(width: 27, height: 27)
211 | .border(color: .black)
212 | .border(width: 2)
213 | .corner(radius: 2)
214 | .color(.lightGray)
215 | .image
216 | .with({ context in
217 | context.setLineCap(.round)
218 | UIColor.white.setStroke()
219 | context.setLineWidth(2)
220 | context.move(to: CGPoint(x: 6, y: 12))
221 | context.addLine(to: CGPoint(x: 9, y: 18))
222 | context.move(to: CGPoint(x: 9, y: 18))
223 | context.addLine(to: CGPoint(x: 21, y: 9))
224 | context.strokePath()
225 | })
226 | )
227 | iv11.frame.origin = CGPoint(x: UIScreen.main.bounds.width*0.5, y: iv10.frame.maxY+5)
228 | self.view.addSubview(iv11)
229 |
230 | //yes
231 | let iv112 = UIImageView(image:
232 | UIImage.size(width: 27, height: 27)
233 | .corner(radius: 13.5)
234 | .color(.green)
235 | .image
236 | .with({ context in
237 | context.setLineCap(.round)
238 | UIColor.white.setStroke()
239 | context.setLineWidth(2)
240 | context.move(to: CGPoint(x: 6, y: 12))
241 | context.addLine(to: CGPoint(x: 9, y: 18))
242 | context.move(to: CGPoint(x: 9, y: 18))
243 | context.addLine(to: CGPoint(x: 21, y: 9))
244 | context.strokePath()
245 | })
246 | )
247 | iv112.frame.origin = CGPoint(x: UIScreen.main.bounds.width*0.5 + 30, y: iv10.frame.maxY+5)
248 | self.view.addSubview(iv112)
249 |
250 | //yes
251 | let iv113 = UIImageView(image:
252 | UIImage.size(width: 27, height: 27)
253 | .corner(radius: 13.5)
254 | .color(.lightGray)
255 | .image
256 | .with({ context in
257 | context.setLineCap(.round)
258 | UIColor.white.setStroke()
259 | context.setLineWidth(2)
260 | context.move(to: CGPoint(x: 6, y: 12))
261 | context.addLine(to: CGPoint(x: 9, y: 18))
262 | context.move(to: CGPoint(x: 9, y: 18))
263 | context.addLine(to: CGPoint(x: 21, y: 9))
264 | context.strokePath()
265 | })
266 | )
267 | iv113.frame.origin = CGPoint(x: UIScreen.main.bounds.width*0.5 + 60, y: iv10.frame.maxY+5)
268 | self.view.addSubview(iv113)
269 |
270 | //yes
271 | let iv114 = UIImageView(image:
272 | UIImage.size(width: 27, height: 27)
273 | .corner(radius: 13.5)
274 | .color(.white)
275 | .border(color: .lightGray)
276 | .border(width: 2)
277 | .image
278 | .with({ context in
279 | context.setLineCap(.round)
280 | UIColor.lightGray.setStroke()
281 | context.setLineWidth(2)
282 | context.move(to: CGPoint(x: 6, y: 12))
283 | context.addLine(to: CGPoint(x: 9, y: 18))
284 | context.move(to: CGPoint(x: 9, y: 18))
285 | context.addLine(to: CGPoint(x: 21, y: 9))
286 | context.strokePath()
287 | })
288 | )
289 | iv114.frame.origin = CGPoint(x: UIScreen.main.bounds.width*0.5 + 90, y: iv10.frame.maxY+5)
290 | self.view.addSubview(iv114)
291 |
292 | //数字
293 | let iv115 = UIImageView(image:({ () -> UIImage in
294 | let M = 30 * 0.111111
295 | return UIImage.size(width: 30, height: 30)
296 | .corner(radius: 15)
297 | .color(.green)
298 | .image
299 | .with({ context in
300 | let str:NSString = "5"
301 | str.draw(in: CGRect(x: M * (5>9 ? 2 : 2.5), y: M, width: 20, height: 20), withAttributes:[NSFontAttributeName:UIFont.boldSystemFont(ofSize: 20),NSForegroundColorAttributeName: UIColor.white])
302 | })
303 | })())
304 | iv115.frame.origin = CGPoint(x: UIScreen.main.bounds.width*0.5 + 120, y: iv10.frame.maxY+5)
305 | self.view.addSubview(iv115)
306 |
307 | //返回
308 | let iv116 = UIImageView(image:
309 | UIImage.size(width: 30, height: 30)
310 | .corner(radius: 15)
311 | .color(.clear)
312 | // .border(color: .white)
313 | // .border(width: 1)
314 | .image
315 | .with({ context in
316 | context.setLineCap(.round)
317 | UIColor.white.setStroke()
318 | context.setLineWidth(2)
319 | context.move(to: CGPoint(x: 17, y: 7))
320 | context.addLine(to: CGPoint(x: 10, y: 15))
321 | context.move(to: CGPoint(x: 10, y: 15))
322 | context.addLine(to: CGPoint(x: 17, y: 23))
323 | context.strokePath()
324 | })
325 | )
326 | iv116.frame.origin = CGPoint(x: UIScreen.main.bounds.width*0.5 + 155, y: iv10.frame.maxY+5)
327 | self.view.addSubview(iv116)
328 |
329 | //删除
330 | let iv117 = UIImageView(image:
331 | UIImage.size(width: 20, height: 20)
332 | .color(.clear)
333 | .image
334 | .with({ context in
335 | context.setLineCap(.round)
336 | UIColor.white.setStroke()
337 | context.setLineWidth(1.5)
338 | context.move(to: CGPoint(x: 8, y: 4))
339 | context.addLine(to: CGPoint(x: 12, y: 4))
340 | context.move(to: CGPoint(x: 4, y: 5))
341 | context.addLine(to: CGPoint(x: 16, y: 5))
342 | context.move(to: CGPoint(x: 5, y: 16))
343 | context.addLine(to: CGPoint(x: 15, y: 16))
344 |
345 | context.move(to: CGPoint(x: 5, y: 6))
346 | context.addLine(to: CGPoint(x: 5, y: 16))
347 |
348 | context.move(to: CGPoint(x: 8, y: 7))
349 | context.addLine(to: CGPoint(x: 8, y: 13))
350 |
351 | context.move(to: CGPoint(x: 12, y: 7))
352 | context.addLine(to: CGPoint(x: 12, y: 13))
353 |
354 | context.move(to: CGPoint(x: 15, y: 6))
355 | context.addLine(to: CGPoint(x: 15, y: 16))
356 | context.strokePath()
357 | })
358 | )
359 | iv117.frame.origin = CGPoint(x: UIScreen.main.bounds.width*0.5 - 22 , y: iv10.frame.maxY+5)
360 | self.view.addSubview(iv117)
361 |
362 | //对
363 | let iv12 = UIImageView(image: ({ () -> UIImage in
364 | let M = 48 * 0.111111
365 | return UIImage.size(width: 48, height: 48)
366 | .color(gradient: [UIColor.green, UIColor.green.withAlphaComponent(0.1)], locations: [0, 1], from: CGPoint(x: 0, y: 0), to: CGPoint(x: 1, y: 1))
367 | .corner(radius: 24)
368 | .image
369 | .with({ context in
370 | context.setLineCap(.round)
371 | UIColor.white.setStroke()
372 | context.setLineWidth(2)
373 | context.move(to: CGPoint(x: M * 2, y: M * 4))
374 | context.addLine(to: CGPoint(x: M * 3, y: M * 6))
375 | context.move(to: CGPoint(x: M * 3, y: M * 6))
376 | context.addLine(to: CGPoint(x: M * 7, y: M * 3))
377 | context.strokePath()
378 | })
379 | })())
380 | iv12.frame.origin = CGPoint(x: UIScreen.main.bounds.width*0.5, y: iv11.frame.maxY+5)
381 | self.view.addSubview(iv12)
382 |
383 | //错
384 | let iv122 = UIImageView(image: ({ () -> UIImage in
385 | let M = 48 * 0.111111
386 | return UIImage.size(width: 48, height: 48)
387 | .color(gradient: [UIColor.red, UIColor.red.withAlphaComponent(0.1)], locations: [0, 1], from: CGPoint(x: 0, y: 0), to: CGPoint(x: 1, y: 1))
388 | .corner(radius: 24)
389 | .image
390 | .with({ context in
391 | context.setLineCap(.round)
392 | UIColor.white.setStroke()
393 | context.setLineWidth(2)
394 | context.move(to: CGPoint(x: M * 3, y: M * 3))
395 | context.addLine(to: CGPoint(x: M * 6, y: M * 6))
396 | context.move(to: CGPoint(x: M * 6, y: M * 3))
397 | context.addLine(to: CGPoint(x: M * 3, y: M * 6))
398 | context.strokePath()
399 | })
400 | })())
401 | iv122.frame.origin = CGPoint(x: UIScreen.main.bounds.width*0.5 + 50, y: iv11.frame.maxY+5)
402 | self.view.addSubview(iv122)
403 |
404 | //照相
405 | let iv123 = UIImageView(image:
406 | UIImage.size(width: 48, height: 48).border(width: 3).border(color: .white).color(UIColor(white: 0.9, alpha: 1)).corner(radius: 24).image +
407 | UIImage.size(width: 40, height: 40).color(UIColor(white: 0.95, alpha: 1) ).corner(radius: 20).image
408 | )
409 | iv123.frame.origin = CGPoint(x: UIScreen.main.bounds.width*0.5 + 100, y: iv11.frame.maxY+5)
410 | self.view.addSubview(iv123)
411 |
412 | let iv13 = UIImageView(image: ({ () -> UIImage in
413 | var container = UIImage.size(width: 180, height: 20)
414 | .color(.clear)
415 | .image
416 | for i in 0..<7{
417 | let doti = UIImage.size(width: 20, height: 20)
418 | .color(gradient: [UIColor.randomColor(), UIColor.randomColor()], locations: [0, 1], from: CGPoint(x: 0, y: 0), to: CGPoint(x: 1, y: 1))
419 | .corner(radius: 10)
420 | .image
421 | .position(CGPoint(x: i * 20 + (i + 1) * 3, y: 0))
422 | container = container + doti
423 | }
424 | return container
425 | })())
426 | iv13.frame.origin = CGPoint(x: UIScreen.main.bounds.width*0.5, y: iv12.frame.maxY+5)
427 | self.view.addSubview(iv13)
428 |
429 | let iv14 = UIImageView(image: ({ () -> UIImage in
430 | var container = UIImage.size(width: 30, height: 120)
431 | .color(.clear)
432 | .image
433 | for i in 0..<4{
434 | let doti = UIImage.size(width: CGFloat(30 - i * 4), height: CGFloat(30 - i * 4))
435 | .color(gradient: [UIColor.randomColor(), UIColor.randomColor()], locations: [0, 1], from: CGPoint(x: 0, y: 0), to: CGPoint(x: 1, y: 1))
436 | .corner(radius: CGFloat(30 - i * 4) * 0.5)
437 | .image
438 | .position(CGPoint(x: i * 2, y: 30 * i + (i + 1) * 3))
439 | container += doti
440 | }
441 | return container
442 | })())
443 | iv14.frame.origin = CGPoint(x: UIScreen.main.bounds.width*0.5, y: iv13.frame.maxY+5)
444 | self.view.addSubview(iv14)
445 |
446 | let iv99 = UIImageView(image:
447 | ({ () -> UIImage in
448 | return UIImage.size(width: UIScreen.main.bounds.width*0.5, height: 44)
449 | .color(gradient: [.white, UIColor.randomColor().withAlphaComponent(0.5)], locations: [0, 1], from: CGPoint(x: 0, y: 0), to: CGPoint(x: 1, y: 1))
450 | .corner(topLeft: 20)
451 | .image
452 | })())
453 | iv99.frame.origin.x = iv8.frame.origin.x
454 | iv99.frame.origin.y = self.view.bounds.height - 44
455 | self.view.addSubview(iv99)
456 | }
457 | }
458 |
459 |
--------------------------------------------------------------------------------