├── .gitignore
├── AFViewHelper.podspec
├── LICENSE
├── README.md
├── Screenshot.png
├── Sources
├── Info-iOS.plist
├── Info-tvOS.plist
├── InspectableButton.swift
├── InspectableView.swift
├── ViewAnimation.swift
├── ViewAutoLayout.swift
├── ViewControllerAutoLayout.swift
├── ViewEffects.swift
└── ViewHelper.h
├── ViewHelper.xcodeproj
├── project.pbxproj
└── xcshareddata
│ └── xcschemes
│ ├── ViewHelper iOS.xcscheme
│ └── ViewHelper tvOS.xcscheme
├── ViewHelperDemo iOS
├── AppDelegate.swift
├── Assets.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
├── Base.lproj
│ └── LaunchScreen.storyboard
├── Info.plist
├── Main.storyboard
└── ViewController.swift
└── ViewHelperDemo tvOS
├── AppDelegate.swift
├── Assets.xcassets
├── App Icon & Top Shelf Image.brandassets
│ ├── App Icon - Large.imagestack
│ │ ├── Back.imagestacklayer
│ │ │ ├── Content.imageset
│ │ │ │ └── Contents.json
│ │ │ └── Contents.json
│ │ ├── Contents.json
│ │ ├── Front.imagestacklayer
│ │ │ ├── Content.imageset
│ │ │ │ └── Contents.json
│ │ │ └── Contents.json
│ │ └── Middle.imagestacklayer
│ │ │ ├── Content.imageset
│ │ │ └── Contents.json
│ │ │ └── Contents.json
│ ├── App Icon - Small.imagestack
│ │ ├── Back.imagestacklayer
│ │ │ ├── Content.imageset
│ │ │ │ └── Contents.json
│ │ │ └── Contents.json
│ │ ├── Contents.json
│ │ ├── Front.imagestacklayer
│ │ │ ├── Content.imageset
│ │ │ │ └── Contents.json
│ │ │ └── Contents.json
│ │ └── Middle.imagestacklayer
│ │ │ ├── Content.imageset
│ │ │ └── Contents.json
│ │ │ └── Contents.json
│ ├── Contents.json
│ ├── Top Shelf Image Wide.imageset
│ │ └── Contents.json
│ └── Top Shelf Image.imageset
│ │ └── Contents.json
├── Contents.json
└── LaunchImage.launchimage
│ └── Contents.json
├── Base.lproj
└── Main.storyboard
├── Info.plist
├── TableViewController.swift
└── ViewController.swift
/.gitignore:
--------------------------------------------------------------------------------
1 | <<<<<<< HEAD
2 | .DS_Store
3 | *.swp
4 | *~.nib
5 |
6 | build/
7 |
8 | *.pbxuser
9 | *.perspective
10 | *.perspectivev3
11 |
12 | *.mode1v3
13 | *.mode2v3
14 |
15 | project.xcworkspace/
16 | xcuserdata
17 | =======
18 | # CocoaPods
19 | #
20 | # We recommend against adding the Pods directory to your .gitignore. However
21 | # you should judge for yourself, the pros and cons are mentioned at:
22 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control?
23 | #
24 | # Pods/
25 |
26 | >>>>>>> 920e0fd8315bafeb029a22d2ea768b71317fabcb
27 |
--------------------------------------------------------------------------------
/AFViewHelper.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = 'AFViewHelper'
3 | s.version = '4.2.4'
4 | s.license = 'MIT'
5 | s.summary = 'Autolayout and Animation UIVIew Extension for Swift 3.0.'
6 | s.homepage = 'https://github.com/melvitax/ViewHelper'
7 | s.author = { 'Melvin Rivera' => 'melvitax@gmail.com' }
8 | s.source = { :git => 'https://github.com/melvitax/ViewHelper.git', :tag => s.version.to_s }
9 | s.description = <<-DESC
10 | Autolayout and Animation UIVIew Extension for Swift 3.0. Includes InspectableView for setting basic view attributes.
11 | DESC
12 | s.social_media_url = 'https://twitter.com/melvitax'
13 | s.framework = 'QuartzCore'
14 |
15 | s.platforms = { :ios => '9.0', :tvos => '9.0' }
16 | s.ios.deployment_target = "9.0"
17 | s.tvos.deployment_target = "10.0"
18 |
19 | s.xcconfig = { 'SWIFT_VERSION' => '3.0' }
20 |
21 | s.source_files = "Sources/**/*.{h,swift}"
22 |
23 | end
24 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Melvin Rivera
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | 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, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ViewHelper
2 |
3 | [](http://cocoapods.org/pods/AFViewHelper)
4 | [](http://cocoapods.org/pods/AFViewHelper)
5 | [](http://cocoapods.org/pods/AFViewHelper)
6 | [](https://github.com/Carthage/Carthage)
7 |
8 |
9 | Autolayout and View Animation Helper for Swift 3.0.
10 | Mimimum requirements: Swift 3 and IOS 9
11 | Supported: IOS and Apple TV
12 |
13 |
14 | 
15 |
16 |
17 | ## Animations
18 |
19 | ```swift
20 | // Required
21 | view.animate(.Shake, curve: .EaseInOutBack)
22 | // With optionals
23 | view.animate(.Shake, curve: .EaseInOutBack, duration: 0.8, delay: 0, force: 1, damping: 0.7,velocity: 1, fromRotation: 0, fromScale: 1.5, fromX: 0, fromY: 0)
24 | ```
25 |
26 | ## Auto Layout
27 |
28 | ```swift
29 | let box = UIView(autoLayout:true)
30 | view.addSubview(box)
31 | box.backgroundColor = UIColor.redColor()
32 | box.width(100)
33 | box.height(100)
34 | box.center(to: view)
35 | view.layoutIfNeeded()
36 | ```
37 |
38 | ### Chainable functions
39 |
40 | 100 pixel view pinned to the center of another view
41 |
42 | ```swift
43 | view.width(100).height(100).center(to: view)
44 | ```
45 |
46 | ### Compression & Hugging
47 |
48 | ```swift
49 | view.horizontalCompressionPriority(UILayoutPriorityDefaultHigh)
50 | view.horizontalHuggingPriority(UILayoutPriorityDefaultLow)
51 | ```
52 |
53 | ### NSLayoutConstraints
54 |
55 | You can have access to the NSLayoutConstraints by using pin() or applyAttribute.
56 |
57 | ```swift
58 | // Pinning to an item
59 | let widthConstraint = view.pin(.Width, to: view, attribute: .Height, constant: 0, multiplier: 0.5, relation: .LessThanOrEqual)
60 | ```
61 |
62 | ```swift
63 | // Applying an attribute
64 | let widthConstraint = view.applyAttribute(.Width, constant: 100, multiplier: 0.5, relation: .Equal)
65 | ```
66 |
67 | ## UIView Extension
68 |
69 | ### Prepping for Auto Layout
70 |
71 | If a view is already in place with frames, prepForAutoLayout() will remove it from view, enable Auto Layout and place back in view.
72 |
73 | ```swift
74 | view.prepForAutoLayout()
75 | ```
76 |
77 | ### Prepping for Animation
78 |
79 | If a view uses auto layout but you need to animate it using frames, prepForAnimation() will remove from view, disable auto layout and place back in view.
80 |
81 | ```swift
82 | view.prepForAnimation()
83 | ```
84 |
85 | ### Instantiate
86 |
87 | Instantiates a new UIView with Auto Layout
88 |
89 | ```swift
90 | convenience init(autoLayout: Bool = true)
91 | ```
92 |
93 | ### Position
94 |
95 | #### Origin
96 |
97 | Returns the frame's origin
98 |
99 | ```swift
100 | origin() -> CGPoint
101 | ```
102 |
103 | Pins the frame's top and left sides using Auto Layout or frames
104 |
105 | ```swift
106 | origin(constant: CGPoint) -> UIView
107 | ```
108 | Pins left and top sides to another view using Auto Layout
109 |
110 | ```swift
111 | origin(to to:AnyObject, constant: CGPoint = CGPoint(x: 0, y: 0), multiplier:CGFloat = 1) -> UIView
112 | ```
113 | #### Left
114 |
115 | Returns the min x point
116 |
117 | ```swift
118 | left() -> CGFloat
119 | ```
120 |
121 | Pins the left side using Auto Layout or frames
122 |
123 | ```swift
124 | left(constant: CGFloat) -> UIView
125 | ```
126 |
127 | Pins left side to another view using Auto Layout
128 |
129 | ```swift
130 | left(to to:AnyObject, attribute: NSLayoutAttribute = .Left, constant: CGFloat = 0, multiplier:CGFloat = 1) -> UIView
131 | ```
132 |
133 | #### Leading
134 |
135 | Returns the leading side value
136 |
137 | ```swift
138 | leading() -> CGFloat
139 | ```
140 |
141 | Pins the leading side using Auto Layout or frames
142 |
143 | ```swift
144 | leading(constant: CGFloat) -> UIView
145 | ```
146 |
147 | Pins the leading side to another view using Auto Layout
148 |
149 | ```swift
150 | leading(to to:AnyObject, attribute: NSLayoutAttribute = .Leading, constant: CGFloat = 0, multiplier:CGFloat = 1) -> UIView
151 | ```
152 | #### Right
153 |
154 | Returns the max x point
155 |
156 | ```swift
157 | right() -> CGFloat
158 | ```
159 |
160 | Pins the right side using Auto Layout or frames
161 |
162 | ```swift
163 | right(constant: CGFloat) -> UIView
164 | ```
165 |
166 | Pins the right side to another view using Auto Layout
167 |
168 | ```swift
169 | right(to to:AnyObject, attribute: NSLayoutAttribute = .Right, constant: CGFloat = 0, multiplier:CGFloat = 1) -> UIView
170 | ```
171 | #### Trailing
172 |
173 | Returns the trailing side value
174 |
175 | ```swift
176 | trailing() -> CGFloat
177 | ```
178 |
179 | Pins the trailing side using Auto Layout or frames
180 |
181 | ```swift
182 | trailing(constant: CGFloat) -> UIView
183 | ```
184 |
185 | Pins the trailing side to another view using Auto Layout
186 |
187 | ```swift
188 | trailing(to to:AnyObject, attribute: NSLayoutAttribute = .Trailing, constant: CGFloat = 0, multiplier:CGFloat = 1) -> UIView
189 | ```
190 |
191 | #### Top
192 |
193 | Returns the top side value
194 |
195 | ```swift
196 | top() -> CGFloat
197 | ```
198 |
199 | Pins the top side using Auto Layout or frames
200 |
201 | ```swift
202 | top(constant: CGFloat) -> UIView
203 | ```
204 |
205 | Pins the trailing side to another view using Auto Layout
206 |
207 | ```swift
208 | top(to to:AnyObject, attribute: NSLayoutAttribute = .Top, constant: CGFloat = 0, multiplier:CGFloat = 1) -> UIView
209 | ```
210 |
211 | #### Bottom
212 |
213 | Returns the bottom side value
214 |
215 | ```swift
216 | bottom() -> CGFloat
217 | ```
218 |
219 | Pins the bottom side using Auto Layout or frames
220 |
221 | ```swift
222 | bottom(constant: CGFloat) -> UIView
223 | ```
224 |
225 | Pins the bottom side to another view using Auto Layout
226 |
227 | ```swift
228 | bottom(to to:AnyObject, attribute: NSLayoutAttribute = .Bottom, constant: CGFloat = 0, multiplier:CGFloat = 1) -> UIView
229 | ```
230 |
231 | #### Center
232 |
233 | Pins the center to it's superview using Auto Layout or frames
234 |
235 | ```swift
236 | center(constant: CGPoint = CGPoint(x: 0, y: 0)) -> UIView
237 | ```
238 |
239 | Pins the center point to another view using Auto Layout
240 |
241 | ```swift
242 | center(to to:AnyObject, constant:CGSize = CGSize(width: 0, height: 0), multiplier:CGFloat = 1) -> UIView
243 | ```
244 |
245 | #### Center X
246 |
247 | Returns the center X
248 |
249 | ```swift
250 | centerX() -> CGFloat
251 | ```
252 |
253 | Pins the center X using Auto Layout or frames
254 |
255 | ```swift
256 | centerX(constant: CGFloat = 0) -> UIView
257 | ```
258 |
259 | Pins the center X to another view using Auto Layout
260 |
261 | ```swift
262 | centerX(to to:AnyObject, attribute: NSLayoutAttribute = .CenterX, constant: CGFloat = 0, multiplier:CGFloat = 1) -> UIView
263 | ```
264 |
265 | #### Center Y
266 |
267 | Returns the center Y
268 |
269 | ```swift
270 | centerY() -> CGFloat
271 | ```
272 |
273 | Pins the center Y using Auto Layout or frames
274 |
275 | ```swift
276 | centerY(constant: CGFloat = 0) -> UIView
277 | ```
278 |
279 | Pins the center Y to another view using Auto Layout
280 |
281 | ```swift
282 | centerY(to to:AnyObject, attribute: NSLayoutAttribute = .CenterY, constant: CGFloat = 0, multiplier:CGFloat = 1) -> UIView
283 | ```
284 |
285 | ### Compression and Hugging Priority
286 |
287 | #### Compression Priority
288 |
289 | Returns the Compression Resistance Priority for Horizontal Axis using Auto Layout
290 |
291 | ```swift
292 | horizontalCompressionPriority() -> UILayoutPriority
293 | ```
294 |
295 | Sets the Compression Resistance Priority for Horizontal Axis using Auto Layout
296 |
297 | ```swift
298 | horizontalCompressionPriority(priority: UILayoutPriority) -> UIView
299 | ```
300 |
301 | Returns the Compression Resistance Priority for Vertical Axis using Auto Layout
302 |
303 | ```swift
304 | verticalCompressionPriority() -> UILayoutPriority
305 | ```
306 |
307 | Sets the Compression Resistance Priority for Vertical Axis using Auto Layout
308 |
309 | ```swift
310 | verticalCompressionPriority(priority: UILayoutPriority) -> UIView
311 | ```
312 |
313 | #### Hugging Priority
314 |
315 | Returns the Content Hugging Priority for Horizontal Axis using Auto Layout
316 |
317 | ```swift
318 | func horizontalHuggingPriority() -> UILayoutPriority
319 | ```
320 |
321 | Sets the Content Hugging Priority for Horizontal Axis using Auto Layout
322 |
323 | ```swift
324 | horizontalHuggingPriority(priority: UILayoutPriority) -> UIView
325 | ```
326 |
327 | Returns the Content Hugging Priority for Vertical Axis using Auto Layout
328 |
329 | ```swift
330 | verticalHuggingPriority() -> UILayoutPriority
331 | ```
332 |
333 | Sets the Content Hugging Priority for Vertical Axis using Auto Layout
334 |
335 | ```swift
336 | verticalHuggingPriority(priority: UILayoutPriority) -> UIView
337 | ```
338 |
339 | ### Size
340 |
341 | #### Size
342 |
343 | Returns the frame size
344 |
345 | ```swift
346 | size() -> CGSize
347 | ```
348 |
349 | Sets the frame size using Auto Layout or frames
350 |
351 | ```swift
352 | size(constant: CGSize) -> UIView
353 | ```
354 |
355 | Pins the size to another view using Auto Layout
356 |
357 | ```swift
358 | size(to to:AnyObject, constant: CGSize = CGSize(width: 0, height: 0), multiplier:CGFloat = 1) -> UIView
359 | ```
360 |
361 | #### Width
362 |
363 | Returns the frame width
364 |
365 | ```swift
366 | width() -> CGFloat
367 | ```
368 |
369 | Sets the frame width using Auto Layout or frames
370 |
371 | ```swift
372 | width(constant: CGFloat) -> UIView
373 | ```
374 |
375 | Pins the width to another view using Auto Layout
376 |
377 | ```swift
378 | width(to to:AnyObject, attribute: NSLayoutAttribute = .Width, constant: CGFloat = 0, multiplier:CGFloat = 1) -> UIView
379 | ```
380 |
381 | #### Height
382 |
383 | Returns the frame height
384 |
385 | ```swift
386 | height() -> CGFloat
387 | ```
388 |
389 | Sets the frame height using Auto Layout or frames
390 |
391 | ```swift
392 | eight(constant: CGFloat) -> UIView
393 | ```
394 |
395 | Pins the height to another view using Auto Layout
396 |
397 | ```swift
398 | height(to to:AnyObject, attribute: NSLayoutAttribute = .Height, constant: CGFloat = 0, multiplier:CGFloat = 1) -> UIView
399 | ```
400 |
401 | #### Minimum Size
402 |
403 | Returns the minimum size using Auto Layout
404 |
405 | ```swift
406 | minSize() -> CGSize?
407 | ```
408 |
409 | Sets the minimum size using Auto Layout
410 |
411 | ```swift
412 | minSize(constant:CGSize) -> UIView
413 | ```
414 |
415 | Pins the minimum size to another view using Auto Layout
416 |
417 | ```swift
418 | minSize(to to:AnyObject, constant:CGSize = CGSize(width: 0, height: 0), multiplier:CGFloat = 1)
419 | ```
420 |
421 | #### Minimum Width
422 |
423 | Returns the minimum width using Auto Layout
424 |
425 | ```swift
426 | minWidth() -> CGFloat?
427 | ```
428 |
429 | Sets the minimum width using Auto Layout
430 |
431 | ```swift
432 | minWidth(constant:CGFloat) -> UIView
433 | ```
434 |
435 | Pins the minimum width to another view using Auto Layout
436 |
437 | ```swift
438 | minWidth(to to:AnyObject, attribute: NSLayoutAttribute = .Width, constant:CGFloat = 0, multiplier:CGFloat = 1) -> UIView
439 | ```
440 |
441 | #### Minimum Height
442 |
443 | Returns the minimum height using Auto Layout
444 |
445 | ```swift
446 | minHeight() -> CGFloat?
447 | ```
448 |
449 | Sets the minimum height using Auto Layout
450 |
451 | ```swift
452 | minHeight(constant:CGFloat) -> UIView
453 | ```
454 |
455 | Pins the minimum height to another view using Auto Layout
456 |
457 | ```swift
458 | minHeight(to to:AnyObject, attribute: NSLayoutAttribute = .Height, constant:CGFloat = 0, multiplier:CGFloat = 1) -> UIView
459 | ```
460 |
461 | #### Maximum Size
462 |
463 | Returns the maximun size using Auto Layout
464 |
465 | ```swift
466 | maxSize() -> CGSize?
467 | ```
468 |
469 | Sets the maximun size using Auto Layout
470 |
471 | ```swift
472 | maxSize(constant:CGSize) -> UIView
473 | ```
474 |
475 | Pins the maximun size to another view using Auto Layout
476 |
477 | ```swift
478 | maxSize(to to:AnyObject, constant:CGSize = CGSize(width: 0, height: 0), multiplier:CGFloat = 1) -> UIView
479 | ```
480 |
481 | #### Maximum Width
482 |
483 | Returns the maximun width using Auto Layout
484 |
485 | ```swift
486 | maxWidth() -> CGFloat?
487 | ```
488 |
489 | Sets the maximun width using Auto Layout
490 |
491 | ```swift
492 | maxWidth(constant:CGFloat) -> UIView
493 | ```
494 |
495 | Pins the maximun width to another view using Auto Layout
496 |
497 | ```swift
498 | maxWidth(to to:AnyObject, attribute: NSLayoutAttribute = .Width, constant:CGFloat = 0, multiplier:CGFloat = 1) -> UIView
499 | ```
500 |
501 | #### Maximum Height
502 |
503 | Returns the maximun height using Auto Layout
504 |
505 | ```swift
506 | maxHeight() -> CGFloat?
507 | ```
508 |
509 | Sets the maximun height using Auto Layout
510 |
511 | ```swift
512 | maxHeight(constant:CGFloat) -> UIView
513 | ```
514 |
515 | Pins the maximun height to another view using Auto Layout
516 |
517 | ```swift
518 | maxHeight(to to:AnyObject, attribute: NSLayoutAttribute = .Height, constant:CGFloat = 0, multiplier:CGFloat = 1) -> UIView
519 | ```
520 |
521 | ### Smallest and Largest Size
522 |
523 | Returns the length of the smallest side
524 |
525 | ```swift
526 | smallestSideLength() -> CGFloat
527 | ```
528 |
529 | Returns the length of the largest side
530 |
531 | ```swift
532 | largestSideLength() -> CGFloat
533 | ```
534 |
535 | ### AutoLayout state
536 |
537 | Prepares the view for a frame based animation by removing the view, enabling translatesAutoresizingMaskIntoConstraints and re-adding the view to it's superview
538 |
539 | ```swift
540 | prepForAnimation()
541 | ```
542 |
543 | Prepares the view for Auto Layout by removing the view, disabling translatesAutoresizingMaskIntoConstraints and re-adding the view to it's superview
544 |
545 | ```swift
546 | prepForAutoLayout()
547 | ```
548 |
549 | ### Pin and Apply
550 |
551 | Pins an attribute to another view
552 |
553 | ```swift
554 | pin(pinAttribute:NSLayoutAttribute, to:AnyObject? = nil, attribute:NSLayoutAttribute, constant:CGFloat = 0, multiplier:CGFloat = 1, relation:NSLayoutRelation = .Equal) -> NSLayoutConstraint?
555 | ```
556 |
557 | Applies an attribute to the view
558 |
559 | ```swift
560 | applyAttribute(attribute:NSLayoutAttribute, constant:CGFloat = 0, multiplier: CGFloat = 1, relation:NSLayoutRelation = .Equal) -> NSLayoutConstraint
561 | ```
562 |
563 | ### Removing Constraints
564 |
565 | Removes all attached constraints recursevely
566 |
567 | ```swift
568 | removeAttachedConstraintsRecursevely() -> UIView
569 | ```
570 |
571 | Removes a constraint recursevely
572 |
573 | ```swift
574 | removeConstraintRecursevely(constraint:NSLayoutConstraint) -> UIView
575 | ```
576 |
577 | ### Direction
578 |
579 | Returns true if layout direction is left to right
580 |
581 | ```swift
582 | layoutDirectionIsLeftToRight() -> Bool
583 | ```
584 |
585 | ## UIView Effects Extension
586 |
587 | ### Border
588 |
589 | The layer border color
590 |
591 | ```swift
592 | var borderColor: UIColor
593 | ```
594 |
595 | The layer border width
596 |
597 | ```swift
598 | var borderWidth: CGFloat
599 | ```
600 |
601 | Sets layer border with a dash pattern
602 |
603 | ```swift
604 | borderWithDashPattern(lineDashPattern: [Int], borderWidth: CGFloat, borderColor: UIColor, cornerRadius: CGFloat?) -> UIView
605 | ```
606 |
607 | ### Rounded Corners
608 |
609 | The layer corner radius
610 |
611 | ```swift
612 | var cornerRadius: CGFloat
613 | ```
614 |
615 | Creates a circle by rounding the corners to half the size of the width, sets border color and width
616 |
617 | ```swift
618 | roundCornersToCircle(borderColor: UIColor?, borderWidth: CGFloat?) -> UIView
619 | ```
620 |
621 | Creates a circle by rounding the corners to hald the size of the width
622 |
623 | ```swift
624 | roundCorners(cornerRadius: CGFloat, borderColor: UIColor?, borderWidth: CGFloat?) -> UIView
625 | ```
626 |
627 | ### Shadow
628 |
629 | The shadow color of the layer
630 |
631 | ```swift
632 | var shadowColor: UIColor
633 | ```
634 |
635 | The shadow offset of the layer
636 |
637 | ```swift
638 | var shadowOffset:CGSize
639 | ```
640 |
641 | The shadow opacity of the layer
642 |
643 | ```swift
644 | var shadowOpacity:Float
645 | ```
646 |
647 | The shadow radius of the layer
648 |
649 | ```swift
650 | var shadowRadius:CGFloat
651 | ```
652 |
653 | Sets shadow of the layer including the color, offset, radius, opacity and mask.
654 |
655 | ```swift
656 | shadow(color: UIColor = UIColor.blackColor(), offset: CGSize = CGSize(width: 0, height: 0), radius: CGFloat = 6, opacity: Float = 1, isMasked: Bool = false) -> UIView
657 | ```
658 |
659 | ### Gradient
660 |
661 | Sets a gradient color layer
662 |
663 | ```swift
664 | setGradient(colors: [UIColor], isHorizontal:Bool = false) -> UIView
665 | ```
666 |
667 | Animates colors of a gradient layer
668 |
669 | ```swift
670 | animateGradientToColors(colors: [UIColor], duration: CFTimeInterval = 3) -> UIView
671 | ```
672 |
673 | Sets a gradient layer mask
674 |
675 | ```swift
676 | setGradientMask(alphas:[CGFloat], isHorizontal:Bool = false) -> UIView
677 | ```
678 |
679 |
680 | ## UIViewController Extension
681 |
682 | ### Direction
683 |
684 | Returns true if layout direction is left to right
685 |
686 | ```swift
687 | layoutDirectionIsLeftToRight() -> Bool
688 | ```
689 |
690 | Returns true if horizontal size class is compact
691 |
692 | ```swift
693 | horizontalSizeClassIsCompact() -> Bool
694 | ```
695 |
696 | Returns true if vertical size class is compact
697 |
698 | ```swift
699 | verticalSizeClassIsCompact() -> Bool
700 | ```
701 |
--------------------------------------------------------------------------------
/Screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/melvitax/ViewHelper/9c68f699d19effc0b9c005d2c7d389d0769cea2e/Screenshot.png
--------------------------------------------------------------------------------
/Sources/Info-iOS.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 | 1.0
19 | CFBundleVersion
20 | $(CURRENT_PROJECT_VERSION)
21 | NSPrincipalClass
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Sources/Info-tvOS.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 | 1.0
19 | CFBundleVersion
20 | $(CURRENT_PROJECT_VERSION)
21 | NSPrincipalClass
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Sources/InspectableButton.swift:
--------------------------------------------------------------------------------
1 | //
2 | // InspectableButton.swift
3 | // ViewHelper: Version 4.2.4
4 | // Created by Melvin Rivera on 6/28/16.
5 | // https://github.com/melvitax/ViewHelper
6 | //
7 |
8 | import Foundation
9 | import Foundation
10 | import UIKit
11 | import QuartzCore
12 |
13 | @IBDesignable open class InspectableButton : UIButton {
14 |
15 |
16 | // MARK: Border
17 |
18 | /**
19 | The layer border color
20 | */
21 | @IBInspectable override public var borderColor: UIColor {
22 | get {
23 | return layer.borderColor == nil ? UIColor.clear : UIColor(cgColor: layer.borderColor!)
24 | }
25 | set {
26 | layer.borderColor = newValue.cgColor
27 | }
28 | }
29 |
30 | /**
31 | The layer border width
32 | */
33 | @IBInspectable override public var borderWidth: CGFloat {
34 | get {
35 | return layer.borderWidth
36 | }
37 | set {
38 | layer.borderWidth = newValue
39 | }
40 | }
41 |
42 |
43 | // MARK: Corner Radius
44 |
45 | /**
46 | The layer corner radius
47 | */
48 | @IBInspectable override public var cornerRadius: CGFloat {
49 | get {
50 | return layer.cornerRadius
51 | }
52 | set {
53 | layer.cornerRadius = newValue
54 | layer.masksToBounds = newValue > 0
55 | setupView()
56 | }
57 | }
58 |
59 |
60 | // MARK: Shadow
61 |
62 | /**
63 | The shadow color of the layer
64 | */
65 | @IBInspectable override public var shadowColor: UIColor {
66 | get {
67 | return layer.shadowColor == nil ? UIColor.clear : UIColor(cgColor: layer.shadowColor!)
68 | }
69 | set {
70 | layer.shadowColor = newValue.cgColor
71 | }
72 | }
73 |
74 |
75 | /**
76 | The shadow offset of the layer
77 | */
78 | @IBInspectable override public var shadowOffset:CGSize {
79 | get {
80 | return layer.shadowOffset
81 | }
82 | set {
83 | layer.shadowOffset = newValue
84 | }
85 | }
86 |
87 | /**
88 | The shadow opacity of the layer
89 |
90 | - Returns: Float
91 | */
92 | @IBInspectable override public var shadowOpacity:Float {
93 | get {
94 | return layer.shadowOpacity
95 | }
96 | set {
97 | layer.shadowOpacity = newValue
98 | }
99 | }
100 |
101 | /**
102 | The shadow radius of the layer
103 |
104 | - Returns: CGFloat
105 | */
106 | @IBInspectable override public var shadowRadius:CGFloat {
107 | get {
108 | return layer.shadowRadius
109 | }
110 | set {
111 | layer.shadowRadius = newValue
112 | }
113 | }
114 |
115 | // MARK: Inspectable properties
116 |
117 | @IBInspectable var startColor: UIColor? {
118 | didSet{
119 | setupView()
120 | }
121 | }
122 |
123 | @IBInspectable var endColor: UIColor? {
124 | didSet{
125 | setupView()
126 | }
127 | }
128 |
129 | @IBInspectable var isHorizontal: Bool = false {
130 | didSet{
131 | setupView()
132 | }
133 | }
134 |
135 |
136 | // MARK: Internal functions
137 |
138 | fileprivate func setupView(){
139 | guard (startColor != nil) && (endColor != nil) else {
140 | return
141 | }
142 | let colors = [startColor!.cgColor, endColor!.cgColor]
143 | gradientLayer.colors = colors
144 | gradientLayer.cornerRadius = cornerRadius
145 | if (isHorizontal){
146 | gradientLayer.endPoint = CGPoint(x: 1, y: 0)
147 | } else {
148 | gradientLayer.endPoint = CGPoint(x: 0, y: 1)
149 | }
150 | self.setNeedsDisplay()
151 | }
152 |
153 | // Helper to return the main layer as CAGradientLayer
154 | var gradientLayer: CAGradientLayer {
155 | return layer as! CAGradientLayer
156 | }
157 |
158 |
159 | // MARK: Overrides ******************************************
160 |
161 | override open class var layerClass:AnyClass{
162 | return CAGradientLayer.self
163 | }
164 |
165 | override init(frame: CGRect) {
166 | super.init(frame: frame)
167 | setupView()
168 | }
169 |
170 | required public init(coder aDecoder: NSCoder) {
171 | super.init(coder: aDecoder)!
172 | setupView()
173 | }
174 |
175 | }
176 |
--------------------------------------------------------------------------------
/Sources/InspectableView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // InspectableView.swift
3 | // ViewHelper: Version 4.2.4
4 | // Created by Melvin Rivera on 7/24/14.
5 | // https://github.com/melvitax/ViewHelper
6 | //
7 |
8 |
9 | import Foundation
10 | import UIKit
11 | import QuartzCore
12 |
13 | @IBDesignable open class InspectableView :UIView {
14 |
15 |
16 | // MARK: Border
17 |
18 | /**
19 | The layer border color
20 | */
21 | @IBInspectable override public var borderColor: UIColor {
22 | get {
23 | return layer.borderColor == nil ? UIColor.clear : UIColor(cgColor: layer.borderColor!)
24 | }
25 | set {
26 | layer.borderColor = newValue.cgColor
27 | }
28 | }
29 |
30 | /**
31 | The layer border width
32 | */
33 | @IBInspectable override public var borderWidth: CGFloat {
34 | get {
35 | return layer.borderWidth
36 | }
37 | set {
38 | layer.borderWidth = newValue
39 | }
40 | }
41 |
42 |
43 | // MARK: Corner Radius
44 |
45 | /**
46 | The layer corner radius
47 | */
48 | @IBInspectable override public var cornerRadius: CGFloat {
49 | get {
50 | return layer.cornerRadius
51 | }
52 | set {
53 | layer.cornerRadius = newValue
54 | layer.masksToBounds = newValue > 0
55 | setupView()
56 | }
57 | }
58 |
59 |
60 | // MARK: Shadow
61 |
62 | /**
63 | The shadow color of the layer
64 | */
65 | @IBInspectable override public var shadowColor: UIColor {
66 | get {
67 | return layer.shadowColor == nil ? UIColor.clear : UIColor(cgColor: layer.shadowColor!)
68 | }
69 | set {
70 | layer.shadowColor = newValue.cgColor
71 | }
72 | }
73 |
74 |
75 | /**
76 | The shadow offset of the layer
77 | */
78 | @IBInspectable override public var shadowOffset:CGSize {
79 | get {
80 | return layer.shadowOffset
81 | }
82 | set {
83 | layer.shadowOffset = newValue
84 | }
85 | }
86 |
87 | /**
88 | The shadow opacity of the layer
89 |
90 | - Returns: Float
91 | */
92 | @IBInspectable override public var shadowOpacity:Float {
93 | get {
94 | return layer.shadowOpacity
95 | }
96 | set {
97 | layer.shadowOpacity = newValue
98 | }
99 | }
100 |
101 | /**
102 | The shadow radius of the layer
103 |
104 | - Returns: CGFloat
105 | */
106 | @IBInspectable override public var shadowRadius:CGFloat {
107 | get {
108 | return layer.shadowRadius
109 | }
110 | set {
111 | layer.shadowRadius = newValue
112 | }
113 | }
114 |
115 | // MARK: Inspectable properties
116 |
117 | @IBInspectable var startColor: UIColor = UIColor.white {
118 | didSet{
119 | setupView()
120 | }
121 | }
122 |
123 | @IBInspectable var endColor: UIColor = UIColor.black {
124 | didSet{
125 | setupView()
126 | }
127 | }
128 |
129 | @IBInspectable var isHorizontal: Bool = false {
130 | didSet{
131 | setupView()
132 | }
133 | }
134 |
135 |
136 | // MARK: Internal functions
137 |
138 | fileprivate func setupView(){
139 | let colors = [startColor.cgColor, endColor.cgColor]
140 | gradientLayer.colors = colors
141 | gradientLayer.cornerRadius = cornerRadius
142 | if (isHorizontal){
143 | gradientLayer.endPoint = CGPoint(x: 1, y: 0)
144 | } else {
145 | gradientLayer.endPoint = CGPoint(x: 0, y: 1)
146 | }
147 | self.setNeedsDisplay()
148 | }
149 |
150 | // Helper to return the main layer as CAGradientLayer
151 | var gradientLayer: CAGradientLayer {
152 | return layer as! CAGradientLayer
153 | }
154 |
155 |
156 | // MARK: Overrides ******************************************
157 |
158 | override open class var layerClass:AnyClass{
159 | return CAGradientLayer.self
160 | }
161 |
162 | override init(frame: CGRect) {
163 | super.init(frame: frame)
164 | setupView()
165 | }
166 |
167 | required public init(coder aDecoder: NSCoder) {
168 | super.init(coder: aDecoder)!
169 | setupView()
170 | }
171 |
172 | open override func prepareForInterfaceBuilder() {
173 | setupView()
174 | }
175 |
176 | }
177 |
--------------------------------------------------------------------------------
/Sources/ViewAnimation.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewAnimation.swift
3 | // ViewHelper: Version 4.2.4
4 | // Created by Melvin Rivera on 11/23/15.
5 | // https://github.com/melvitax/ViewHelper
6 | //
7 |
8 | import Foundation
9 | import UIKit
10 |
11 | /**
12 | A preset animation behavior.
13 | */
14 | public enum AnimationType {
15 | case slideLeft, slideRight, slideDown, slideUp, squeezeLeft, squeezeRight, squeezeDown, squeezeUp, fadeIn, fadeOut, fadeOutIn, fadeInLeft, fadeInRight, fadeInDown, fadeInUp, zoomIn, zoomOut, fall, shake, pop, flipX, flipY, morph, squeeze, flash, wobble, swing
16 | static let allValues = [shake, pop, morph, squeeze, wobble, swing, flipX, flipY, fall, squeezeLeft, squeezeRight, squeezeDown, squeezeUp, slideLeft, slideRight, slideDown, slideUp, fadeIn, fadeOut, fadeOutIn, fadeInLeft, fadeInRight, fadeInDown, fadeInUp, zoomIn, zoomOut, flash]
17 | var description: String {
18 | get {
19 | return String(describing: self)
20 | }
21 | }
22 | }
23 |
24 | /**
25 | Easing curve to be used in animation.
26 | */
27 | public enum AnimationEasingCurve {
28 | case easeIn, easeOut, easeInOut, linear, easeInSine, easeOutSine, easeInOutSine, easeInQuad, easeOutQuad, easeInOutQuad, easeInCubic, easeOutCubic, easeInOutCubic, easeInQuart, easeOutQuart, easeInOutQuart, easeInQuint, easeOutQuint, easeInOutQuint, easeInExpo, easeOutExpo, easeInOutExpo, easeInCirc, easeOutCirc, easeInOutCirc, easeInBack, easeOutBack, easeInOutBack, spring
29 | static let allValues = [easeIn, easeOut, easeInOut, linear, easeInSine, easeOutSine, easeInOutSine, easeInQuad, easeOutQuad, easeInOutQuad, easeInCubic, easeOutCubic, easeInOutCubic, easeInQuart, easeOutQuart, easeInOutQuart, easeInQuint, easeOutQuint, easeInOutQuint, easeInExpo, easeOutExpo, easeInOutExpo, easeInCirc, easeOutCirc, easeInOutCirc, easeInBack, easeOutBack, easeInOutBack, spring]
30 | var timingFunction:CAMediaTimingFunction {
31 | switch self {
32 | case .easeIn: return CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn)
33 | case .easeOut: return CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)
34 | case .easeInOut: return CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
35 | case .linear: return CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
36 | case .easeInSine: return CAMediaTimingFunction(controlPoints: 0.47, 0, 0.745, 0.715)
37 | case .easeOutSine: return CAMediaTimingFunction(controlPoints: 0.39, 0.575, 0.565, 1)
38 | case .easeInOutSine: return CAMediaTimingFunction(controlPoints: 0.445, 0.05, 0.55, 0.95)
39 | case .easeInQuad: return CAMediaTimingFunction(controlPoints: 0.55, 0.085, 0.68, 0.53)
40 | case .easeOutQuad: return CAMediaTimingFunction(controlPoints: 0.25, 0.46, 0.45, 0.94)
41 | case .easeInOutQuad: return CAMediaTimingFunction(controlPoints: 0.455, 0.03, 0.515, 0.955)
42 | case .easeInCubic: return CAMediaTimingFunction(controlPoints: 0.55, 0.055, 0.675, 0.19)
43 | case .easeOutCubic: return CAMediaTimingFunction(controlPoints: 0.215, 0.61, 0.355, 1)
44 | case .easeInOutCubic: return CAMediaTimingFunction(controlPoints: 0.645, 0.045, 0.355, 1)
45 | case .easeInQuart: return CAMediaTimingFunction(controlPoints: 0.895, 0.03, 0.685, 0.22)
46 | case .easeOutQuart: return CAMediaTimingFunction(controlPoints: 0.165, 0.84, 0.44, 1)
47 | case .easeInOutQuart: return CAMediaTimingFunction(controlPoints: 0.77, 0, 0.175, 1)
48 | case .easeInQuint: return CAMediaTimingFunction(controlPoints: 0.755, 0.05, 0.855, 0.06)
49 | case .easeOutQuint: return CAMediaTimingFunction(controlPoints: 0.23, 1, 0.32, 1)
50 | case .easeInOutQuint: return CAMediaTimingFunction(controlPoints: 0.86, 0, 0.07, 1)
51 | case .easeInExpo: return CAMediaTimingFunction(controlPoints: 0.95, 0.05, 0.795, 0.035)
52 | case .easeOutExpo: return CAMediaTimingFunction(controlPoints: 0.19, 1, 0.22, 1)
53 | case .easeInOutExpo: return CAMediaTimingFunction(controlPoints: 1, 0, 0, 1)
54 | case .easeInCirc: return CAMediaTimingFunction(controlPoints: 0.6, 0.04, 0.98, 0.335)
55 | case .easeOutCirc: return CAMediaTimingFunction(controlPoints: 0.075, 0.82, 0.165, 1)
56 | case .easeInOutCirc: return CAMediaTimingFunction(controlPoints: 0.785, 0.135, 0.15, 0.86)
57 | case .easeInBack: return CAMediaTimingFunction(controlPoints: 0.6, -0.28, 0.735, 0.045)
58 | case .easeOutBack: return CAMediaTimingFunction(controlPoints: 0.175, 0.885, 0.32, 1.275)
59 | case .easeInOutBack: return CAMediaTimingFunction(controlPoints: 0.68, -0.55, 0.265, 1.55)
60 | case .spring: return CAMediaTimingFunction(controlPoints: 0.5, 1.1+Float(1/3), 1, 1)
61 | }
62 | }
63 | var animationOption:UIViewAnimationOptions {
64 | switch self {
65 | case .easeIn: return UIViewAnimationOptions.curveEaseIn
66 | case .easeOut: return UIViewAnimationOptions.curveEaseOut
67 | case .easeInOut: return UIViewAnimationOptions()
68 | default: return UIViewAnimationOptions.curveLinear
69 | }
70 | }
71 | var description: String {
72 | get {
73 | return String(describing: self)
74 | }
75 | }
76 | }
77 |
78 | public extension UIView {
79 |
80 | typealias AnimationCompletionHandler = () -> Void
81 |
82 | /**
83 | Animates using a predermined animation type and provides optional properties for customization.
84 |
85 | - Parameter animationType: The Animation type to use.
86 | - Parameter curve: The animation easing curve.
87 | - Parameter duration: The duration of the animation.
88 | - Parameter delay: The delay before animation begins.
89 | - Parameter force: The force of the movement.
90 | - Parameter damping: The damping of the force.
91 | - Parameter velocity: The velocity of the movement.
92 | - Parameter distance: The distance that it travels, like in the case of SlideLeft
93 | - Parameter fromRotation: The starting rotation.
94 | - Parameter fromScale: The starting scale.
95 | - Parameter fromX: The starting x offset.
96 | - Parameter fromY: The starting y offset.
97 | - Parameter completion: The completion handler that runs after animation is complete.
98 | */
99 |
100 | func animate(_ animationType:AnimationType, curve:AnimationEasingCurve, duration:CGFloat = 1, delay:CGFloat = 0, force:CGFloat = 1, damping:CGFloat = 0.7, velocity:CGFloat = 0.7, distance:CGFloat = 300.0, fromRotation:CGFloat = 0, fromScale:CGFloat = 1, fromX:CGFloat = 0, fromY:CGFloat = 0, completion: AnimationCompletionHandler? = nil)
101 | {
102 | var scaleX = fromScale
103 | var scaleY = fromScale
104 | var opacity:CGFloat = 0
105 | let repeatCount:Float = 1
106 | var rotate = fromRotation
107 | var x = fromX
108 | var y = fromY
109 |
110 | var animateFromInitialState = true
111 |
112 | alpha = 0.99
113 |
114 | switch animationType {
115 | case .slideLeft:
116 | x = distance*force
117 | case .slideRight:
118 | x = -distance*force
119 | case .slideDown:
120 | y = -distance*force
121 | case .slideUp:
122 | y = distance*force
123 | case .squeezeLeft:
124 | x = distance
125 | scaleX = 3*force
126 | case .squeezeRight:
127 | x = -distance
128 | scaleX = 3*force
129 | case .squeezeDown:
130 | y = -distance
131 | scaleY = 3*force
132 | case .squeezeUp:
133 | y = distance
134 | scaleY = 3*force
135 | case .fadeIn:
136 | opacity = 0
137 | case .fadeOut:
138 | animateFromInitialState = false
139 | opacity = 0
140 | case .fadeOutIn:
141 | let animation = CABasicAnimation()
142 | animation.keyPath = "opacity"
143 | animation.fromValue = 1
144 | animation.toValue = 0
145 | animation.timingFunction = curve.timingFunction
146 | animation.duration = CFTimeInterval(duration)
147 | animation.beginTime = CACurrentMediaTime() + CFTimeInterval(delay)
148 | animation.autoreverses = true
149 | layer.add(animation, forKey: "fade")
150 | case .fadeInLeft:
151 | opacity = 0
152 | x = distance*force
153 | case .fadeInRight:
154 | x = -distance*force
155 | opacity = 0
156 | case .fadeInDown:
157 | y = -distance*force
158 | opacity = 0
159 | case .fadeInUp:
160 | y = distance*force
161 | opacity = 0
162 | case .zoomIn:
163 | opacity = 0
164 | scaleX = 2*force
165 | scaleY = 2*force
166 | case .zoomOut:
167 | animateFromInitialState = false
168 | opacity = 0
169 | scaleX = 2*force
170 | scaleY = 2*force
171 | case .fall:
172 | animateFromInitialState = false
173 | rotate = 15 * CGFloat(M_PI/180)
174 | y = distance*force
175 | case .shake:
176 | let animation = CAKeyframeAnimation()
177 | animation.keyPath = "position.x"
178 | animation.values = [0, 30*force, -30*force, 30*force, 0]
179 | animation.keyTimes = [0, 0.2, 0.4, 0.6, 0.8, 1]
180 | animation.timingFunction = curve.timingFunction
181 | animation.duration = CFTimeInterval(duration)
182 | animation.isAdditive = true
183 | animation.repeatCount = repeatCount
184 | animation.beginTime = CACurrentMediaTime() + CFTimeInterval(delay)
185 | layer.add(animation, forKey: "shake")
186 | case .pop:
187 | let animation = CAKeyframeAnimation()
188 | animation.keyPath = "transform.scale"
189 | animation.values = [0, 0.2*force, -0.2*force, 0.2*force, 0]
190 | animation.keyTimes = [0, 0.2, 0.4, 0.6, 0.8, 1]
191 | animation.timingFunction = curve.timingFunction
192 | animation.duration = CFTimeInterval(duration)
193 | animation.isAdditive = true
194 | animation.repeatCount = repeatCount
195 | animation.beginTime = CACurrentMediaTime() + CFTimeInterval(delay)
196 | layer.add(animation, forKey: "pop")
197 | case .flipX:
198 | rotate = 0
199 | scaleX = 1
200 | scaleY = 1
201 | var perspective = CATransform3DIdentity
202 | perspective.m34 = -1.0 / layer.frame.size.width/2
203 |
204 | let animation = CABasicAnimation()
205 | animation.keyPath = "transform"
206 | animation.fromValue = NSValue(caTransform3D:
207 | CATransform3DMakeRotation(0, 0, 0, 0))
208 | animation.toValue = NSValue(caTransform3D:
209 | CATransform3DConcat(perspective, CATransform3DMakeRotation(CGFloat(M_PI), 0, 1, 0)))
210 | animation.duration = CFTimeInterval(duration)
211 | animation.beginTime = CACurrentMediaTime() + CFTimeInterval(delay)
212 | animation.timingFunction = curve.timingFunction
213 | layer.add(animation, forKey: "3d")
214 | case .flipY:
215 | var perspective = CATransform3DIdentity
216 | perspective.m34 = -1.0 / layer.frame.size.width/2
217 |
218 | let animation = CABasicAnimation()
219 | animation.keyPath = "transform"
220 | animation.fromValue = NSValue(caTransform3D:
221 | CATransform3DMakeRotation(0, 0, 0, 0))
222 | animation.toValue = NSValue(caTransform3D:
223 | CATransform3DConcat(perspective,CATransform3DMakeRotation(CGFloat(M_PI), 1, 0, 0)))
224 | animation.duration = CFTimeInterval(duration)
225 | animation.beginTime = CACurrentMediaTime() + CFTimeInterval(delay)
226 | animation.timingFunction = curve.timingFunction
227 | layer.add(animation, forKey: "3d")
228 | case .morph:
229 | let morphX = CAKeyframeAnimation()
230 | morphX.keyPath = "transform.scale.x"
231 | morphX.values = [1, 1.3*force, 0.7, 1.3*force, 1]
232 | morphX.keyTimes = [0, 0.2, 0.4, 0.6, 0.8, 1]
233 | morphX.timingFunction = curve.timingFunction
234 | morphX.duration = CFTimeInterval(duration)
235 | morphX.repeatCount = repeatCount
236 | morphX.beginTime = CACurrentMediaTime() + CFTimeInterval(delay)
237 | layer.add(morphX, forKey: "morphX")
238 |
239 | let morphY = CAKeyframeAnimation()
240 | morphY.keyPath = "transform.scale.y"
241 | morphY.values = [1, 0.7, 1.3*force, 0.7, 1]
242 | morphY.keyTimes = [0, 0.2, 0.4, 0.6, 0.8, 1]
243 | morphY.timingFunction = curve.timingFunction
244 | morphY.duration = CFTimeInterval(duration)
245 | morphY.repeatCount = repeatCount
246 | morphY.beginTime = CACurrentMediaTime() + CFTimeInterval(delay)
247 | layer.add(morphY, forKey: "morphY")
248 | case .squeeze:
249 | let morphX = CAKeyframeAnimation()
250 | morphX.keyPath = "transform.scale.x"
251 | morphX.values = [1, 1.5*force, 0.5, 1.5*force, 1]
252 | morphX.keyTimes = [0, 0.2, 0.4, 0.6, 0.8, 1]
253 | morphX.timingFunction = curve.timingFunction
254 | morphX.duration = CFTimeInterval(duration)
255 | morphX.repeatCount = repeatCount
256 | morphX.beginTime = CACurrentMediaTime() + CFTimeInterval(delay)
257 | layer.add(morphX, forKey: "morphX")
258 |
259 | let morphY = CAKeyframeAnimation()
260 | morphY.keyPath = "transform.scale.y"
261 | morphY.values = [1, 0.5, 1, 0.5, 1]
262 | morphY.keyTimes = [0, 0.2, 0.4, 0.6, 0.8, 1]
263 | morphY.timingFunction = curve.timingFunction
264 | morphY.duration = CFTimeInterval(duration)
265 | morphY.repeatCount = repeatCount
266 | morphY.beginTime = CACurrentMediaTime() + CFTimeInterval(delay)
267 | layer.add(morphY, forKey: "morphY")
268 | case .flash:
269 | let animation = CABasicAnimation()
270 | animation.keyPath = "opacity"
271 | animation.fromValue = 1
272 | animation.toValue = 0
273 | animation.duration = CFTimeInterval(duration)
274 | animation.repeatCount = repeatCount * 2.0
275 | animation.autoreverses = true
276 | animation.beginTime = CACurrentMediaTime() + CFTimeInterval(delay)
277 | layer.add(animation, forKey: "flash")
278 | case .wobble:
279 | let animation = CAKeyframeAnimation()
280 | animation.keyPath = "transform.rotation"
281 | animation.values = [0, 0.3*force, -0.3*force, 0.3*force, 0]
282 | animation.keyTimes = [0, 0.2, 0.4, 0.6, 0.8, 1]
283 | animation.duration = CFTimeInterval(duration)
284 | animation.isAdditive = true
285 | animation.beginTime = CACurrentMediaTime() + CFTimeInterval(delay)
286 | layer.add(animation, forKey: "wobble")
287 |
288 | let x = CAKeyframeAnimation()
289 | x.keyPath = "position.x"
290 | x.values = [0, 30*force, -30*force, 30*force, 0]
291 | x.keyTimes = [0, 0.2, 0.4, 0.6, 0.8, 1]
292 | x.timingFunction = curve.timingFunction
293 | x.duration = CFTimeInterval(duration)
294 | x.isAdditive = true
295 | x.repeatCount = repeatCount
296 | x.beginTime = CACurrentMediaTime() + CFTimeInterval(delay)
297 | layer.add(x, forKey: "x")
298 | case .swing:
299 | let animation = CAKeyframeAnimation()
300 | animation.keyPath = "transform.rotation"
301 | animation.values = [0, 0.3*force, -0.3*force, 0.3*force, 0]
302 | animation.keyTimes = [0, 0.2, 0.4, 0.6, 0.8, 1]
303 | animation.duration = CFTimeInterval(duration)
304 | animation.isAdditive = true
305 | animation.beginTime = CACurrentMediaTime() + CFTimeInterval(delay)
306 | layer.add(animation, forKey: "swing")
307 | }
308 |
309 | if animateFromInitialState {
310 | let translate = CGAffineTransform(translationX: x, y: y)
311 | let scale = CGAffineTransform(scaleX: scaleX, y: scaleY)
312 | let rotate = CGAffineTransform(rotationAngle: rotate)
313 | let translateAndScale = translate.concatenating(scale)
314 | self.transform = rotate.concatenating(translateAndScale)
315 | alpha = opacity
316 | }
317 |
318 | UIView.animate( withDuration: TimeInterval(duration),
319 | delay: TimeInterval(delay),
320 | usingSpringWithDamping: damping,
321 | initialSpringVelocity: velocity,
322 | options: [curve.animationOption, UIViewAnimationOptions.allowUserInteraction],
323 | animations: { [weak self] in
324 | if let _self = self {
325 | if animateFromInitialState {
326 | _self.transform = CGAffineTransform.identity
327 | _self.alpha = 1
328 | } else {
329 | let translate = CGAffineTransform(translationX: x, y: y)
330 | let scale = CGAffineTransform(scaleX: scaleX, y: scaleY)
331 | let rotate = CGAffineTransform(rotationAngle: rotate)
332 | let translateAndScale = translate.concatenating(scale)
333 | _self.transform = rotate.concatenating(translateAndScale)
334 | _self.alpha = opacity
335 | }
336 | }
337 | }, completion: { finished in
338 | completion?()
339 | })
340 | }
341 | }
342 |
--------------------------------------------------------------------------------
/Sources/ViewAutoLayout.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewAutoLayout.swift
3 | // ViewHelper: Version 4.2.4
4 | // Created by Melvin Rivera on 11/5/15.
5 | // https://github.com/melvitax/ViewHelper
6 | //
7 |
8 |
9 | import Foundation
10 | import UIKit
11 |
12 | public extension UIView {
13 |
14 | // MARK: Init
15 |
16 | /**
17 | Instantiates a new UIView with Auto Layout
18 |
19 | - Parameter autoLayout Enables Auto Layout.
20 | - Returns: self
21 | */
22 | convenience init(autoLayout: Bool = true)
23 | {
24 | self.init(frame:CGRect.zero)
25 | self.translatesAutoresizingMaskIntoConstraints = !(autoLayout)
26 | }
27 |
28 | // MARK: Position
29 |
30 | /**
31 | Returns the frame's origin
32 | */
33 |
34 | func origin() -> CGPoint { return frame.origin }
35 |
36 | /**
37 | Sets the frame's top and left sides using Auto Layout or frames
38 |
39 | - Parameter constant: The CGPoint to ise as the origin
40 | - Returns: self
41 | */
42 | func origin(_ constant: CGPoint) -> UIView {
43 | if translatesAutoresizingMaskIntoConstraints {
44 | frame.origin = constant
45 | return self
46 | } else {
47 | return origin(to: superview!, constant: constant)
48 | }
49 | }
50 | /**
51 | Pins left and top sides to another view using Auto Layout
52 |
53 | - Parameter to: The view to pin to
54 | - Parameter constant: The offset to use after multiplication is done.
55 | - Parameter multiplier: The multiplier to use, i.e. 0.5 is half.
56 | - Returns: self UIView
57 | */
58 | func origin(to:AnyObject, constant: CGPoint = CGPoint(x: 0, y: 0), multiplier:CGFloat = 1) -> UIView {
59 | var constraints = [NSLayoutConstraint]()
60 | if let left = pin(.left, to: to, attribute: .left, constant: constant.x, multiplier: multiplier) {
61 | constraints.append(left)
62 | }
63 | if let top = pin(.top, to: to, attribute: .top, constant: constant.y, multiplier: multiplier) {
64 | constraints.append(top)
65 | }
66 | return self
67 | }
68 |
69 | /**
70 | Returns the frame minimum x point
71 | */
72 | func left() -> CGFloat { return frame.origin.x }
73 |
74 | /**
75 | Sets the frame left side using Auto Layout or frames
76 |
77 | - Parameter constant: The value to use.
78 | - Returns: self
79 | */
80 | func left(_ constant: CGFloat) -> UIView {
81 | if translatesAutoresizingMaskIntoConstraints {
82 | frame.origin.x = constant
83 | return self
84 | } else {
85 | return left(to: superview!, attribute: .left, constant: constant)
86 | }
87 | }
88 |
89 | /**
90 | Pins left side to another view using Auto Layout
91 |
92 | - Parameter to: The view to pin to
93 | - Parameter attribute: The attribute to pin to
94 | - Parameter constant: The offset to use after multiplication is done.
95 | - Parameter multiplier: The multiplier to use, i.e. 0.5 is half.
96 | - Returns: self
97 | */
98 | func left(to:AnyObject, attribute: NSLayoutAttribute = .left, constant: CGFloat = 0, multiplier:CGFloat = 1) -> UIView {
99 | _ = pin(.left, to: to, attribute: attribute, constant: constant, multiplier: multiplier)
100 | return self
101 | }
102 |
103 | /**
104 | Returns the frame leading value
105 | */
106 | func leading() -> CGFloat { return layoutDirectionIsLeftToRight() ? left() : right() }
107 |
108 | /**
109 | Sets the frame leading side using Auto Layout or frames
110 |
111 | - Parameter constant: The value to use.
112 | - Returns: self
113 | */
114 | func leading(_ constant: CGFloat) -> UIView {
115 | if translatesAutoresizingMaskIntoConstraints {
116 | return layoutDirectionIsLeftToRight() ? left(constant) : right(constant)
117 | } else {
118 | return leading(to: superview!, attribute: .leading, constant: constant)
119 | }
120 | }
121 |
122 | /**
123 | Pins the frame leading side to another view using Auto Layout
124 |
125 | - Parameter to: The view to pin to
126 | - Parameter attribute: The attribute to pin to
127 | - Parameter constant: The offset to use after multiplication is done.
128 | - Parameter multiplier: The multiplier to use, i.e. 0.5 is half.
129 | - Returns: self
130 | */
131 | func leading(to:AnyObject, attribute: NSLayoutAttribute = .leading, constant: CGFloat = 0, multiplier:CGFloat = 1) -> UIView {
132 | _ = pin(.leading, to: to, attribute: attribute, constant: constant, multiplier: multiplier)
133 | return self
134 | }
135 |
136 | /**
137 | Returns the frame max x point
138 | */
139 | func right() -> CGFloat { return frame.origin.x + frame.size.width }
140 |
141 | /**
142 | Sets the frame right side using Auto Layout or frames
143 |
144 | - Parameter constant: The value to use.
145 | - Returns: self
146 | */
147 | func right(_ constant: CGFloat) -> UIView {
148 | if translatesAutoresizingMaskIntoConstraints {
149 | return left(constant - width())
150 | } else {
151 | return right(to: superview!, attribute: .right, constant: constant)
152 | }
153 | }
154 | /**
155 | Pins the frame right side to another view using Auto Layout
156 |
157 | - Parameter to: The view to pin to
158 | - Parameter attribute: The attribute to pin to
159 | - Parameter constant: The offset to use after multiplication is done.
160 | - Parameter multiplier: The multiplier to use, i.e. 0.5 is half.
161 | - Returns: self
162 | */
163 | func right(to:AnyObject, attribute: NSLayoutAttribute = .right, constant: CGFloat = 0, multiplier:CGFloat = 1) -> UIView {
164 | _ = pin(.right, to: to, attribute: attribute, constant: constant, multiplier: multiplier)
165 | return self
166 | }
167 |
168 | /**
169 | Returns the frame trailing value
170 | */
171 | func trailing() -> CGFloat { return layoutDirectionIsLeftToRight() ? right() : left() }
172 |
173 | /**
174 | Sets the frame trailing side using Auto Layout or frames
175 |
176 | - Parameter constant: The value to use
177 | - Returns: self UIView
178 | */
179 | func trailing(_ constant: CGFloat) -> UIView {
180 | if translatesAutoresizingMaskIntoConstraints {
181 | return layoutDirectionIsLeftToRight() ? right(constant) : left(constant)
182 | } else {
183 | return trailing(to: superview!, attribute: .trailing, constant: constant)
184 | }
185 | }
186 |
187 | /**
188 | Pins the frame trailing side to another view using Auto Layout
189 |
190 | - Parameter to: The view to pin to
191 | - Parameter attribute: The attribute to pin to
192 | - Parameter constant: The offset to use after multiplication is done.
193 | - Parameter multiplier: The multiplier to use, i.e. 0.5 is half.
194 | - Returns: self
195 | */
196 | func trailing(to:AnyObject, attribute: NSLayoutAttribute = .trailing, constant: CGFloat = 0, multiplier:CGFloat = 1) -> UIView {
197 | _ = pin(.trailing, to: to, attribute: attribute, constant: constant, multiplier: multiplier)
198 | return self
199 | }
200 |
201 | /**
202 | Returns the frame top value
203 | */
204 | func top() -> CGFloat { return frame.origin.y }
205 |
206 | /**
207 | Sets the frame top side using Auto Layout or frames
208 |
209 | - Parameter constant: The value to use.
210 | - Returns: self
211 | */
212 | func top(_ constant: CGFloat) -> UIView {
213 | if translatesAutoresizingMaskIntoConstraints {
214 | frame.origin.y = constant
215 | return self
216 | } else {
217 | return top(to: superview!, attribute: .top, constant: constant)
218 | }
219 | }
220 |
221 | /**
222 | Pins the frame trailing side to another view using Auto Layout
223 |
224 | - Parameter to: The view to pin to
225 | - Parameter attribute: The attribute to pin to
226 | - Parameter constant: The offset to use after multiplication is done.
227 | - Parameter multiplier: The multiplier to use, i.e. 0.5 is half.
228 | - Returns: self
229 | */
230 | func top(to:AnyObject, attribute: NSLayoutAttribute = .top, constant: CGFloat = 0, multiplier:CGFloat = 1) -> UIView {
231 | _ = pin(.top, to: to, attribute: attribute, constant: constant, multiplier: multiplier)
232 | return self
233 | }
234 |
235 | /**
236 | Returns the frame bottom value
237 | */
238 | func bottom() -> CGFloat { return top() + height() }
239 |
240 | /**
241 | Sets the frame bottom side using Auto Layout or frames
242 |
243 | - Parameter constant: The value to use.
244 | - Returns: self
245 | */
246 | func bottom(_ constant: CGFloat) -> UIView {
247 | if translatesAutoresizingMaskIntoConstraints {
248 | return top(constant - height())
249 | } else {
250 | return bottom(to: superview!, attribute: .bottom, constant: constant)
251 | }
252 | }
253 | /**
254 | Pins the frame bottom side to another view using Auto Layout
255 |
256 | - Parameter to: The view to pin to
257 | - Parameter attribute: The attribute to pin to
258 | - Parameter constant: The offset to use after multiplication is done.
259 | - Parameter multiplier: The multiplier to use, i.e. 0.5 is half.
260 | - Returns: self
261 | */
262 | func bottom(to:AnyObject, attribute: NSLayoutAttribute = .bottom, constant: CGFloat = 0, multiplier:CGFloat = 1) -> UIView {
263 | _ = pin(.bottom, to: to, attribute: attribute, constant: constant, multiplier: multiplier)
264 | return self
265 | }
266 |
267 | /**
268 | Sets the center to it's superview using Auto Layout or frames
269 |
270 | - Parameter constant: The value to use.
271 | - Returns: self
272 | */
273 | func center(_ constant: CGPoint = CGPoint(x: 0, y: 0)) -> UIView {
274 | if translatesAutoresizingMaskIntoConstraints {
275 | center = constant
276 | } else {
277 | _ = centerX(constant.x).centerY(constant.y)
278 | }
279 | return self
280 | }
281 |
282 | /**
283 | Pins the center point to another view using Auto Layout
284 |
285 | - Parameter to: The view to pin to
286 | - Parameter constant: The offset to use after multiplication is done.
287 | - Parameter multiplier: The multiplier to use, i.e. 0.5 is half.
288 | - Returns: self
289 | */
290 | func center(to:AnyObject, constant:CGSize = CGSize(width: 0, height: 0), multiplier:CGFloat = 1) -> UIView {
291 | var constraints = [NSLayoutConstraint]()
292 | if let centerX = pin(.centerX, to: superview!, attribute: .centerX, constant: constant.width, multiplier: multiplier) {
293 | constraints.append(centerX)
294 | }
295 | if let centerY = pin(.centerY, to: superview!, attribute: .centerY, constant: constant.height, multiplier: multiplier) {
296 | constraints.append(centerY)
297 | }
298 | return self
299 | }
300 |
301 | /**
302 | Returns the center X
303 | */
304 | func centerX() -> CGFloat { return center.x }
305 |
306 | /**
307 | Sets the center X using Auto Layout or frames
308 |
309 | - Parameter constant: The value to use.
310 | - Returns: self
311 | */
312 | func centerX(_ constant: CGFloat = 0) -> UIView {
313 | if translatesAutoresizingMaskIntoConstraints {
314 | center = CGPoint(x: superview!.width()/2 + constant , y: center.y)
315 | } else {
316 | _ = pin(.centerX, to: superview!, attribute: .centerX, constant: constant)
317 | }
318 | return self
319 | }
320 |
321 | /**
322 | Pins the center X to another view using Auto Layout
323 |
324 | - Parameter to: The view to pin to
325 | - Parameter attribute: The attribute to pin to
326 | - Parameter constant: The offset to use after multiplication is done.
327 | - Parameter multiplier: The multiplier to use, i.e. 0.5 is half.
328 | - Returns: self
329 | */
330 | func centerX(to:AnyObject, attribute: NSLayoutAttribute = .centerX, constant: CGFloat = 0, multiplier:CGFloat = 1) -> UIView {
331 | _ = pin(.centerX, to: to, attribute: attribute, constant: constant, multiplier: multiplier)
332 | return self
333 | }
334 |
335 | /**
336 | Returns the center Y
337 | */
338 | func centerY() -> CGFloat { return center.y }
339 |
340 | /**
341 | Sets the center Y using Auto Layout or frames
342 |
343 | - Parameter constant: The value to use.
344 | - Returns: self
345 | */
346 | func centerY(_ constant: CGFloat = 0) -> UIView {
347 | if translatesAutoresizingMaskIntoConstraints {
348 | center = CGPoint(x: superview!.center.x, y: CGFloat(superview!.height()/2) + constant)
349 | } else {
350 | _ = pin(.centerY, to: superview!, attribute: .centerY, constant: constant)
351 | }
352 | return self
353 | }
354 |
355 | /**
356 | Pins the center Y to another view using Auto Layout
357 |
358 | - Parameter to: The view to pin to
359 | - Parameter attribute: The attribute to pin to
360 | - Parameter constant: The offset to use after multiplication is done.
361 | - Parameter multiplier: The multiplier to use, i.e. 0.5 is half.
362 | - Returns: self
363 | */
364 | func centerY(to:AnyObject, attribute: NSLayoutAttribute = .centerY, constant: CGFloat = 0, multiplier:CGFloat = 1) -> UIView {
365 | _ = pin(.centerY, to: superview!, attribute: attribute, constant: constant)
366 | return self
367 | }
368 |
369 | // MARK: Compression and Hugging Priority
370 |
371 | /**
372 | Returns the Compression Resistance Priority for Horizontal Axis using Auto Layout
373 | */
374 | func horizontalCompressionPriority() -> UILayoutPriority { return contentCompressionResistancePriority(for: .horizontal) }
375 |
376 | /**
377 | Sets the Compression Resistance Priority for Horizontal Axis using Auto Layout
378 |
379 | - Returns: self
380 | */
381 | func horizontalCompressionPriority(_ priority: UILayoutPriority) -> UIView {
382 | if !translatesAutoresizingMaskIntoConstraints {
383 | setContentCompressionResistancePriority(priority, for: .horizontal)
384 | }
385 | return self
386 | }
387 |
388 | /**
389 | Returns the Compression Resistance Priority for Vertical Axis using Auto Layout
390 | */
391 | func verticalCompressionPriority() -> UILayoutPriority { return contentCompressionResistancePriority(for: .vertical) }
392 |
393 | /**
394 | Sets the Compression Resistance Priority for Vertical Axis using Auto Layout
395 |
396 | - Returns: self
397 | */
398 | func verticalCompressionPriority(_ priority: UILayoutPriority) -> UIView {
399 | if !translatesAutoresizingMaskIntoConstraints {
400 | setContentCompressionResistancePriority(priority, for: .vertical)
401 | }
402 | return self
403 | }
404 |
405 | /**
406 | Returns the Content Hugging Priority for Horizontal Axis using Auto Layout
407 | */
408 | func horizontalHuggingPriority() -> UILayoutPriority { return contentHuggingPriority(for: .horizontal) }
409 |
410 | /**
411 | Sets the Content Hugging Priority for Horizontal Axis using Auto Layout
412 |
413 | - Returns: self
414 | */
415 | func horizontalHuggingPriority(_ priority: UILayoutPriority) -> UIView {
416 | if !translatesAutoresizingMaskIntoConstraints {
417 | setContentHuggingPriority(priority, for: .horizontal)
418 | }
419 | return self
420 | }
421 |
422 | /**
423 | Returns the Content Hugging Priority for Vertical Axis using Auto Layout
424 | */
425 | func verticalHuggingPriority() -> UILayoutPriority { return contentHuggingPriority(for: .vertical) }
426 |
427 | /**
428 | Sets the Content Hugging Priority for Vertical Axis using Auto Layout
429 |
430 | - Returns: self
431 | */
432 | func verticalHuggingPriority(_ priority: UILayoutPriority) -> UIView {
433 | if !translatesAutoresizingMaskIntoConstraints {
434 | setContentHuggingPriority(priority, for: .vertical)
435 | }
436 | return self
437 | }
438 |
439 |
440 | // MARK: Size
441 |
442 | /**
443 | Returns the frame size
444 | */
445 | func size() -> CGSize { return frame.size }
446 |
447 | /**
448 | Sets the frame size using Auto Layout or frames
449 |
450 | - Parameter constant: The value to use.
451 | - Returns: self UIView
452 | */
453 | func size(_ constant: CGSize) -> UIView {
454 | if translatesAutoresizingMaskIntoConstraints {
455 | frame.size = constant
456 | } else {
457 | _ = applyAttribute(.width, constant: constant.width)
458 | _ = applyAttribute(.height, constant: constant.height)
459 | }
460 | return self
461 | }
462 |
463 | /**
464 | Pins the size to another view using Auto Layout
465 |
466 | - Parameter to: The view to pin to
467 | - Parameter constant: The offset to use after multiplication is done.
468 | - Parameter multiplier: The multiplier to use, i.e. 0.5 is half.
469 | - Returns: self
470 | */
471 | func size(to:AnyObject, constant: CGSize = CGSize(width: 0, height: 0), multiplier:CGFloat = 1) -> UIView {
472 | if !translatesAutoresizingMaskIntoConstraints {
473 | var constraints = [NSLayoutConstraint]()
474 | if let width = pin(.width, to: to, attribute: .width, constant: constant.width, multiplier: multiplier) {
475 | constraints.append(width)
476 | }
477 | if let height = pin(.height, to: to, attribute: .height, constant: constant.height, multiplier: multiplier) {
478 | constraints.append(height)
479 | }
480 | }
481 | return self
482 | }
483 |
484 | /**
485 | Returns the frame width
486 | */
487 | func width() -> CGFloat { return frame.size.width }
488 |
489 | /**
490 | Sets the frame width using Auto Layout or frames
491 |
492 | - Parameter constant: The value to use.
493 | - Returns: self
494 | */
495 | func width(_ constant: CGFloat) -> UIView {
496 | if translatesAutoresizingMaskIntoConstraints {
497 | frame.size.width = constant
498 | } else {
499 | _ = applyAttribute(.width, constant: constant)
500 | }
501 | return self
502 | }
503 |
504 | /**
505 | Pins the width to another view using Auto Layout
506 |
507 | - Parameter to: The view to pin to
508 | - Parameter attribute: The attribute to pin to
509 | - Parameter constant: The offset to use after multiplication is done.
510 | - Parameter multiplier: The multiplier to use, i.e. 0.5 is half.
511 | - Returns: self
512 | */
513 | func width(to:AnyObject, attribute: NSLayoutAttribute = .width, constant: CGFloat = 0, multiplier:CGFloat = 1) -> UIView {
514 | if !translatesAutoresizingMaskIntoConstraints {
515 | _ = pin(.width, to: to, attribute: attribute, constant: constant, multiplier: multiplier)
516 | }
517 | return self
518 | }
519 |
520 | /**
521 | Returns the frame height
522 | */
523 | func height() -> CGFloat { return frame.size.height }
524 |
525 | /**
526 | Sets the frame height using Auto Layout or frames
527 |
528 | - Parameter constant: The value to use.
529 | - Returns: self UIView
530 | */
531 | func height(_ constant: CGFloat) -> UIView {
532 | if translatesAutoresizingMaskIntoConstraints {
533 | frame.size.height = constant
534 | } else {
535 | _ = applyAttribute(.height, constant: constant)
536 | }
537 | return self
538 | }
539 |
540 | /**
541 | Pins the height to another view using Auto Layout
542 |
543 | - Parameter to: The view to pin to
544 | - Parameter attribute: The attribute to pin to
545 | - Parameter constant: The offset to use after multiplication is done.
546 | - Parameter multiplier: The multiplier to use, i.e. 0.5 is half.
547 | - Returns: self
548 | */
549 | func height(to:AnyObject, attribute: NSLayoutAttribute = .height, constant: CGFloat = 0, multiplier:CGFloat = 1) -> UIView {
550 | if !translatesAutoresizingMaskIntoConstraints {
551 | _ = pin(.height, to: to, attribute: attribute, constant: constant, multiplier: multiplier)
552 | }
553 | return self
554 | }
555 |
556 | /**
557 | Returns the minimum size using Auto Layout
558 | */
559 | func minSize() -> CGSize? {
560 | if !translatesAutoresizingMaskIntoConstraints {
561 | if let minWidth = minWidth() {
562 | if let minHeight = minHeight() {
563 | return CGSize(width: minWidth, height: minHeight)
564 | }
565 | }
566 | }
567 | return nil
568 | }
569 |
570 | /**
571 | Sets the minimum size using Auto Layout
572 |
573 | - Parameter constant: The value to use.
574 | - Returns: self
575 | */
576 | func minSize(_ constant:CGSize) -> UIView {
577 | if !translatesAutoresizingMaskIntoConstraints {
578 | _ = applyAttribute(.width, constant: constant.width, multiplier: 1, relation: .greaterThanOrEqual)
579 | _ = applyAttribute(.height, constant: constant.height, multiplier: 1, relation: .greaterThanOrEqual)
580 | }
581 | return self
582 | }
583 |
584 | /**
585 | Pins the minimum size to another view using Auto Layout
586 |
587 | - Parameter to: The view to pin to
588 | - Parameter constant: The offset to use after multiplication is done.
589 | - Parameter multiplier: The multiplier to use, i.e. 0.5 is half.
590 | - Returns: self
591 | */
592 | func minSize(to:AnyObject, constant:CGSize = CGSize(width: 0, height: 0), multiplier:CGFloat = 1) -> UIView {
593 | if !translatesAutoresizingMaskIntoConstraints {
594 | var constraints = [NSLayoutConstraint]()
595 | if let width = pin(.width, to: to, attribute: .width, constant: constant.width, multiplier: multiplier, relation: .greaterThanOrEqual) {
596 | constraints.append(width)
597 | }
598 | if let height = pin(.width, to: to, attribute: .height, constant: constant.height, multiplier: multiplier, relation: .greaterThanOrEqual) {
599 | constraints.append(height)
600 | }
601 | }
602 | return self
603 | }
604 |
605 | /**
606 | Returns the minimum width using Auto Layout
607 | */
608 | func minWidth() -> CGFloat? {
609 | if !translatesAutoresizingMaskIntoConstraints {
610 | for constrain in constraints {
611 | if constrain.firstAttribute == .width && constrain.firstItem as! NSObject == self && constrain.secondItem == nil && constrain.relation == .greaterThanOrEqual {
612 | return constrain.constant
613 | }
614 | }
615 | }
616 | return nil
617 | }
618 |
619 | /**
620 | Sets the minimum width using Auto Layout
621 |
622 | - Parameter constant: The value to use.
623 | - Returns: self
624 | */
625 | func minWidth(_ constant:CGFloat) -> UIView {
626 | if !translatesAutoresizingMaskIntoConstraints {
627 | _ = applyAttribute(.width, constant: constant, multiplier: 1, relation: .greaterThanOrEqual)
628 | }
629 | return self
630 | }
631 |
632 | /**
633 | Pins the minimum width to another view using Auto Layout
634 |
635 | - Parameter to: The view to pin to
636 | - Parameter attribute: The attribute to pin to
637 | - Parameter constant: The offset to use after multiplication is done.
638 | - Parameter multiplier: The multiplier to use, i.e. 0.5 is half.
639 | - Returns: self
640 | */
641 | func minWidth(to:AnyObject, attribute: NSLayoutAttribute = .width, constant:CGFloat = 0, multiplier:CGFloat = 1) -> UIView {
642 | if !translatesAutoresizingMaskIntoConstraints {
643 | _ = pin(.width, to: to, attribute: attribute, constant: constant, multiplier: multiplier, relation: .greaterThanOrEqual)
644 | }
645 | return self
646 | }
647 |
648 | /**
649 | Returns the minimum height using Auto Layout
650 | */
651 | func minHeight() -> CGFloat? {
652 | if !translatesAutoresizingMaskIntoConstraints {
653 | for constrain in constraints {
654 | if constrain.firstAttribute == .height && constrain.firstItem as! NSObject == self && constrain.secondItem == nil && constrain.relation == .greaterThanOrEqual {
655 | return constrain.constant
656 | }
657 | }
658 | }
659 | return nil
660 | }
661 |
662 | /**
663 | Sets the minimum height using Auto Layout
664 |
665 | - Parameter constant: The value to use.
666 | - Returns: self
667 | */
668 | func minHeight(_ constant:CGFloat) -> UIView {
669 | if !translatesAutoresizingMaskIntoConstraints {
670 | _ = applyAttribute(.height, constant: constant, multiplier: 1, relation: .greaterThanOrEqual)
671 | }
672 | return self
673 | }
674 |
675 | /**
676 | Pins the minimum height to another view using Auto Layout
677 |
678 | - Parameter to: The view to pin to
679 | - Parameter attribute: The attribute to pin to
680 | - Parameter constant: The offset to use after multiplication is done.
681 | - Parameter multiplier: The multiplier to use, i.e. 0.5 is half.
682 | - Returns: self
683 | */
684 | func minHeight(to:AnyObject, attribute: NSLayoutAttribute = .height, constant:CGFloat = 0, multiplier:CGFloat = 1) -> UIView {
685 | if !translatesAutoresizingMaskIntoConstraints {
686 | _ = pin(.height, to: to, attribute: attribute, constant: constant, multiplier: multiplier, relation: .greaterThanOrEqual)
687 | }
688 | return self
689 | }
690 |
691 | /**
692 | Returns the maximun size using Auto Layout
693 | */
694 | func maxSize() -> CGSize? {
695 | if !translatesAutoresizingMaskIntoConstraints {
696 | if let maxWidth = maxWidth() {
697 | if let maxHeight = maxHeight() {
698 | return CGSize(width: maxWidth, height: maxHeight)
699 | }
700 | }
701 | }
702 | return nil
703 | }
704 |
705 | /**
706 | Sets the maximun size using Auto Layout
707 |
708 | - Parameter constant: The value to use.
709 | - Returns: self
710 | */
711 | func maxSize(_ constant:CGSize) -> UIView {
712 | if !translatesAutoresizingMaskIntoConstraints {
713 | _ = applyAttribute(.width, constant: constant.width, multiplier: 1, relation: .lessThanOrEqual)
714 | _ = applyAttribute(.height, constant: constant.height, multiplier: 1, relation: .lessThanOrEqual)
715 | }
716 | return self
717 | }
718 |
719 | /**
720 | Pins the maximun size to another view using Auto Layout
721 |
722 | - Parameter to: The view to pin to
723 | - Parameter constant: The offset to use after multiplication is done.
724 | - Parameter multiplier: The multiplier to use, i.e. 0.5 is half.
725 | - Returns: self
726 | */
727 | func maxSize(to:AnyObject, constant:CGSize = CGSize(width: 0, height: 0), multiplier:CGFloat = 1) -> UIView {
728 | if !translatesAutoresizingMaskIntoConstraints {
729 | var constraints = [NSLayoutConstraint]()
730 | if let width = pin(.width, to: to, attribute: .width, constant: constant.width, multiplier: multiplier, relation: .lessThanOrEqual) {
731 | constraints.append(width)
732 | }
733 | if let height = pin(.width, to: to, attribute: .height, constant: constant.height, multiplier: multiplier, relation: .lessThanOrEqual) {
734 | constraints.append(height)
735 | }
736 | }
737 | return self
738 | }
739 |
740 | /**
741 | Returns the maximun width using Auto Layout
742 | */
743 | func maxWidth() -> CGFloat? {
744 | if !translatesAutoresizingMaskIntoConstraints {
745 | for constrain in constraints {
746 | if constrain.firstAttribute == .width && constrain.firstItem as! NSObject == self && constrain.secondItem == nil && constrain.relation == .lessThanOrEqual {
747 | return constrain.constant
748 | }
749 | }
750 | }
751 | return nil
752 | }
753 |
754 | /**
755 | Sets the maximun width using Auto Layout
756 |
757 | - Parameter constant: The value to use.
758 | - Returns: self
759 | */
760 | func maxWidth(_ constant:CGFloat) -> UIView {
761 | if !translatesAutoresizingMaskIntoConstraints {
762 | _ = applyAttribute(.width, constant: constant, multiplier: 1, relation: .lessThanOrEqual)
763 | }
764 | return self
765 | }
766 |
767 | /**
768 | Pins the maximun width to another view using Auto Layout
769 |
770 | - Parameter to: The view to pin to
771 | - Parameter attribute: The attribute to pin to
772 | - Parameter constant: The offset to use after multiplication is done.
773 | - Parameter multiplier: The multiplier to use, i.e. 0.5 is half.
774 | - Returns: self
775 | */
776 | func maxWidth(to:AnyObject, attribute: NSLayoutAttribute = .width, constant:CGFloat = 0, multiplier:CGFloat = 1) -> UIView {
777 | if !translatesAutoresizingMaskIntoConstraints {
778 | _ = pin(.width, to: to, attribute: attribute, constant: constant, multiplier: multiplier, relation: .lessThanOrEqual)
779 | }
780 | return self
781 | }
782 |
783 | /**
784 | Returns the maximun height using Auto Layout
785 | */
786 | func maxHeight() -> CGFloat? {
787 | if !translatesAutoresizingMaskIntoConstraints {
788 | for constrain in constraints {
789 | if constrain.firstAttribute == .height && constrain.firstItem as! NSObject == self && constrain.secondItem == nil && constrain.relation == .lessThanOrEqual {
790 | return constrain.constant
791 | }
792 | }
793 | }
794 | return nil
795 | }
796 |
797 | /**
798 | Sets the maximun height using Auto Layout
799 |
800 | - Parameter constant: The value to use.
801 | - Returns: self
802 | */
803 | func maxHeight(_ constant:CGFloat) -> UIView {
804 | if !translatesAutoresizingMaskIntoConstraints {
805 | _ = applyAttribute(.height, constant: constant, multiplier: 1, relation: .lessThanOrEqual)
806 | }
807 | return self
808 | }
809 |
810 | /**
811 | Pins the maximun height to another view using Auto Layout
812 |
813 | - Parameter to: The view to pin to
814 | - Parameter attribute: The attribute to pin to
815 | - Parameter constant: The offset to use after multiplication is done.
816 | - Parameter multiplier: The multiplier to use, i.e. 0.5 is half.
817 | - Returns: self
818 | */
819 | func maxHeight(to:AnyObject, attribute: NSLayoutAttribute = .height, constant:CGFloat = 0, multiplier:CGFloat = 1) -> UIView {
820 | if !translatesAutoresizingMaskIntoConstraints {
821 | _ = pin(.height, to: to, attribute: attribute, constant: constant, multiplier: multiplier, relation: .lessThanOrEqual)
822 | }
823 | return self
824 | }
825 |
826 | /**
827 | Returns the length of the smallest side
828 | */
829 | func smallestSideLength() -> CGFloat
830 | {
831 | return min(width(), height())
832 | }
833 |
834 | /**
835 | Returns the length of the largest side
836 | */
837 | func largestSideLength() -> CGFloat
838 | {
839 | return max(width(), height())
840 | }
841 |
842 |
843 | // MARK: AutoLayout state
844 |
845 | /**
846 | Prepares the view for a frame based animation by removing the view, enabling translatesAutoresizingMaskIntoConstraints and re-adding the view to it's superview
847 | */
848 | func prepForAnimation()
849 | {
850 | if superview != nil {
851 | let aSuperview = superview!
852 | removeFromSuperview()
853 | translatesAutoresizingMaskIntoConstraints = true
854 | aSuperview.addSubview(self)
855 | }
856 | }
857 |
858 | /**
859 | Prepares the view for Auto Layout by removing the view, disabling translatesAutoresizingMaskIntoConstraints and re-adding the view to it's superview
860 | */
861 | func prepForAutoLayout()
862 | {
863 | if superview != nil {
864 | let aSuperview = superview!
865 | removeFromSuperview()
866 | translatesAutoresizingMaskIntoConstraints = false
867 | aSuperview.addSubview(self)
868 | }
869 | }
870 |
871 |
872 | // MARK: Pin and Apply
873 |
874 | /**
875 | Pins an attribute to another view
876 |
877 | - Parameter pinAttribute: The View's attribut to pin
878 | - Parameter to: The view to pin to
879 | - Parameter attribute: The Attribute to pin to
880 | - Parameter constant: The offset to use after multiplication is done.
881 | - Parameter multiplier: The multiplier to use, i.e. 0.5 is half.
882 | - Parameter relation: The Relation to use
883 | - Returns: NSLayoutConstraint
884 | */
885 | func pin(_ pinAttribute:NSLayoutAttribute, to:AnyObject? = nil, attribute:NSLayoutAttribute, constant:CGFloat = 0, multiplier:CGFloat = 1, relation:NSLayoutRelation = .equal) -> NSLayoutConstraint? {
886 | if !translatesAutoresizingMaskIntoConstraints {
887 | if self.superview == nil {
888 | print("WARNING: No superview found for pinning")
889 | return nil
890 | }
891 | var superview: UIView!
892 | if (to != nil) {
893 | superview = to is UIView ? commonSuperviewWithView(to! as! UIView)! : self.superview
894 | } else {
895 | superview = self.superview
896 | }
897 | let constraint = NSLayoutConstraint(item: self, attribute: pinAttribute, relatedBy: relation, toItem: to, attribute: attribute, multiplier: multiplier, constant: constant)
898 | superview?.addConstraint(constraint)
899 | return constraint
900 | }
901 | return nil
902 | }
903 |
904 | /**
905 | Applies an attribute to the view
906 |
907 | - Parameter attribute: Attribute to apply
908 | - Parameter constant: The offset to use after multiplication is done.
909 | - Parameter multiplier: The multiplier to use, i.e. 0.5 is half.
910 | - Parameter relation: The Relation to use
911 | - Returns: NSLayoutConstraint
912 | */
913 | func applyAttribute(_ attribute:NSLayoutAttribute, constant:CGFloat = 0, multiplier: CGFloat = 1, relation:NSLayoutRelation = .equal) -> NSLayoutConstraint {
914 | let constraint = NSLayoutConstraint(item: self, attribute: attribute, relatedBy: relation, toItem: nil, attribute: .notAnAttribute, multiplier: multiplier, constant: constant)
915 | addConstraint(constraint)
916 | return constraint
917 | }
918 |
919 | // MARK: Removing Constraints
920 |
921 | /**
922 | Removes all attached constraints recursevely
923 |
924 | - Returns: self
925 | */
926 | func removeAttachedConstraintsRecursevely() -> UIView
927 | {
928 | for constraint in constraints {
929 | print("constraint \(constraint)")
930 | _ = removeConstraintRecursevely(constraint )
931 | }
932 | for constraint in superview!.constraints {
933 | let firstView = constraint.firstItem as! UIView
934 | if let _ = constraint.secondItem as? UIView {
935 | if firstView == self {
936 | _ = firstView.removeConstraintRecursevely(constraint )
937 | }
938 | }
939 | }
940 | return self
941 | }
942 |
943 | /**
944 | Removes a constraint recursevely
945 |
946 | - Returns: self
947 | */
948 | func removeConstraintRecursevely(_ constraint:NSLayoutConstraint) -> UIView
949 | {
950 | let firstView = constraint.firstItem as! UIView
951 | if constraint.secondItem != nil {
952 | var commonSuperview = firstView.commonSuperviewWithView(constraint.secondItem as! UIView)
953 | var constraintFound = false
954 | while constraintFound == false {
955 | for _ in commonSuperview!.constraints {
956 | constraintFound = true
957 | }
958 | if constraintFound == true {
959 | commonSuperview!.removeConstraint(constraint)
960 | return self
961 | }
962 | commonSuperview = commonSuperview?.superview
963 | }
964 | } else {
965 | constraint.firstItem.removeConstraint(constraint)
966 | }
967 | return self
968 | }
969 |
970 |
971 | // MARK: Direction
972 |
973 | /**
974 | Returns true if layout direction is left to right
975 | */
976 | func layoutDirectionIsLeftToRight() -> Bool {
977 | if #available(iOS 10.0, *) {
978 | return (self.effectiveUserInterfaceLayoutDirection == UIUserInterfaceLayoutDirection.leftToRight)
979 | } else {
980 | // TODO: Figure out how to implemet this in IOS9. For now, we wil force left to right layout
981 | return true
982 | }
983 | }
984 |
985 |
986 |
987 | // MARK: Private
988 |
989 | /**
990 | Finds the nearest common superview
991 |
992 | - Returns: UIVIew?
993 | */
994 | fileprivate func commonSuperviewWithView(_ view:UIView) -> UIView?
995 | {
996 | var commonSuperview: UIView? = nil
997 | var checkView: UIView? = self
998 | repeat {
999 | if view.isDescendant(of: checkView!) {
1000 | commonSuperview = checkView!
1001 | }
1002 | checkView = checkView!.superview
1003 | } while (checkView) != nil
1004 | return commonSuperview
1005 | }
1006 |
1007 | }
1008 |
--------------------------------------------------------------------------------
/Sources/ViewControllerAutoLayout.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewControllerAutoLayout.swift
3 | // ViewHelper: Version 4.2.4
4 | // Created by Melvin Rivera on 11/5/15.
5 | // https://github.com/melvitax/ViewHelper
6 | //
7 |
8 | import Foundation
9 | import UIKit
10 |
11 | public extension UIViewController {
12 |
13 |
14 | /**
15 | Returns true if horizontal size class is compact
16 | */
17 | func horizontalSizeClassIsCompact() -> Bool
18 | {
19 | return traitCollection.horizontalSizeClass == .compact;
20 | }
21 |
22 | /**
23 | Returns true if vertical size class is compact
24 | */
25 | func verticalSizeClassIsCompact() -> Bool
26 | {
27 | return traitCollection.verticalSizeClass == .compact;
28 | }
29 |
30 | }
31 |
32 |
--------------------------------------------------------------------------------
/Sources/ViewEffects.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewEffects.swift
3 | // ViewHelper: Version 4.2.4
4 | // Created by Melvin Rivera on 7/2/14.
5 | // https://github.com/melvitax/ViewHelper
6 | //
7 |
8 | import UIKit
9 | import QuartzCore
10 |
11 |
12 |
13 | @IBDesignable public extension UIView {
14 |
15 | // MARK: Border
16 |
17 | /**
18 | The layer border color
19 | */
20 | var borderColor: UIColor {
21 | get {
22 | return layer.borderColor == nil ? UIColor.clear : UIColor(cgColor: layer.borderColor!)
23 | }
24 | set {
25 | layer.borderColor = newValue.cgColor
26 | }
27 | }
28 |
29 | /**
30 | The layer border width
31 | */
32 | var borderWidth: CGFloat {
33 | get {
34 | return layer.borderWidth
35 | }
36 | set {
37 | layer.borderWidth = newValue
38 | }
39 | }
40 |
41 |
42 | /**
43 | Sets layer border with a dash pattern
44 |
45 | - Parameter lineDashPattern: The dash pattern applied to the shape’s path when stroked.
46 | - Parameter borderWidth: The width of the border.
47 | - Parameter borderColor: The color of the border.
48 | - Parameter cornerRadius: The radius of each corner oval.
49 | - Returns: self
50 | */
51 | func borderWithDashPattern(_ lineDashPattern: [Int], borderWidth: CGFloat, borderColor: UIColor, cornerRadius: CGFloat?) -> UIView {
52 | let strokeLayer = CAShapeLayer()
53 | strokeLayer.strokeColor = borderColor.cgColor
54 | strokeLayer.fillColor = nil
55 | strokeLayer.lineWidth = borderWidth
56 | strokeLayer.lineDashPattern = lineDashPattern as [NSNumber]?
57 | if cornerRadius != nil {
58 | strokeLayer.path = UIBezierPath(roundedRect: bounds, cornerRadius: cornerRadius!).cgPath
59 | } else {
60 | strokeLayer.path = UIBezierPath(roundedRect: bounds, cornerRadius: self.cornerRadius).cgPath
61 | }
62 |
63 | strokeLayer.frame = bounds
64 | layer.addSublayer(strokeLayer)
65 | return self
66 | }
67 |
68 |
69 | // MARK: Rounded Corners
70 |
71 | /**
72 | The layer corner radius
73 | */
74 | var cornerRadius: CGFloat {
75 | get {
76 | return layer.cornerRadius
77 | }
78 | set {
79 | layer.cornerRadius = newValue
80 | layer.masksToBounds = newValue > 0
81 | }
82 | }
83 |
84 | /**
85 | Creates a circle by rounding the corners to half the size of the width, sets border color and width
86 |
87 | - Parameter borderColor: The border color.
88 | - Parameter borderWidth: The border width.
89 | - Returns: self
90 | */
91 | func roundCornersToCircle(borderColor: UIColor = UIColor.clear, borderWidth: CGFloat = 0) -> UIView {
92 | cornerRadius = width()/2
93 | self.borderWidth = borderWidth
94 | self.borderColor = borderColor
95 | return self
96 | }
97 |
98 | /**
99 | Rounding the corners, sets border color and width
100 |
101 | - Parameter cornerRadius: The radius of each corner oval.
102 | - Parameter borderColor: The border color.
103 | - Parameter borderWidth: The border width.
104 | - Returns: self
105 | */
106 | func roundCorners(_ cornerRadius: CGFloat, borderColor: UIColor?, borderWidth: CGFloat?) -> UIView {
107 | self.cornerRadius = cornerRadius
108 | if borderWidth != nil {
109 | self.borderWidth = borderWidth!
110 | }
111 | if borderColor != nil {
112 | self.borderColor = borderColor!
113 | }
114 | return self
115 | }
116 |
117 |
118 | // MARK: Shadow
119 |
120 | /**
121 | The shadow color of the layer
122 | */
123 | var shadowColor: UIColor {
124 | get {
125 | return layer.shadowColor == nil ? UIColor.clear : UIColor(cgColor: layer.shadowColor!)
126 | }
127 | set {
128 | layer.shadowColor = newValue.cgColor
129 | }
130 | }
131 |
132 |
133 | /**
134 | The offset (in points) of the layer’s shadow.
135 | */
136 | var shadowOffset:CGSize {
137 | get {
138 | return layer.shadowOffset
139 | }
140 | set {
141 | layer.shadowOffset = newValue
142 | }
143 | }
144 |
145 | /**
146 | The shadow opacity of the layer
147 | */
148 | var shadowOpacity:Float {
149 | get {
150 | return layer.shadowOpacity
151 | }
152 | set {
153 | layer.shadowOpacity = newValue
154 | }
155 | }
156 |
157 | /**
158 | The blur radius (in points) used to render the layer’s shadow.
159 | */
160 | var shadowRadius:CGFloat {
161 | get {
162 | return layer.shadowRadius
163 | }
164 | set {
165 | layer.shadowRadius = newValue
166 | }
167 | }
168 |
169 | /**
170 | Shortcut for applying shadow.
171 |
172 | - Parameter color: The shadow color.
173 | - Parameter offset: The offset (in points) of the layer’s shadow.
174 | - Parameter radius: The blur radius (in points) used to render the layer’s shadow.
175 | - Parameter opacity: The shadow opacity.
176 | - Parameter isMasked: Indicates if it should be masked.
177 | - Returns: self UIView
178 | */
179 | func shadow(_ color: UIColor = UIColor.black, offset: CGSize = CGSize(width: 0, height: 0), radius: CGFloat = 6, opacity: Float = 1, isMasked: Bool = false) -> UIView {
180 | shadowColor = color
181 | shadowOffset = offset
182 | shadowOpacity = opacity
183 | shadowRadius = radius
184 | if isMasked {
185 | layer.shadowPath = UIBezierPath(roundedRect: bounds, cornerRadius: radius).cgPath
186 | let path = CGMutablePath()
187 | path.addRect(bounds.insetBy(dx: -10, dy: -10))
188 | path.addPath(UIBezierPath(roundedRect: bounds, cornerRadius: radius).cgPath)
189 | let maskLayer = CAShapeLayer()
190 | maskLayer.path = path
191 | maskLayer.fillRule = kCAFillRuleEvenOdd
192 | layer.mask = maskLayer
193 | }
194 | return self
195 | }
196 |
197 | // MARK: Gradient
198 |
199 | /**
200 | Sets a gradient color layer
201 |
202 | - Parameter colors: Array of colors to use in gradient.
203 | - Parameter isHorizontal: Indicates if gradient is horizontal instead of vertical.
204 | - Returns: self
205 | */
206 | func setGradient(_ colors: [UIColor], isHorizontal:Bool = false) -> UIView {
207 | let gradientLayer = layer as! CAGradientLayer
208 | gradientLayer.startPoint = isHorizontal ? CGPoint(x: 0.5, y: 0) : CGPoint(x: 0.5, y: 1)
209 | gradientLayer.startPoint = isHorizontal ? CGPoint(x: 0.5, y: 1) : CGPoint(x: 1, y: 0.5)
210 | gradientLayer.colors = colors
211 | return self
212 | }
213 |
214 | /**
215 | Animates colors of a gradient layer
216 |
217 | - Parameter colors: Array of colors to use in gradient.
218 | - Parameter duration: Duration os animation
219 | - Returns: self
220 | */
221 | func animateGradientToColors(_ colors: [UIColor], duration: CFTimeInterval = 3) -> UIView {
222 | let gradientLayer = layer as! CAGradientLayer
223 | let fromColors = gradientLayer.colors
224 | gradientLayer.colors = colors
225 | let a = CABasicAnimation(keyPath: "colors")
226 | a.fromValue = fromColors
227 | a.toValue = colors
228 | a.duration = duration
229 | a.isRemovedOnCompletion = true
230 | a.fillMode = kCAFillModeForwards
231 | a.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
232 | //a.delegate = self
233 | layer.add(a, forKey: "Gradient Animation")
234 | return self
235 | }
236 |
237 | /**
238 | Sets a gradient layer mask
239 |
240 | - Parameter alphas: Array of alpha values to use for gradient mask.
241 | - Parameter isHorizontal: Indicates if gradient is horizontal instead of vertical.
242 | - Returns: self
243 | */
244 | func setGradientMask(_ alphas:[CGFloat], isHorizontal:Bool = false) -> UIView {
245 | let gradientLayer = (layer.mask is CAGradientLayer) ? layer.mask as! CAGradientLayer : CAGradientLayer()
246 | var colors = [CGColor]()
247 | for alpha in alphas {
248 | colors.append(UIColor(white: 1, alpha: alpha).cgColor)
249 | }
250 | gradientLayer.startPoint = isHorizontal ? CGPoint(x: 1, y: 0.5) : CGPoint(x: 0.5, y: 1)
251 | gradientLayer.startPoint = isHorizontal ? CGPoint(x: 0, y: 0.5) : CGPoint(x: 0.5, y: 0)
252 | gradientLayer.colors = colors
253 | layer.mask = gradientLayer
254 | return self
255 | }
256 |
257 |
258 |
259 | }
260 |
--------------------------------------------------------------------------------
/Sources/ViewHelper.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewHelper iOS.h
3 | // ViewHelper iOS
4 | //
5 | // Created by Melvin Rivera on 9/16/16.
6 | // Copyright © 2016 All Forces. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | //! Project version number for ViewHelper iOS.
12 | FOUNDATION_EXPORT double ViewHelperVersionNumber;
13 |
14 | //! Project version string for ViewHelper iOS.
15 | FOUNDATION_EXPORT const unsigned char ViewHelperVersionString[];
16 |
17 | // In this header, you should import all the public headers of your framework using statements like #import
18 |
19 |
20 |
--------------------------------------------------------------------------------
/ViewHelper.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 6588DCCB1DE971EB00575329 /* TableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6588DCCA1DE971EB00575329 /* TableViewController.swift */; };
11 | 658FE8F01D92FA0D00CB92F3 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 658FE8EF1D92FA0D00CB92F3 /* ViewController.swift */; };
12 | 65D6FA911D8C6874004BAB04 /* ViewHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 65D6FA8F1D8C6802004BAB04 /* ViewHelper.h */; settings = {ATTRIBUTES = (Public, ); }; };
13 | 65D6FA931D8C6876004BAB04 /* ViewHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 65D6FA8F1D8C6802004BAB04 /* ViewHelper.h */; settings = {ATTRIBUTES = (Public, ); }; };
14 | 65D6FA941D8C689E004BAB04 /* InspectableButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65D6FA4C1D8C66A0004BAB04 /* InspectableButton.swift */; };
15 | 65D6FA951D8C689E004BAB04 /* InspectableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65D6FA4D1D8C66A0004BAB04 /* InspectableView.swift */; };
16 | 65D6FA961D8C689E004BAB04 /* ViewAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65D6FA4E1D8C66A0004BAB04 /* ViewAnimation.swift */; };
17 | 65D6FA971D8C689E004BAB04 /* ViewAutoLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65D6FA4F1D8C66A0004BAB04 /* ViewAutoLayout.swift */; };
18 | 65D6FA981D8C689E004BAB04 /* ViewControllerAutoLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65D6FA501D8C66A0004BAB04 /* ViewControllerAutoLayout.swift */; };
19 | 65D6FA991D8C689E004BAB04 /* ViewEffects.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65D6FA511D8C66A0004BAB04 /* ViewEffects.swift */; };
20 | 65D6FAA01D8C68A0004BAB04 /* InspectableButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65D6FA4C1D8C66A0004BAB04 /* InspectableButton.swift */; };
21 | 65D6FAA11D8C68A0004BAB04 /* InspectableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65D6FA4D1D8C66A0004BAB04 /* InspectableView.swift */; };
22 | 65D6FAA21D8C68A0004BAB04 /* ViewAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65D6FA4E1D8C66A0004BAB04 /* ViewAnimation.swift */; };
23 | 65D6FAA31D8C68A0004BAB04 /* ViewAutoLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65D6FA4F1D8C66A0004BAB04 /* ViewAutoLayout.swift */; };
24 | 65D6FAA41D8C68A0004BAB04 /* ViewControllerAutoLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65D6FA501D8C66A0004BAB04 /* ViewControllerAutoLayout.swift */; };
25 | 65D6FAA51D8C68A0004BAB04 /* ViewEffects.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65D6FA511D8C66A0004BAB04 /* ViewEffects.swift */; };
26 | 65D6FAAD1D8C68CF004BAB04 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65D6FAAC1D8C68CF004BAB04 /* AppDelegate.swift */; };
27 | 65D6FAB41D8C68CF004BAB04 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 65D6FAB31D8C68CF004BAB04 /* Assets.xcassets */; };
28 | 65D6FAB71D8C68CF004BAB04 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 65D6FAB51D8C68CF004BAB04 /* LaunchScreen.storyboard */; };
29 | 65D6FABC1D8C69BF004BAB04 /* InspectableButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65D6FA4C1D8C66A0004BAB04 /* InspectableButton.swift */; };
30 | 65D6FABD1D8C69BF004BAB04 /* InspectableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65D6FA4D1D8C66A0004BAB04 /* InspectableView.swift */; };
31 | 65D6FABE1D8C69BF004BAB04 /* ViewAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65D6FA4E1D8C66A0004BAB04 /* ViewAnimation.swift */; };
32 | 65D6FABF1D8C69BF004BAB04 /* ViewAutoLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65D6FA4F1D8C66A0004BAB04 /* ViewAutoLayout.swift */; };
33 | 65D6FAC01D8C69BF004BAB04 /* ViewControllerAutoLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65D6FA501D8C66A0004BAB04 /* ViewControllerAutoLayout.swift */; };
34 | 65D6FAC11D8C69BF004BAB04 /* ViewEffects.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65D6FA511D8C66A0004BAB04 /* ViewEffects.swift */; };
35 | 65D6FAC91D8C6C3E004BAB04 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65D6FAC81D8C6C3E004BAB04 /* AppDelegate.swift */; };
36 | 65D6FACE1D8C6C3E004BAB04 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 65D6FACC1D8C6C3E004BAB04 /* Main.storyboard */; };
37 | 65D6FAD01D8C6C3E004BAB04 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 65D6FACF1D8C6C3E004BAB04 /* Assets.xcassets */; };
38 | 65D6FAD61D8C73BD004BAB04 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 65D6FAD51D8C73BD004BAB04 /* Main.storyboard */; };
39 | 65D6FAD91D8C76A9004BAB04 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65D6FACA1D8C6C3E004BAB04 /* ViewController.swift */; };
40 | 65D6FADA1D8C7CDB004BAB04 /* InspectableButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65D6FA4C1D8C66A0004BAB04 /* InspectableButton.swift */; };
41 | 65D6FADB1D8C7CDB004BAB04 /* InspectableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65D6FA4D1D8C66A0004BAB04 /* InspectableView.swift */; };
42 | 65D6FADC1D8C7CDB004BAB04 /* ViewAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65D6FA4E1D8C66A0004BAB04 /* ViewAnimation.swift */; };
43 | 65D6FADD1D8C7CDB004BAB04 /* ViewAutoLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65D6FA4F1D8C66A0004BAB04 /* ViewAutoLayout.swift */; };
44 | 65D6FADE1D8C7CDB004BAB04 /* ViewControllerAutoLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65D6FA501D8C66A0004BAB04 /* ViewControllerAutoLayout.swift */; };
45 | 65D6FADF1D8C7CDB004BAB04 /* ViewEffects.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65D6FA511D8C66A0004BAB04 /* ViewEffects.swift */; };
46 | /* End PBXBuildFile section */
47 |
48 | /* Begin PBXFileReference section */
49 | 655AEB42192D42990053AD6C /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
50 | 655AEB44192D42990053AD6C /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
51 | 655AEB46192D42990053AD6C /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
52 | 655AEB64192D429A0053AD6C /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
53 | 6588DCCA1DE971EB00575329 /* TableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TableViewController.swift; sourceTree = ""; };
54 | 658FE8EF1D92FA0D00CB92F3 /* ViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
55 | 65B7EA75197082AA0097E598 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; };
56 | 65D016A319771FD1005220FB /* AFViewHelper.podspec */ = {isa = PBXFileReference; lastKnownFileType = text; path = AFViewHelper.podspec; sourceTree = ""; };
57 | 65D6FA4C1D8C66A0004BAB04 /* InspectableButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InspectableButton.swift; sourceTree = ""; };
58 | 65D6FA4D1D8C66A0004BAB04 /* InspectableView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InspectableView.swift; sourceTree = ""; };
59 | 65D6FA4E1D8C66A0004BAB04 /* ViewAnimation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewAnimation.swift; sourceTree = ""; };
60 | 65D6FA4F1D8C66A0004BAB04 /* ViewAutoLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewAutoLayout.swift; sourceTree = ""; };
61 | 65D6FA501D8C66A0004BAB04 /* ViewControllerAutoLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewControllerAutoLayout.swift; sourceTree = ""; };
62 | 65D6FA511D8C66A0004BAB04 /* ViewEffects.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewEffects.swift; sourceTree = ""; };
63 | 65D6FA6A1D8C673E004BAB04 /* ViewHelper.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ViewHelper.framework; sourceTree = BUILT_PRODUCTS_DIR; };
64 | 65D6FA841D8C675E004BAB04 /* ViewHelper.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ViewHelper.framework; sourceTree = BUILT_PRODUCTS_DIR; };
65 | 65D6FA8C1D8C6802004BAB04 /* Info-iOS.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Info-iOS.plist"; sourceTree = ""; };
66 | 65D6FA8D1D8C6802004BAB04 /* Info-tvOS.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Info-tvOS.plist"; sourceTree = ""; };
67 | 65D6FA8F1D8C6802004BAB04 /* ViewHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewHelper.h; sourceTree = ""; };
68 | 65D6FAAA1D8C68CF004BAB04 /* ViewHelperDemo iOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "ViewHelperDemo iOS.app"; sourceTree = BUILT_PRODUCTS_DIR; };
69 | 65D6FAAC1D8C68CF004BAB04 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
70 | 65D6FAB31D8C68CF004BAB04 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
71 | 65D6FAB61D8C68CF004BAB04 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
72 | 65D6FAB81D8C68CF004BAB04 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
73 | 65D6FAC61D8C6C3E004BAB04 /* ViewHelperDemo tvOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "ViewHelperDemo tvOS.app"; sourceTree = BUILT_PRODUCTS_DIR; };
74 | 65D6FAC81D8C6C3E004BAB04 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
75 | 65D6FACA1D8C6C3E004BAB04 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
76 | 65D6FACD1D8C6C3E004BAB04 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
77 | 65D6FACF1D8C6C3E004BAB04 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
78 | 65D6FAD11D8C6C3E004BAB04 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
79 | 65D6FAD51D8C73BD004BAB04 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = ""; };
80 | /* End PBXFileReference section */
81 |
82 | /* Begin PBXFrameworksBuildPhase section */
83 | 65D6FA661D8C673E004BAB04 /* Frameworks */ = {
84 | isa = PBXFrameworksBuildPhase;
85 | buildActionMask = 2147483647;
86 | files = (
87 | );
88 | runOnlyForDeploymentPostprocessing = 0;
89 | };
90 | 65D6FA801D8C675E004BAB04 /* Frameworks */ = {
91 | isa = PBXFrameworksBuildPhase;
92 | buildActionMask = 2147483647;
93 | files = (
94 | );
95 | runOnlyForDeploymentPostprocessing = 0;
96 | };
97 | 65D6FAA71D8C68CF004BAB04 /* Frameworks */ = {
98 | isa = PBXFrameworksBuildPhase;
99 | buildActionMask = 2147483647;
100 | files = (
101 | );
102 | runOnlyForDeploymentPostprocessing = 0;
103 | };
104 | 65D6FAC31D8C6C3E004BAB04 /* Frameworks */ = {
105 | isa = PBXFrameworksBuildPhase;
106 | buildActionMask = 2147483647;
107 | files = (
108 | );
109 | runOnlyForDeploymentPostprocessing = 0;
110 | };
111 | /* End PBXFrameworksBuildPhase section */
112 |
113 | /* Begin PBXGroup section */
114 | 655AEB36192D42990053AD6C = {
115 | isa = PBXGroup;
116 | children = (
117 | 65D6FA4B1D8C66A0004BAB04 /* Sources */,
118 | 65B7EA75197082AA0097E598 /* README.md */,
119 | 65D016A319771FD1005220FB /* AFViewHelper.podspec */,
120 | 65D6FAAB1D8C68CF004BAB04 /* Demo iOS */,
121 | 65D6FAC71D8C6C3E004BAB04 /* Demo tvOS */,
122 | 655AEB41192D42990053AD6C /* Frameworks */,
123 | 655AEB40192D42990053AD6C /* Products */,
124 | );
125 | sourceTree = "";
126 | };
127 | 655AEB40192D42990053AD6C /* Products */ = {
128 | isa = PBXGroup;
129 | children = (
130 | 65D6FA6A1D8C673E004BAB04 /* ViewHelper.framework */,
131 | 65D6FA841D8C675E004BAB04 /* ViewHelper.framework */,
132 | 65D6FAAA1D8C68CF004BAB04 /* ViewHelperDemo iOS.app */,
133 | 65D6FAC61D8C6C3E004BAB04 /* ViewHelperDemo tvOS.app */,
134 | );
135 | name = Products;
136 | sourceTree = "";
137 | };
138 | 655AEB41192D42990053AD6C /* Frameworks */ = {
139 | isa = PBXGroup;
140 | children = (
141 | 655AEB42192D42990053AD6C /* Foundation.framework */,
142 | 655AEB44192D42990053AD6C /* CoreGraphics.framework */,
143 | 655AEB46192D42990053AD6C /* UIKit.framework */,
144 | 655AEB64192D429A0053AD6C /* XCTest.framework */,
145 | );
146 | name = Frameworks;
147 | sourceTree = "";
148 | };
149 | 65D6FA4B1D8C66A0004BAB04 /* Sources */ = {
150 | isa = PBXGroup;
151 | children = (
152 | 65D6FA4C1D8C66A0004BAB04 /* InspectableButton.swift */,
153 | 65D6FA4D1D8C66A0004BAB04 /* InspectableView.swift */,
154 | 65D6FA4E1D8C66A0004BAB04 /* ViewAnimation.swift */,
155 | 65D6FA4F1D8C66A0004BAB04 /* ViewAutoLayout.swift */,
156 | 65D6FA501D8C66A0004BAB04 /* ViewControllerAutoLayout.swift */,
157 | 65D6FA511D8C66A0004BAB04 /* ViewEffects.swift */,
158 | 65D6FA8C1D8C6802004BAB04 /* Info-iOS.plist */,
159 | 65D6FA8D1D8C6802004BAB04 /* Info-tvOS.plist */,
160 | 65D6FA8F1D8C6802004BAB04 /* ViewHelper.h */,
161 | );
162 | path = Sources;
163 | sourceTree = "";
164 | };
165 | 65D6FAAB1D8C68CF004BAB04 /* Demo iOS */ = {
166 | isa = PBXGroup;
167 | children = (
168 | 65D6FAAC1D8C68CF004BAB04 /* AppDelegate.swift */,
169 | 658FE8EF1D92FA0D00CB92F3 /* ViewController.swift */,
170 | 65D6FAB31D8C68CF004BAB04 /* Assets.xcassets */,
171 | 65D6FAD51D8C73BD004BAB04 /* Main.storyboard */,
172 | 65D6FAB51D8C68CF004BAB04 /* LaunchScreen.storyboard */,
173 | 65D6FAB81D8C68CF004BAB04 /* Info.plist */,
174 | );
175 | name = "Demo iOS";
176 | path = "ViewHelperDemo iOS";
177 | sourceTree = "";
178 | };
179 | 65D6FAC71D8C6C3E004BAB04 /* Demo tvOS */ = {
180 | isa = PBXGroup;
181 | children = (
182 | 65D6FAC81D8C6C3E004BAB04 /* AppDelegate.swift */,
183 | 65D6FACA1D8C6C3E004BAB04 /* ViewController.swift */,
184 | 6588DCCA1DE971EB00575329 /* TableViewController.swift */,
185 | 65D6FACC1D8C6C3E004BAB04 /* Main.storyboard */,
186 | 65D6FACF1D8C6C3E004BAB04 /* Assets.xcassets */,
187 | 65D6FAD11D8C6C3E004BAB04 /* Info.plist */,
188 | );
189 | name = "Demo tvOS";
190 | path = "ViewHelperDemo tvOS";
191 | sourceTree = "";
192 | };
193 | /* End PBXGroup section */
194 |
195 | /* Begin PBXHeadersBuildPhase section */
196 | 65D6FA671D8C673E004BAB04 /* Headers */ = {
197 | isa = PBXHeadersBuildPhase;
198 | buildActionMask = 2147483647;
199 | files = (
200 | 65D6FA911D8C6874004BAB04 /* ViewHelper.h in Headers */,
201 | );
202 | runOnlyForDeploymentPostprocessing = 0;
203 | };
204 | 65D6FA811D8C675E004BAB04 /* Headers */ = {
205 | isa = PBXHeadersBuildPhase;
206 | buildActionMask = 2147483647;
207 | files = (
208 | 65D6FA931D8C6876004BAB04 /* ViewHelper.h in Headers */,
209 | );
210 | runOnlyForDeploymentPostprocessing = 0;
211 | };
212 | /* End PBXHeadersBuildPhase section */
213 |
214 | /* Begin PBXNativeTarget section */
215 | 65D6FA691D8C673E004BAB04 /* ViewHelper iOS */ = {
216 | isa = PBXNativeTarget;
217 | buildConfigurationList = 65D6FA6F1D8C673E004BAB04 /* Build configuration list for PBXNativeTarget "ViewHelper iOS" */;
218 | buildPhases = (
219 | 65D6FA651D8C673E004BAB04 /* Sources */,
220 | 65D6FA661D8C673E004BAB04 /* Frameworks */,
221 | 65D6FA671D8C673E004BAB04 /* Headers */,
222 | 65D6FA681D8C673E004BAB04 /* Resources */,
223 | );
224 | buildRules = (
225 | );
226 | dependencies = (
227 | );
228 | name = "ViewHelper iOS";
229 | productName = "ViewHelper iOS";
230 | productReference = 65D6FA6A1D8C673E004BAB04 /* ViewHelper.framework */;
231 | productType = "com.apple.product-type.framework";
232 | };
233 | 65D6FA831D8C675E004BAB04 /* ViewHelper tvOS */ = {
234 | isa = PBXNativeTarget;
235 | buildConfigurationList = 65D6FA891D8C675E004BAB04 /* Build configuration list for PBXNativeTarget "ViewHelper tvOS" */;
236 | buildPhases = (
237 | 65D6FA7F1D8C675E004BAB04 /* Sources */,
238 | 65D6FA801D8C675E004BAB04 /* Frameworks */,
239 | 65D6FA811D8C675E004BAB04 /* Headers */,
240 | 65D6FA821D8C675E004BAB04 /* Resources */,
241 | );
242 | buildRules = (
243 | );
244 | dependencies = (
245 | );
246 | name = "ViewHelper tvOS";
247 | productName = "ViewHelper tvOS";
248 | productReference = 65D6FA841D8C675E004BAB04 /* ViewHelper.framework */;
249 | productType = "com.apple.product-type.framework";
250 | };
251 | 65D6FAA91D8C68CF004BAB04 /* ViewHelperDemo iOS */ = {
252 | isa = PBXNativeTarget;
253 | buildConfigurationList = 65D6FAB91D8C68CF004BAB04 /* Build configuration list for PBXNativeTarget "ViewHelperDemo iOS" */;
254 | buildPhases = (
255 | 65D6FAA61D8C68CF004BAB04 /* Sources */,
256 | 65D6FAA71D8C68CF004BAB04 /* Frameworks */,
257 | 65D6FAA81D8C68CF004BAB04 /* Resources */,
258 | );
259 | buildRules = (
260 | );
261 | dependencies = (
262 | );
263 | name = "ViewHelperDemo iOS";
264 | productName = "ViewHelperDemo iOS";
265 | productReference = 65D6FAAA1D8C68CF004BAB04 /* ViewHelperDemo iOS.app */;
266 | productType = "com.apple.product-type.application";
267 | };
268 | 65D6FAC51D8C6C3E004BAB04 /* ViewHelperDemo tvOS */ = {
269 | isa = PBXNativeTarget;
270 | buildConfigurationList = 65D6FAD21D8C6C3E004BAB04 /* Build configuration list for PBXNativeTarget "ViewHelperDemo tvOS" */;
271 | buildPhases = (
272 | 65D6FAC21D8C6C3E004BAB04 /* Sources */,
273 | 65D6FAC31D8C6C3E004BAB04 /* Frameworks */,
274 | 65D6FAC41D8C6C3E004BAB04 /* Resources */,
275 | );
276 | buildRules = (
277 | );
278 | dependencies = (
279 | );
280 | name = "ViewHelperDemo tvOS";
281 | productName = "ViewHelperDemo tvOS";
282 | productReference = 65D6FAC61D8C6C3E004BAB04 /* ViewHelperDemo tvOS.app */;
283 | productType = "com.apple.product-type.application";
284 | };
285 | /* End PBXNativeTarget section */
286 |
287 | /* Begin PBXProject section */
288 | 655AEB37192D42990053AD6C /* Project object */ = {
289 | isa = PBXProject;
290 | attributes = {
291 | LastSwiftMigration = 0700;
292 | LastSwiftUpdateCheck = 0800;
293 | LastUpgradeCheck = 0800;
294 | ORGANIZATIONNAME = "All Forces";
295 | TargetAttributes = {
296 | 65D6FA691D8C673E004BAB04 = {
297 | CreatedOnToolsVersion = 8.0;
298 | ProvisioningStyle = Automatic;
299 | };
300 | 65D6FA831D8C675E004BAB04 = {
301 | CreatedOnToolsVersion = 8.0;
302 | ProvisioningStyle = Automatic;
303 | };
304 | 65D6FAA91D8C68CF004BAB04 = {
305 | CreatedOnToolsVersion = 8.0;
306 | ProvisioningStyle = Automatic;
307 | };
308 | 65D6FAC51D8C6C3E004BAB04 = {
309 | CreatedOnToolsVersion = 8.0;
310 | ProvisioningStyle = Automatic;
311 | };
312 | };
313 | };
314 | buildConfigurationList = 655AEB3A192D42990053AD6C /* Build configuration list for PBXProject "ViewHelper" */;
315 | compatibilityVersion = "Xcode 3.2";
316 | developmentRegion = English;
317 | hasScannedForEncodings = 0;
318 | knownRegions = (
319 | en,
320 | Base,
321 | );
322 | mainGroup = 655AEB36192D42990053AD6C;
323 | productRefGroup = 655AEB40192D42990053AD6C /* Products */;
324 | projectDirPath = "";
325 | projectRoot = "";
326 | targets = (
327 | 65D6FAA91D8C68CF004BAB04 /* ViewHelperDemo iOS */,
328 | 65D6FAC51D8C6C3E004BAB04 /* ViewHelperDemo tvOS */,
329 | 65D6FA691D8C673E004BAB04 /* ViewHelper iOS */,
330 | 65D6FA831D8C675E004BAB04 /* ViewHelper tvOS */,
331 | );
332 | };
333 | /* End PBXProject section */
334 |
335 | /* Begin PBXResourcesBuildPhase section */
336 | 65D6FA681D8C673E004BAB04 /* Resources */ = {
337 | isa = PBXResourcesBuildPhase;
338 | buildActionMask = 2147483647;
339 | files = (
340 | );
341 | runOnlyForDeploymentPostprocessing = 0;
342 | };
343 | 65D6FA821D8C675E004BAB04 /* Resources */ = {
344 | isa = PBXResourcesBuildPhase;
345 | buildActionMask = 2147483647;
346 | files = (
347 | );
348 | runOnlyForDeploymentPostprocessing = 0;
349 | };
350 | 65D6FAA81D8C68CF004BAB04 /* Resources */ = {
351 | isa = PBXResourcesBuildPhase;
352 | buildActionMask = 2147483647;
353 | files = (
354 | 65D6FAD61D8C73BD004BAB04 /* Main.storyboard in Resources */,
355 | 65D6FAB71D8C68CF004BAB04 /* LaunchScreen.storyboard in Resources */,
356 | 65D6FAB41D8C68CF004BAB04 /* Assets.xcassets in Resources */,
357 | );
358 | runOnlyForDeploymentPostprocessing = 0;
359 | };
360 | 65D6FAC41D8C6C3E004BAB04 /* Resources */ = {
361 | isa = PBXResourcesBuildPhase;
362 | buildActionMask = 2147483647;
363 | files = (
364 | 65D6FAD01D8C6C3E004BAB04 /* Assets.xcassets in Resources */,
365 | 65D6FACE1D8C6C3E004BAB04 /* Main.storyboard in Resources */,
366 | );
367 | runOnlyForDeploymentPostprocessing = 0;
368 | };
369 | /* End PBXResourcesBuildPhase section */
370 |
371 | /* Begin PBXSourcesBuildPhase section */
372 | 65D6FA651D8C673E004BAB04 /* Sources */ = {
373 | isa = PBXSourcesBuildPhase;
374 | buildActionMask = 2147483647;
375 | files = (
376 | 65D6FAA21D8C68A0004BAB04 /* ViewAnimation.swift in Sources */,
377 | 65D6FAA11D8C68A0004BAB04 /* InspectableView.swift in Sources */,
378 | 65D6FAA41D8C68A0004BAB04 /* ViewControllerAutoLayout.swift in Sources */,
379 | 65D6FAA31D8C68A0004BAB04 /* ViewAutoLayout.swift in Sources */,
380 | 65D6FAA51D8C68A0004BAB04 /* ViewEffects.swift in Sources */,
381 | 65D6FAA01D8C68A0004BAB04 /* InspectableButton.swift in Sources */,
382 | );
383 | runOnlyForDeploymentPostprocessing = 0;
384 | };
385 | 65D6FA7F1D8C675E004BAB04 /* Sources */ = {
386 | isa = PBXSourcesBuildPhase;
387 | buildActionMask = 2147483647;
388 | files = (
389 | 65D6FA961D8C689E004BAB04 /* ViewAnimation.swift in Sources */,
390 | 65D6FA951D8C689E004BAB04 /* InspectableView.swift in Sources */,
391 | 65D6FA981D8C689E004BAB04 /* ViewControllerAutoLayout.swift in Sources */,
392 | 65D6FA971D8C689E004BAB04 /* ViewAutoLayout.swift in Sources */,
393 | 65D6FA991D8C689E004BAB04 /* ViewEffects.swift in Sources */,
394 | 65D6FA941D8C689E004BAB04 /* InspectableButton.swift in Sources */,
395 | );
396 | runOnlyForDeploymentPostprocessing = 0;
397 | };
398 | 65D6FAA61D8C68CF004BAB04 /* Sources */ = {
399 | isa = PBXSourcesBuildPhase;
400 | buildActionMask = 2147483647;
401 | files = (
402 | 65D6FAC11D8C69BF004BAB04 /* ViewEffects.swift in Sources */,
403 | 65D6FABC1D8C69BF004BAB04 /* InspectableButton.swift in Sources */,
404 | 65D6FABD1D8C69BF004BAB04 /* InspectableView.swift in Sources */,
405 | 65D6FAC01D8C69BF004BAB04 /* ViewControllerAutoLayout.swift in Sources */,
406 | 65D6FABE1D8C69BF004BAB04 /* ViewAnimation.swift in Sources */,
407 | 65D6FABF1D8C69BF004BAB04 /* ViewAutoLayout.swift in Sources */,
408 | 658FE8F01D92FA0D00CB92F3 /* ViewController.swift in Sources */,
409 | 65D6FAAD1D8C68CF004BAB04 /* AppDelegate.swift in Sources */,
410 | );
411 | runOnlyForDeploymentPostprocessing = 0;
412 | };
413 | 65D6FAC21D8C6C3E004BAB04 /* Sources */ = {
414 | isa = PBXSourcesBuildPhase;
415 | buildActionMask = 2147483647;
416 | files = (
417 | 65D6FADF1D8C7CDB004BAB04 /* ViewEffects.swift in Sources */,
418 | 65D6FAD91D8C76A9004BAB04 /* ViewController.swift in Sources */,
419 | 65D6FADA1D8C7CDB004BAB04 /* InspectableButton.swift in Sources */,
420 | 6588DCCB1DE971EB00575329 /* TableViewController.swift in Sources */,
421 | 65D6FADB1D8C7CDB004BAB04 /* InspectableView.swift in Sources */,
422 | 65D6FADE1D8C7CDB004BAB04 /* ViewControllerAutoLayout.swift in Sources */,
423 | 65D6FADC1D8C7CDB004BAB04 /* ViewAnimation.swift in Sources */,
424 | 65D6FADD1D8C7CDB004BAB04 /* ViewAutoLayout.swift in Sources */,
425 | 65D6FAC91D8C6C3E004BAB04 /* AppDelegate.swift in Sources */,
426 | );
427 | runOnlyForDeploymentPostprocessing = 0;
428 | };
429 | /* End PBXSourcesBuildPhase section */
430 |
431 | /* Begin PBXVariantGroup section */
432 | 65D6FAB51D8C68CF004BAB04 /* LaunchScreen.storyboard */ = {
433 | isa = PBXVariantGroup;
434 | children = (
435 | 65D6FAB61D8C68CF004BAB04 /* Base */,
436 | );
437 | name = LaunchScreen.storyboard;
438 | sourceTree = "";
439 | };
440 | 65D6FACC1D8C6C3E004BAB04 /* Main.storyboard */ = {
441 | isa = PBXVariantGroup;
442 | children = (
443 | 65D6FACD1D8C6C3E004BAB04 /* Base */,
444 | );
445 | name = Main.storyboard;
446 | sourceTree = "";
447 | };
448 | /* End PBXVariantGroup section */
449 |
450 | /* Begin XCBuildConfiguration section */
451 | 655AEB72192D429A0053AD6C /* Debug */ = {
452 | isa = XCBuildConfiguration;
453 | buildSettings = {
454 | ALWAYS_SEARCH_USER_PATHS = NO;
455 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
456 | CLANG_CXX_LIBRARY = "libc++";
457 | CLANG_ENABLE_MODULES = YES;
458 | CLANG_ENABLE_OBJC_ARC = YES;
459 | CLANG_WARN_BOOL_CONVERSION = YES;
460 | CLANG_WARN_CONSTANT_CONVERSION = YES;
461 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
462 | CLANG_WARN_EMPTY_BODY = YES;
463 | CLANG_WARN_ENUM_CONVERSION = YES;
464 | CLANG_WARN_INFINITE_RECURSION = YES;
465 | CLANG_WARN_INT_CONVERSION = YES;
466 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
467 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
468 | CLANG_WARN_UNREACHABLE_CODE = YES;
469 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
470 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
471 | COPY_PHASE_STRIP = NO;
472 | ENABLE_STRICT_OBJC_MSGSEND = YES;
473 | ENABLE_TESTABILITY = YES;
474 | GCC_C_LANGUAGE_STANDARD = gnu99;
475 | GCC_DYNAMIC_NO_PIC = NO;
476 | GCC_NO_COMMON_BLOCKS = YES;
477 | GCC_OPTIMIZATION_LEVEL = 0;
478 | GCC_PREPROCESSOR_DEFINITIONS = (
479 | "DEBUG=1",
480 | "$(inherited)",
481 | );
482 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
483 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
484 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
485 | GCC_WARN_UNDECLARED_SELECTOR = YES;
486 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
487 | GCC_WARN_UNUSED_FUNCTION = YES;
488 | GCC_WARN_UNUSED_VARIABLE = YES;
489 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
490 | ONLY_ACTIVE_ARCH = YES;
491 | SDKROOT = iphoneos;
492 | TARGETED_DEVICE_FAMILY = "1,2";
493 | };
494 | name = Debug;
495 | };
496 | 655AEB73192D429A0053AD6C /* Release */ = {
497 | isa = XCBuildConfiguration;
498 | buildSettings = {
499 | ALWAYS_SEARCH_USER_PATHS = NO;
500 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
501 | CLANG_CXX_LIBRARY = "libc++";
502 | CLANG_ENABLE_MODULES = YES;
503 | CLANG_ENABLE_OBJC_ARC = YES;
504 | CLANG_WARN_BOOL_CONVERSION = YES;
505 | CLANG_WARN_CONSTANT_CONVERSION = YES;
506 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
507 | CLANG_WARN_EMPTY_BODY = YES;
508 | CLANG_WARN_ENUM_CONVERSION = YES;
509 | CLANG_WARN_INFINITE_RECURSION = YES;
510 | CLANG_WARN_INT_CONVERSION = YES;
511 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
512 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
513 | CLANG_WARN_UNREACHABLE_CODE = YES;
514 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
515 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
516 | COPY_PHASE_STRIP = YES;
517 | ENABLE_NS_ASSERTIONS = NO;
518 | ENABLE_STRICT_OBJC_MSGSEND = YES;
519 | GCC_C_LANGUAGE_STANDARD = gnu99;
520 | GCC_NO_COMMON_BLOCKS = YES;
521 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
522 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
523 | GCC_WARN_UNDECLARED_SELECTOR = YES;
524 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
525 | GCC_WARN_UNUSED_FUNCTION = YES;
526 | GCC_WARN_UNUSED_VARIABLE = YES;
527 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
528 | SDKROOT = iphoneos;
529 | TARGETED_DEVICE_FAMILY = "1,2";
530 | VALIDATE_PRODUCT = YES;
531 | };
532 | name = Release;
533 | };
534 | 65D6FA701D8C673E004BAB04 /* Debug */ = {
535 | isa = XCBuildConfiguration;
536 | buildSettings = {
537 | APPLICATION_EXTENSION_API_ONLY = YES;
538 | CLANG_ANALYZER_NONNULL = YES;
539 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
540 | CLANG_WARN_INFINITE_RECURSION = YES;
541 | CLANG_WARN_SUSPICIOUS_MOVES = YES;
542 | CLANG_WARN_UNREACHABLE_CODE = YES;
543 | CODE_SIGN_IDENTITY = "";
544 | CURRENT_PROJECT_VERSION = 1;
545 | DEBUG_INFORMATION_FORMAT = dwarf;
546 | DEFINES_MODULE = YES;
547 | DYLIB_COMPATIBILITY_VERSION = 1;
548 | DYLIB_CURRENT_VERSION = 1;
549 | DYLIB_INSTALL_NAME_BASE = "@rpath";
550 | ENABLE_STRICT_OBJC_MSGSEND = YES;
551 | GCC_NO_COMMON_BLOCKS = YES;
552 | INFOPLIST_FILE = "$(SRCROOT)/Sources/Info-iOS.plist";
553 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
554 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
555 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
556 | MTL_ENABLE_DEBUG_INFO = YES;
557 | PRODUCT_BUNDLE_IDENTIFIER = "com.allforces.ViewHelper-iOS";
558 | PRODUCT_NAME = ViewHelper;
559 | SKIP_INSTALL = YES;
560 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
561 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
562 | SWIFT_VERSION = 3.0;
563 | TVOS_DEPLOYMENT_TARGET = 10.0;
564 | VERSIONING_SYSTEM = "apple-generic";
565 | VERSION_INFO_PREFIX = "";
566 | WATCHOS_DEPLOYMENT_TARGET = 2.0;
567 | };
568 | name = Debug;
569 | };
570 | 65D6FA711D8C673E004BAB04 /* Release */ = {
571 | isa = XCBuildConfiguration;
572 | buildSettings = {
573 | APPLICATION_EXTENSION_API_ONLY = YES;
574 | CLANG_ANALYZER_NONNULL = YES;
575 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
576 | CLANG_WARN_INFINITE_RECURSION = YES;
577 | CLANG_WARN_SUSPICIOUS_MOVES = YES;
578 | CLANG_WARN_UNREACHABLE_CODE = YES;
579 | CODE_SIGN_IDENTITY = "";
580 | COPY_PHASE_STRIP = NO;
581 | CURRENT_PROJECT_VERSION = 1;
582 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
583 | DEFINES_MODULE = YES;
584 | DYLIB_COMPATIBILITY_VERSION = 1;
585 | DYLIB_CURRENT_VERSION = 1;
586 | DYLIB_INSTALL_NAME_BASE = "@rpath";
587 | ENABLE_STRICT_OBJC_MSGSEND = YES;
588 | GCC_NO_COMMON_BLOCKS = YES;
589 | INFOPLIST_FILE = "$(SRCROOT)/Sources/Info-iOS.plist";
590 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
591 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
592 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
593 | MTL_ENABLE_DEBUG_INFO = NO;
594 | PRODUCT_BUNDLE_IDENTIFIER = "com.allforces.ViewHelper-iOS";
595 | PRODUCT_NAME = ViewHelper;
596 | SKIP_INSTALL = YES;
597 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
598 | SWIFT_VERSION = 3.0;
599 | TVOS_DEPLOYMENT_TARGET = 10.0;
600 | VERSIONING_SYSTEM = "apple-generic";
601 | VERSION_INFO_PREFIX = "";
602 | WATCHOS_DEPLOYMENT_TARGET = 2.0;
603 | };
604 | name = Release;
605 | };
606 | 65D6FA8A1D8C675E004BAB04 /* Debug */ = {
607 | isa = XCBuildConfiguration;
608 | buildSettings = {
609 | APPLICATION_EXTENSION_API_ONLY = YES;
610 | CLANG_ANALYZER_NONNULL = YES;
611 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
612 | CLANG_WARN_INFINITE_RECURSION = YES;
613 | CLANG_WARN_SUSPICIOUS_MOVES = YES;
614 | CLANG_WARN_UNREACHABLE_CODE = YES;
615 | CODE_SIGN_IDENTITY = "";
616 | CURRENT_PROJECT_VERSION = 1;
617 | DEBUG_INFORMATION_FORMAT = dwarf;
618 | DEFINES_MODULE = YES;
619 | DYLIB_COMPATIBILITY_VERSION = 1;
620 | DYLIB_CURRENT_VERSION = 1;
621 | DYLIB_INSTALL_NAME_BASE = "@rpath";
622 | ENABLE_STRICT_OBJC_MSGSEND = YES;
623 | GCC_NO_COMMON_BLOCKS = YES;
624 | INFOPLIST_FILE = "$(SRCROOT)/Sources/Info-tvOS.plist";
625 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
626 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
627 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
628 | MTL_ENABLE_DEBUG_INFO = YES;
629 | PRODUCT_BUNDLE_IDENTIFIER = "com.allforces.ViewHelper-tvOS";
630 | PRODUCT_NAME = ViewHelper;
631 | SDKROOT = appletvos;
632 | SKIP_INSTALL = YES;
633 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
634 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
635 | SWIFT_VERSION = 3.0;
636 | TARGETED_DEVICE_FAMILY = 3;
637 | TVOS_DEPLOYMENT_TARGET = 10.0;
638 | VERSIONING_SYSTEM = "apple-generic";
639 | VERSION_INFO_PREFIX = "";
640 | WATCHOS_DEPLOYMENT_TARGET = 2.0;
641 | };
642 | name = Debug;
643 | };
644 | 65D6FA8B1D8C675E004BAB04 /* Release */ = {
645 | isa = XCBuildConfiguration;
646 | buildSettings = {
647 | APPLICATION_EXTENSION_API_ONLY = YES;
648 | CLANG_ANALYZER_NONNULL = YES;
649 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
650 | CLANG_WARN_INFINITE_RECURSION = YES;
651 | CLANG_WARN_SUSPICIOUS_MOVES = YES;
652 | CLANG_WARN_UNREACHABLE_CODE = YES;
653 | CODE_SIGN_IDENTITY = "";
654 | COPY_PHASE_STRIP = NO;
655 | CURRENT_PROJECT_VERSION = 1;
656 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
657 | DEFINES_MODULE = YES;
658 | DYLIB_COMPATIBILITY_VERSION = 1;
659 | DYLIB_CURRENT_VERSION = 1;
660 | DYLIB_INSTALL_NAME_BASE = "@rpath";
661 | ENABLE_STRICT_OBJC_MSGSEND = YES;
662 | GCC_NO_COMMON_BLOCKS = YES;
663 | INFOPLIST_FILE = "$(SRCROOT)/Sources/Info-tvOS.plist";
664 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
665 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
666 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
667 | MTL_ENABLE_DEBUG_INFO = NO;
668 | PRODUCT_BUNDLE_IDENTIFIER = "com.allforces.ViewHelper-tvOS";
669 | PRODUCT_NAME = ViewHelper;
670 | SDKROOT = appletvos;
671 | SKIP_INSTALL = YES;
672 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
673 | SWIFT_VERSION = 3.0;
674 | TARGETED_DEVICE_FAMILY = 3;
675 | TVOS_DEPLOYMENT_TARGET = 10.0;
676 | VERSIONING_SYSTEM = "apple-generic";
677 | VERSION_INFO_PREFIX = "";
678 | WATCHOS_DEPLOYMENT_TARGET = 2.0;
679 | };
680 | name = Release;
681 | };
682 | 65D6FABA1D8C68CF004BAB04 /* Debug */ = {
683 | isa = XCBuildConfiguration;
684 | buildSettings = {
685 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
686 | CLANG_ANALYZER_NONNULL = YES;
687 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
688 | CLANG_WARN_INFINITE_RECURSION = YES;
689 | CLANG_WARN_SUSPICIOUS_MOVES = YES;
690 | CLANG_WARN_UNREACHABLE_CODE = YES;
691 | DEBUG_INFORMATION_FORMAT = dwarf;
692 | ENABLE_STRICT_OBJC_MSGSEND = YES;
693 | GCC_NO_COMMON_BLOCKS = YES;
694 | INFOPLIST_FILE = "ViewHelperDemo iOS/Info.plist";
695 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
696 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
697 | MTL_ENABLE_DEBUG_INFO = YES;
698 | PRODUCT_BUNDLE_IDENTIFIER = "com.allforces.ViewHelperDemo-iOS";
699 | PRODUCT_NAME = "$(TARGET_NAME)";
700 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
701 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
702 | SWIFT_VERSION = 3.0;
703 | };
704 | name = Debug;
705 | };
706 | 65D6FABB1D8C68CF004BAB04 /* Release */ = {
707 | isa = XCBuildConfiguration;
708 | buildSettings = {
709 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
710 | CLANG_ANALYZER_NONNULL = YES;
711 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
712 | CLANG_WARN_INFINITE_RECURSION = YES;
713 | CLANG_WARN_SUSPICIOUS_MOVES = YES;
714 | CLANG_WARN_UNREACHABLE_CODE = YES;
715 | COPY_PHASE_STRIP = NO;
716 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
717 | ENABLE_STRICT_OBJC_MSGSEND = YES;
718 | GCC_NO_COMMON_BLOCKS = YES;
719 | INFOPLIST_FILE = "ViewHelperDemo iOS/Info.plist";
720 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
721 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
722 | MTL_ENABLE_DEBUG_INFO = NO;
723 | PRODUCT_BUNDLE_IDENTIFIER = "com.allforces.ViewHelperDemo-iOS";
724 | PRODUCT_NAME = "$(TARGET_NAME)";
725 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
726 | SWIFT_VERSION = 3.0;
727 | };
728 | name = Release;
729 | };
730 | 65D6FAD31D8C6C3E004BAB04 /* Debug */ = {
731 | isa = XCBuildConfiguration;
732 | buildSettings = {
733 | ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image";
734 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
735 | CLANG_ANALYZER_NONNULL = YES;
736 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
737 | CLANG_WARN_INFINITE_RECURSION = YES;
738 | CLANG_WARN_SUSPICIOUS_MOVES = YES;
739 | CLANG_WARN_UNREACHABLE_CODE = YES;
740 | DEBUG_INFORMATION_FORMAT = dwarf;
741 | ENABLE_STRICT_OBJC_MSGSEND = YES;
742 | GCC_NO_COMMON_BLOCKS = YES;
743 | INFOPLIST_FILE = "ViewHelperDemo tvOS/Info.plist";
744 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
745 | MTL_ENABLE_DEBUG_INFO = YES;
746 | PRODUCT_BUNDLE_IDENTIFIER = "com.allforces.ViewHelperDemo-tvOS";
747 | PRODUCT_NAME = "$(TARGET_NAME)";
748 | SDKROOT = appletvos;
749 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
750 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
751 | SWIFT_VERSION = 3.0;
752 | TARGETED_DEVICE_FAMILY = 3;
753 | TVOS_DEPLOYMENT_TARGET = 10.0;
754 | };
755 | name = Debug;
756 | };
757 | 65D6FAD41D8C6C3E004BAB04 /* Release */ = {
758 | isa = XCBuildConfiguration;
759 | buildSettings = {
760 | ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image";
761 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
762 | CLANG_ANALYZER_NONNULL = YES;
763 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
764 | CLANG_WARN_INFINITE_RECURSION = YES;
765 | CLANG_WARN_SUSPICIOUS_MOVES = YES;
766 | CLANG_WARN_UNREACHABLE_CODE = YES;
767 | COPY_PHASE_STRIP = NO;
768 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
769 | ENABLE_STRICT_OBJC_MSGSEND = YES;
770 | GCC_NO_COMMON_BLOCKS = YES;
771 | INFOPLIST_FILE = "ViewHelperDemo tvOS/Info.plist";
772 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
773 | MTL_ENABLE_DEBUG_INFO = NO;
774 | PRODUCT_BUNDLE_IDENTIFIER = "com.allforces.ViewHelperDemo-tvOS";
775 | PRODUCT_NAME = "$(TARGET_NAME)";
776 | SDKROOT = appletvos;
777 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
778 | SWIFT_VERSION = 3.0;
779 | TARGETED_DEVICE_FAMILY = 3;
780 | TVOS_DEPLOYMENT_TARGET = 10.0;
781 | };
782 | name = Release;
783 | };
784 | /* End XCBuildConfiguration section */
785 |
786 | /* Begin XCConfigurationList section */
787 | 655AEB3A192D42990053AD6C /* Build configuration list for PBXProject "ViewHelper" */ = {
788 | isa = XCConfigurationList;
789 | buildConfigurations = (
790 | 655AEB72192D429A0053AD6C /* Debug */,
791 | 655AEB73192D429A0053AD6C /* Release */,
792 | );
793 | defaultConfigurationIsVisible = 0;
794 | defaultConfigurationName = Release;
795 | };
796 | 65D6FA6F1D8C673E004BAB04 /* Build configuration list for PBXNativeTarget "ViewHelper iOS" */ = {
797 | isa = XCConfigurationList;
798 | buildConfigurations = (
799 | 65D6FA701D8C673E004BAB04 /* Debug */,
800 | 65D6FA711D8C673E004BAB04 /* Release */,
801 | );
802 | defaultConfigurationIsVisible = 0;
803 | defaultConfigurationName = Release;
804 | };
805 | 65D6FA891D8C675E004BAB04 /* Build configuration list for PBXNativeTarget "ViewHelper tvOS" */ = {
806 | isa = XCConfigurationList;
807 | buildConfigurations = (
808 | 65D6FA8A1D8C675E004BAB04 /* Debug */,
809 | 65D6FA8B1D8C675E004BAB04 /* Release */,
810 | );
811 | defaultConfigurationIsVisible = 0;
812 | defaultConfigurationName = Release;
813 | };
814 | 65D6FAB91D8C68CF004BAB04 /* Build configuration list for PBXNativeTarget "ViewHelperDemo iOS" */ = {
815 | isa = XCConfigurationList;
816 | buildConfigurations = (
817 | 65D6FABA1D8C68CF004BAB04 /* Debug */,
818 | 65D6FABB1D8C68CF004BAB04 /* Release */,
819 | );
820 | defaultConfigurationIsVisible = 0;
821 | defaultConfigurationName = Release;
822 | };
823 | 65D6FAD21D8C6C3E004BAB04 /* Build configuration list for PBXNativeTarget "ViewHelperDemo tvOS" */ = {
824 | isa = XCConfigurationList;
825 | buildConfigurations = (
826 | 65D6FAD31D8C6C3E004BAB04 /* Debug */,
827 | 65D6FAD41D8C6C3E004BAB04 /* Release */,
828 | );
829 | defaultConfigurationIsVisible = 0;
830 | defaultConfigurationName = Release;
831 | };
832 | /* End XCConfigurationList section */
833 | };
834 | rootObject = 655AEB37192D42990053AD6C /* Project object */;
835 | }
836 |
--------------------------------------------------------------------------------
/ViewHelper.xcodeproj/xcshareddata/xcschemes/ViewHelper iOS.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 |
--------------------------------------------------------------------------------
/ViewHelper.xcodeproj/xcshareddata/xcschemes/ViewHelper tvOS.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 |
--------------------------------------------------------------------------------
/ViewHelperDemo iOS/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // ViewHelperDemo iOS
4 | //
5 | // Created by Melvin Rivera on 9/16/16.
6 | // Copyright © 2016 All Forces. 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 |
--------------------------------------------------------------------------------
/ViewHelperDemo iOS/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 | }
--------------------------------------------------------------------------------
/ViewHelperDemo iOS/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 |
27 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/ViewHelperDemo iOS/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 |
--------------------------------------------------------------------------------
/ViewHelperDemo iOS/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 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
81 |
82 |
83 |
84 |
85 |
86 |
90 |
91 |
92 |
93 |
94 |
95 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
113 |
114 |
115 |
116 |
117 |
118 |
122 |
123 |
124 |
125 |
126 |
127 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
144 |
145 |
146 |
147 |
148 |
149 |
153 |
154 |
155 |
156 |
157 |
158 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
196 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
--------------------------------------------------------------------------------
/ViewHelperDemo iOS/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | //
4 | // Created by Melvin Rivera on 7/2/14.
5 | // Copyright (c) 2014 All Forces. All rights reserved.
6 | //
7 |
8 | import Foundation
9 | import UIKit
10 | import QuartzCore
11 |
12 | class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
13 |
14 | var selectedAnimation: Int = 0
15 | var selectedEasing: Int = 0
16 |
17 | @IBOutlet weak var forceSlider: UISlider!
18 | @IBOutlet weak var forceLabel: UILabel!
19 |
20 | @IBOutlet weak var durationSlider: UISlider!
21 | @IBOutlet weak var durationLabel: UILabel!
22 |
23 | @IBOutlet weak var delaySlider: UISlider!
24 | @IBOutlet weak var delayLabel: UILabel!
25 |
26 | @IBOutlet weak var scaleSlider: UISlider!
27 | @IBOutlet weak var scaleLabel: UILabel!
28 |
29 | @IBOutlet weak var rotateSlider: UISlider!
30 | @IBOutlet weak var rotateLabel: UILabel!
31 |
32 | @IBOutlet weak var dampingSlider: UISlider!
33 | @IBOutlet weak var dampingLabel: UILabel!
34 |
35 | @IBOutlet weak var velocitySlider: UISlider!
36 | @IBOutlet weak var velocityLabel: UILabel!
37 |
38 | @IBOutlet weak var xSlider: UISlider!
39 | @IBOutlet weak var xLabel: UILabel!
40 |
41 | @IBOutlet weak var ySlider: UISlider!
42 | @IBOutlet weak var yLabel: UILabel!
43 |
44 |
45 | @IBOutlet weak var mainBox: InspectableView!
46 | @IBOutlet weak var bigCircle: InspectableView!
47 | @IBOutlet weak var smallCircle: InspectableView!
48 |
49 | override var prefersStatusBarHidden : Bool {
50 | return true
51 | }
52 |
53 | override func viewDidLoad() {
54 |
55 | super.viewDidLoad()
56 |
57 |
58 | // Top Left Square
59 | let topLeftSquare = UIView(autoLayout:true)
60 | bigCircle.addSubview(topLeftSquare)
61 | topLeftSquare.backgroundColor = UIColor(white: 0.1, alpha: 1)
62 | topLeftSquare
63 | .left(to: bigCircle)
64 | .top(to: bigCircle)
65 | .width(to: bigCircle, attribute: .width, constant: 0, multiplier: 0.48)
66 | .height(to: topLeftSquare, attribute: .width)
67 | .layoutIfNeeded()
68 |
69 | // Top Right Square
70 | let topRightSquare = UIView(autoLayout:true)
71 | bigCircle.addSubview(topRightSquare)
72 | topRightSquare.backgroundColor = UIColor(white: 0.1, alpha: 1)
73 | topRightSquare
74 | .right(to: bigCircle)
75 | .top(to: bigCircle)
76 | .size(to: topLeftSquare)
77 | .layoutIfNeeded()
78 |
79 | // Bottom Left Square
80 | let bottomLeftSquare = UIView(autoLayout:true)
81 | bigCircle.addSubview(bottomLeftSquare)
82 | bottomLeftSquare.backgroundColor = UIColor(white: 0.1, alpha: 1)
83 | bottomLeftSquare
84 | .left(to: bigCircle)
85 | .bottom(to: bigCircle)
86 | .size(to: topLeftSquare)
87 | .layoutIfNeeded()
88 |
89 |
90 | // Bottom Right Square
91 | let bottomRightSquare = UIView(autoLayout:true)
92 | bigCircle.addSubview(bottomRightSquare)
93 | bottomRightSquare.backgroundColor = UIColor(white:0.1, alpha: 1)
94 | bottomRightSquare
95 | .right(to: bigCircle)
96 | .bottom(to: bigCircle)
97 | .size(to: topLeftSquare)
98 | .layoutIfNeeded()
99 |
100 | resetValues()
101 | }
102 |
103 | // MARK: View Layout
104 |
105 | override func viewDidAppear(_ animated: Bool)
106 | {
107 | super.viewDidAppear(animated)
108 | layoutView()
109 | }
110 |
111 | override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator)
112 | {
113 | super.viewWillTransition(to: size, with: coordinator)
114 |
115 | //view.layoutIfNeeded()
116 | coordinator.animate(alongsideTransition: {
117 | context in
118 | // Create a transition and match the context's duration
119 | let transition = CATransition()
120 | transition.duration = context.transitionDuration
121 | transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
122 | self.bigCircle.layer.add(transition, forKey: "cornerRadius")
123 | self.bigCircle.cornerRadius = self.bigCircle.width()/2
124 | self.smallCircle.layer.add(transition, forKey: "cornerRadius")
125 | self.smallCircle.cornerRadius = self.smallCircle.width()/2
126 | }, completion: nil)
127 |
128 | }
129 |
130 | func layoutView()
131 | {
132 | view.layoutIfNeeded()
133 | bigCircle.cornerRadius = bigCircle.width()/2
134 | smallCircle.cornerRadius = smallCircle.width()/2
135 | }
136 |
137 |
138 | // MARK: UIPickerView
139 |
140 | func numberOfComponents(in pickerView: UIPickerView) -> Int {
141 | return 2
142 | }
143 |
144 | func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
145 | return component == 0 ? AnimationType.allValues.count : AnimationEasingCurve.allValues.count
146 | }
147 |
148 | func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
149 | return component == 0 ? String(describing: AnimationType.allValues[row]) : String(describing: AnimationEasingCurve.allValues[row])
150 | }
151 |
152 | func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
153 | switch component {
154 | case 0:
155 | selectedAnimation = row
156 | animateView(nil)
157 | default:
158 | selectedEasing = row
159 | animateView()
160 | }
161 | }
162 |
163 |
164 | // MARK: Actions
165 |
166 | @IBAction func resetValues(_ sender: AnyObject? = nil) {
167 | forceSlider.setValue(1, animated: true)
168 | durationSlider.setValue(0.5, animated: true)
169 | delaySlider.setValue(0, animated: true)
170 | scaleSlider.setValue(1, animated: true)
171 | rotateSlider.setValue(0, animated: true)
172 | dampingSlider.setValue(0.7, animated: true)
173 | velocitySlider.setValue(0.7, animated: true)
174 | xSlider.setValue(0, animated: true)
175 | ySlider.setValue(0, animated: true)
176 | }
177 |
178 | @IBAction func animateView(_ sender: AnyObject? = nil) {
179 | bigCircle.animate(AnimationType.allValues[selectedAnimation], curve: AnimationEasingCurve.allValues[selectedEasing], duration: CGFloat(durationSlider.value), delay: CGFloat(delaySlider.value), force: CGFloat(forceSlider.value), damping: CGFloat(dampingSlider.value),velocity: CGFloat(velocitySlider.value), fromRotation: CGFloat(rotateSlider.value), fromScale: CGFloat(scaleSlider.value), fromX: CGFloat(xSlider.value), fromY: CGFloat(ySlider.value))
180 | }
181 |
182 | @IBAction func forceSliderChanged(_ sender: AnyObject) {
183 | animateView()
184 | forceLabel.text = String(format: "Force: %.1f", forceSlider.value)
185 | }
186 | @IBAction func durationSliderChanged(_ sender: AnyObject) {
187 | animateView()
188 | durationLabel.text = String(format: "Duration: %.1f", durationSlider.value)
189 | }
190 | @IBAction func delaySliderChanged(_ sender: AnyObject) {
191 | animateView()
192 | delayLabel.text = String(format: "Delay: %.1f", delaySlider.value)
193 | }
194 |
195 | @IBAction func scaleSliderChanged(_ sender: AnyObject) {
196 | animateView()
197 | scaleLabel.text = String(format: "Scale: %.1f", scaleSlider.value)
198 | }
199 | @IBAction func rotateSliderChanged(_ sender: AnyObject) {
200 | animateView()
201 | rotateLabel.text = String(format: "Rotate: %.1f", rotateSlider.value)
202 | }
203 | @IBAction func dampingSliderChanged(_ sender: AnyObject) {
204 | animateView()
205 | dampingLabel.text = String(format: "Damping: %.1f", dampingSlider.value)
206 | }
207 |
208 | @IBAction func velocitySliderChanged(_ sender: AnyObject) {
209 | animateView()
210 | velocityLabel.text = String(format: "Velocity: %.1f", velocitySlider.value)
211 | }
212 | @IBAction func xSliderChanged(_ sender: AnyObject) {
213 | animateView()
214 | xLabel.text = String(format: "x: %.1f", xSlider.value)
215 | }
216 | @IBAction func ySliderChanged(_ sender: AnyObject) {
217 | animateView()
218 | yLabel.text = String(format: "y: %.1f", ySlider.value)
219 | }
220 |
221 |
222 | }
223 |
224 |
--------------------------------------------------------------------------------
/ViewHelperDemo tvOS/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // ViewHelperDemo tvOS
4 | //
5 | // Created by Melvin Rivera on 9/16/16.
6 | // Copyright © 2016 All Forces. 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 throttle down OpenGL ES frame rates. 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 |
--------------------------------------------------------------------------------
/ViewHelperDemo tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Back.imagestacklayer/Content.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv",
5 | "scale" : "1x"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/ViewHelperDemo tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Back.imagestacklayer/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/ViewHelperDemo tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "layers" : [
3 | {
4 | "filename" : "Front.imagestacklayer"
5 | },
6 | {
7 | "filename" : "Middle.imagestacklayer"
8 | },
9 | {
10 | "filename" : "Back.imagestacklayer"
11 | }
12 | ],
13 | "info" : {
14 | "version" : 1,
15 | "author" : "xcode"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/ViewHelperDemo tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Front.imagestacklayer/Content.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv",
5 | "scale" : "1x"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/ViewHelperDemo tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Front.imagestacklayer/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/ViewHelperDemo tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv",
5 | "scale" : "1x"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/ViewHelperDemo tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Middle.imagestacklayer/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/ViewHelperDemo tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Back.imagestacklayer/Content.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv",
5 | "scale" : "1x"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/ViewHelperDemo tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Back.imagestacklayer/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/ViewHelperDemo tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "layers" : [
3 | {
4 | "filename" : "Front.imagestacklayer"
5 | },
6 | {
7 | "filename" : "Middle.imagestacklayer"
8 | },
9 | {
10 | "filename" : "Back.imagestacklayer"
11 | }
12 | ],
13 | "info" : {
14 | "version" : 1,
15 | "author" : "xcode"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/ViewHelperDemo tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Front.imagestacklayer/Content.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv",
5 | "scale" : "1x"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/ViewHelperDemo tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Front.imagestacklayer/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/ViewHelperDemo tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv",
5 | "scale" : "1x"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/ViewHelperDemo tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Middle.imagestacklayer/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/ViewHelperDemo tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "assets" : [
3 | {
4 | "size" : "1280x768",
5 | "idiom" : "tv",
6 | "filename" : "App Icon - Large.imagestack",
7 | "role" : "primary-app-icon"
8 | },
9 | {
10 | "size" : "400x240",
11 | "idiom" : "tv",
12 | "filename" : "App Icon - Small.imagestack",
13 | "role" : "primary-app-icon"
14 | },
15 | {
16 | "size" : "2320x720",
17 | "idiom" : "tv",
18 | "filename" : "Top Shelf Image Wide.imageset",
19 | "role" : "top-shelf-image-wide"
20 | },
21 | {
22 | "size" : "1920x720",
23 | "idiom" : "tv",
24 | "filename" : "Top Shelf Image.imageset",
25 | "role" : "top-shelf-image"
26 | }
27 | ],
28 | "info" : {
29 | "version" : 1,
30 | "author" : "xcode"
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/ViewHelperDemo tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image Wide.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv",
5 | "scale" : "1x"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/ViewHelperDemo tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv",
5 | "scale" : "1x"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/ViewHelperDemo tvOS/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/ViewHelperDemo tvOS/Assets.xcassets/LaunchImage.launchimage/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "orientation" : "landscape",
5 | "idiom" : "tv",
6 | "extent" : "full-screen",
7 | "minimum-system-version" : "9.0",
8 | "scale" : "1x"
9 | }
10 | ],
11 | "info" : {
12 | "version" : 1,
13 | "author" : "xcode"
14 | }
15 | }
--------------------------------------------------------------------------------
/ViewHelperDemo tvOS/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 | UIMainStoryboardFile
24 | Main
25 | UIRequiredDeviceCapabilities
26 |
27 | arm64
28 |
29 | UIUserInterfaceStyle
30 | Automatic
31 |
32 |
33 |
--------------------------------------------------------------------------------
/ViewHelperDemo tvOS/TableViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TableViewController.swift
3 | // ViewHelper
4 | //
5 | // Created by Melvin Rivera on 11/26/16.
6 | // Copyright © 2016 All Forces. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class TableViewController: UITableViewController {
12 |
13 | var selected: Int = 0
14 | var items = [String]()
15 |
16 | override func viewDidLoad() {
17 | super.viewDidLoad()
18 |
19 | }
20 |
21 | override func viewDidAppear(_ animated: Bool) {
22 | super.viewDidAppear(animated)
23 | self.tableView.selectRow(at: IndexPath(item: selected, section: 0), animated: true, scrollPosition: UITableViewScrollPosition.middle)
24 | }
25 |
26 | // MARK: - Table view data source
27 |
28 | override func numberOfSections(in tableView: UITableView) -> Int {
29 | return 1
30 | }
31 |
32 | override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
33 | return items.count
34 | }
35 |
36 | override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
37 | let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
38 | cell.textLabel?.text = items[indexPath.row]
39 | return cell
40 | }
41 |
42 | override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
43 | selected = indexPath.row
44 | if self.title == selectedAnimationKey {
45 | UserDefaults.standard.set(selected, forKey: selectedAnimationKey)
46 | } else {
47 | UserDefaults.standard.set(selected, forKey: selectedEasingCurveKey)
48 | }
49 | UserDefaults.standard.synchronize()
50 | }
51 |
52 | }
53 |
--------------------------------------------------------------------------------
/ViewHelperDemo tvOS/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // ViewHelperDemo tvOS
4 | //
5 | // Created by Melvin Rivera on 9/16/16.
6 | // Copyright © 2016 All Forces. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | let selectedAnimationKey = "selectedAnimation"
12 | let selectedEasingCurveKey = "selectedEasingCurve"
13 |
14 | class ViewController: UIViewController {
15 |
16 | var selectedAnimation: Int = 0
17 | var selectedEasingCurve: Int = 0
18 |
19 | @IBOutlet weak var mainBox: InspectableView!
20 | @IBOutlet weak var bigCircle: InspectableView!
21 | @IBOutlet weak var smallCircle: InspectableView!
22 |
23 |
24 | @IBOutlet weak var forceLabel: UILabel!
25 | @IBOutlet weak var durationLabel: UILabel!
26 | @IBOutlet weak var delayLabel: UILabel!
27 | @IBOutlet weak var scaleLabel: UILabel!
28 | @IBOutlet weak var rotateLabel: UILabel!
29 | @IBOutlet weak var dampingLabel: UILabel!
30 | @IBOutlet weak var velocityLabel: UILabel!
31 | @IBOutlet weak var xPointLabel: UILabel!
32 | @IBOutlet weak var yPointLabel: UILabel!
33 |
34 | @IBOutlet weak var animation: UIButton!
35 | @IBOutlet weak var curve: UIButton!
36 |
37 | struct AnimationProperty {
38 | var minValue:Float
39 | var maxValue:Float
40 | var defaultValue:Float
41 | var stepValue:Float
42 | init (min:Float, max:Float, defaultValue:Float, step:Float) {
43 | minValue = min
44 | maxValue = max
45 | self.defaultValue = defaultValue
46 | currentValue = defaultValue
47 | stepValue = step
48 | }
49 | var currentValue:Float {
50 | didSet {
51 | currentValue = max(min(currentValue, maxValue), minValue)
52 | }
53 | }
54 | var percentageValue:Float {
55 | get { return (currentValue - minValue) / (maxValue - minValue) }
56 | }
57 | }
58 |
59 |
60 | var force = AnimationProperty(min: 1, max: 5, defaultValue: 1, step: 1)
61 | var duration = AnimationProperty(min: 0.5, max: 5, defaultValue: 0.5, step: 0.5)
62 | var delay = AnimationProperty(min: 0, max: 5, defaultValue: 0, step: 0.5)
63 | var scale = AnimationProperty(min: 1, max: 5, defaultValue: 1, step: 1)
64 | var rotate = AnimationProperty(min: 0, max: 5, defaultValue: 0, step: 1)
65 | var damping = AnimationProperty(min: 0, max: 1, defaultValue: 0.7, step: 0.1)
66 | var velocity = AnimationProperty(min: 0, max: 1, defaultValue: 0.7, step: 0.1)
67 | var xPoint = AnimationProperty(min: -1000, max: 1000, defaultValue: 0, step: 50)
68 | var yPoint = AnimationProperty(min: -1000, max: 1000, defaultValue: 0, step: 50)
69 |
70 |
71 | override func viewDidLoad() {
72 | super.viewDidLoad()
73 |
74 |
75 | /*
76 |
77 | Setting up some views by code to demnstrate how to add a view with constraints.
78 | */
79 | // Top Left Square
80 | let topLeftSquare = UIView(autoLayout:true)
81 | bigCircle.addSubview(topLeftSquare)
82 | topLeftSquare.backgroundColor = UIColor(white: 0.1, alpha: 1)
83 | topLeftSquare
84 | .left(to: bigCircle)
85 | .top(to: bigCircle)
86 | .width(to: bigCircle, attribute: .width, constant: 0, multiplier: 0.48)
87 | .height(to: topLeftSquare, attribute: .width)
88 | .layoutIfNeeded()
89 |
90 | // Top Right Square
91 | let topRightSquare = UIView(autoLayout:true)
92 | bigCircle.addSubview(topRightSquare)
93 | topRightSquare.backgroundColor = UIColor(white: 0.1, alpha: 1)
94 | topRightSquare
95 | .right(to: bigCircle)
96 | .top(to: bigCircle)
97 | .size(to: topLeftSquare)
98 | .layoutIfNeeded()
99 |
100 | // Bottom Left Square
101 | let bottomLeftSquare = UIView(autoLayout:true)
102 | bigCircle.addSubview(bottomLeftSquare)
103 | bottomLeftSquare.backgroundColor = UIColor(white: 0.1, alpha: 1)
104 | bottomLeftSquare
105 | .left(to: bigCircle)
106 | .bottom(to: bigCircle)
107 | .size(to: topLeftSquare)
108 | .layoutIfNeeded()
109 |
110 |
111 | // Bottom Right Square
112 | let bottomRightSquare = UIView(autoLayout:true)
113 | bigCircle.addSubview(bottomRightSquare)
114 | bottomRightSquare.backgroundColor = UIColor(white:0.1, alpha: 1)
115 | bottomRightSquare
116 | .right(to: bigCircle)
117 | .bottom(to: bigCircle)
118 | .size(to: topLeftSquare)
119 | .layoutIfNeeded()
120 |
121 | UserDefaults.standard.addObserver(self, forKeyPath: selectedAnimationKey, options: NSKeyValueObservingOptions.new, context: nil)
122 | UserDefaults.standard.addObserver(self, forKeyPath: selectedEasingCurveKey, options: NSKeyValueObservingOptions.new, context: nil)
123 |
124 | resetValues()
125 |
126 | }
127 |
128 | override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
129 | if keyPath == selectedAnimationKey {
130 | updateAnimationUI()
131 | } else {
132 | updateEasingCurveUI()
133 | }
134 | animateView()
135 | }
136 |
137 | override func viewDidAppear(_ animated: Bool)
138 | {
139 | super.viewDidAppear(animated)
140 | layoutView()
141 | }
142 |
143 | func layoutView()
144 | {
145 | view.layoutIfNeeded()
146 | bigCircle.cornerRadius = bigCircle.width()/2
147 | smallCircle.cornerRadius = smallCircle.width()/2
148 | }
149 |
150 |
151 |
152 | @IBAction func resetValues(_ sender: AnyObject? = nil) {
153 |
154 | force.currentValue = force.defaultValue
155 | updateForceUI()
156 |
157 | duration.currentValue = duration.defaultValue
158 | updateDurationUI()
159 |
160 | delay.currentValue = delay.defaultValue
161 | updateDelayUI()
162 |
163 | scale.currentValue = scale.defaultValue
164 | updateScaleUI()
165 |
166 | rotate.currentValue = rotate.defaultValue
167 | updateRotateUI()
168 |
169 | damping.currentValue = damping.defaultValue
170 | updateDampingUI()
171 |
172 | velocity.currentValue = velocity.defaultValue
173 | updateVelocityUI()
174 |
175 | xPoint.currentValue = xPoint.defaultValue
176 | updateXPointUI()
177 |
178 | yPoint.currentValue = yPoint.defaultValue
179 | updateYPointUI()
180 |
181 | selectedAnimation = 0
182 | selectedEasingCurve = 0
183 | UserDefaults.standard.set(selectedAnimation, forKey: selectedAnimationKey)
184 | UserDefaults.standard.set(selectedEasingCurve, forKey: selectedAnimationKey)
185 | UserDefaults.standard.synchronize()
186 | updateAnimationUI()
187 | updateEasingCurveUI()
188 |
189 | }
190 |
191 | @IBAction func animateView(_ sender: AnyObject? = nil) {
192 | bigCircle.animate(AnimationType.allValues[selectedAnimation],
193 | curve: AnimationEasingCurve.allValues[selectedEasingCurve],
194 | duration: CGFloat(duration.currentValue),
195 | delay: CGFloat(delay.currentValue),
196 | force: CGFloat(force.currentValue),
197 | damping: CGFloat(damping.currentValue),
198 | velocity: CGFloat(velocity.currentValue),
199 | fromRotation: CGFloat(rotate.currentValue),
200 | fromScale: CGFloat(scale.currentValue),
201 | fromX: CGFloat(xPoint.currentValue),
202 | fromY: CGFloat(yPoint.currentValue))
203 | }
204 |
205 | @IBAction func forceAction(sender: UIButton) {
206 | force.currentValue = sender.titleLabel!.text == "+" ? force.currentValue + force.stepValue : force.currentValue - force.stepValue
207 | updateForceUI()
208 | animateView()
209 | }
210 | func updateForceUI() {
211 | forceLabel.text = String(format: "%.1f", force.currentValue)
212 | }
213 |
214 | @IBAction func durationAction(sender: UIButton) {
215 | duration.currentValue = sender.titleLabel!.text == "+" ? duration.currentValue + duration.stepValue : duration.currentValue - duration.stepValue
216 | updateDurationUI()
217 | animateView()
218 | }
219 | func updateDurationUI() {
220 | durationLabel.text = String(format: "%.1f", duration.currentValue)
221 | }
222 |
223 | @IBAction func delayAction(sender: UIButton) {
224 | delay.currentValue = sender.titleLabel!.text == "+" ? delay.currentValue + delay.stepValue : delay.currentValue - delay.stepValue
225 | updateDelayUI()
226 | animateView()
227 | }
228 | func updateDelayUI() {
229 | delayLabel.text = String(format: "%.1f", delay.currentValue)
230 | }
231 |
232 | @IBAction func scaleAction(sender: UIButton) {
233 | scale.currentValue = sender.titleLabel!.text == "+" ? scale.currentValue + scale.stepValue : scale.currentValue - scale.stepValue
234 | updateScaleUI()
235 | animateView()
236 | }
237 | func updateScaleUI() {
238 | scaleLabel.text = String(format: "%.1f", scale.currentValue)
239 | }
240 |
241 | @IBAction func rotateAction(sender: UIButton) {
242 | rotate.currentValue = sender.titleLabel!.text == "+" ? rotate.currentValue + rotate.stepValue : rotate.currentValue - rotate.stepValue
243 | updateRotateUI()
244 | animateView()
245 | }
246 | func updateRotateUI() {
247 | rotateLabel.text = String(format: "%.1f", rotate.currentValue)
248 | }
249 |
250 | @IBAction func dampingAction(sender: UIButton) {
251 | damping.currentValue = sender.titleLabel!.text == "+" ? damping.currentValue + damping.stepValue : damping.currentValue - damping.stepValue
252 | updateDampingUI()
253 | animateView()
254 | }
255 | func updateDampingUI() {
256 | dampingLabel.text = String(format: "%.1f", damping.currentValue)
257 | }
258 |
259 | @IBAction func velocityAction(sender: UIButton) {
260 | velocity.currentValue = sender.titleLabel!.text == "+" ? velocity.currentValue + velocity.stepValue : velocity.currentValue - velocity.stepValue
261 | updateVelocityUI()
262 | animateView()
263 | }
264 | func updateVelocityUI() {
265 | velocityLabel.text = String(format: "%.1f", velocity.currentValue)
266 | }
267 |
268 | @IBAction func xAction(sender: UIButton) {
269 | xPoint.currentValue = sender.titleLabel!.text == "+" ? xPoint.currentValue + xPoint.stepValue : xPoint.currentValue - xPoint.stepValue
270 | updateXPointUI()
271 | animateView()
272 | }
273 | func updateXPointUI() {
274 | xPointLabel.text = String(format: "%.1f", xPoint.currentValue)
275 | }
276 |
277 | @IBAction func yAction(sender: UIButton) {
278 | yPoint.currentValue = sender.titleLabel!.text == "+" ? yPoint.currentValue + yPoint.stepValue : yPoint.currentValue - yPoint.stepValue
279 | updateYPointUI()
280 | animateView()
281 | }
282 | func updateYPointUI() {
283 | yPointLabel.text = String(format: "%.1f", yPoint.currentValue)
284 | }
285 |
286 | func updateAnimationUI() {
287 | selectedAnimation = UserDefaults.standard.integer(forKey: selectedAnimationKey)
288 | animation.setTitle("Animation: \(AnimationType.allValues[selectedAnimation]) ⋯", for: .normal)
289 | }
290 |
291 | func updateEasingCurveUI() {
292 | selectedEasingCurve = UserDefaults.standard.integer(forKey: selectedEasingCurveKey)
293 | curve.setTitle("Curve: \(AnimationEasingCurve.allValues[selectedEasingCurve]) ⋯", for: .normal)
294 | }
295 |
296 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
297 | let controller = segue.destination as! TableViewController
298 | if segue.identifier == "Animation" {
299 | controller.items = AnimationType.allValues.map { $0.description }
300 | controller.selected = selectedAnimation
301 | controller.title = selectedAnimationKey
302 | } else {
303 | controller.items = AnimationEasingCurve.allValues.map { $0.description }
304 | controller.selected = selectedEasingCurve
305 | controller.title = selectedEasingCurveKey
306 | }
307 |
308 | }
309 |
310 | func updateUIFromTableViewControllerAction(){
311 |
312 | }
313 |
314 | @IBAction func unwindToThisViewController(segue: UIStoryboardSegue) {
315 | print("here")
316 | let controller = segue.source as! TableViewController
317 | if controller.title == selectedAnimationKey {
318 | selectedAnimation = controller.selected
319 | updateAnimationUI()
320 | } else {
321 | selectedEasingCurve = controller.selected
322 | updateEasingCurveUI()
323 | }
324 | }
325 |
326 |
327 | }
328 |
329 |
--------------------------------------------------------------------------------