├── .gitignore ├── Configs ├── Windless.plist └── WindlessTests.plist ├── Example ├── AppDelegate.swift ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ ├── Contents.json │ ├── background.imageset │ │ ├── Contents.json │ │ └── snow-man-2933588_640.jpg │ ├── star.imageset │ │ ├── Contents.json │ │ └── if_star_285661.png │ └── user.imageset │ │ ├── Contents.json │ │ └── user-2935373_640.png ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── BasicViewController.swift ├── Info.plist ├── ListViewController.swift └── TableViewController.swift ├── LICENSE ├── Package.swift ├── README.md ├── Resource ├── basic.gif ├── collection.gif ├── configu1.png ├── configu2.png ├── configu3.png ├── example1.png ├── multi1.png ├── multi2.png ├── multitext.png ├── result1.png ├── result2.png ├── result3.png ├── sample-1.png ├── sample.gif └── table.gif ├── Sources ├── AnimationFactory.swift ├── CAMediaTimingFunction+Windless.swift ├── Constant+Windless.swift ├── Maker.swift ├── MultipleLines.swift ├── TransitionFactory.swift ├── UIView+Windless.swift ├── Windless.swift ├── WindlessConfiguration.swift ├── WindlessContext.swift ├── WindlessLayer.swift └── WindlessOptions.swift ├── Tests ├── LinuxMain.swift └── WindlessTests │ └── WindlessTests.swift ├── Windless.podspec └── Windless.xcodeproj ├── project.pbxproj ├── project.xcworkspace └── contents.xcworkspacedata └── xcshareddata └── xcschemes └── Windless-iOS.xcscheme /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xccheckout 23 | *.xcscmblueprint 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | *.ipa 28 | *.dSYM.zip 29 | *.dSYM 30 | 31 | ## Playgrounds 32 | timeline.xctimeline 33 | playground.xcworkspace 34 | 35 | # Swift Package Manager 36 | # 37 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 38 | # Packages/ 39 | # Package.pins 40 | .build/ 41 | 42 | # CocoaPods 43 | # 44 | # We recommend against adding the Pods directory to your .gitignore. However 45 | # you should judge for yourself, the pros and cons are mentioned at: 46 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 47 | # 48 | # Pods/ 49 | 50 | # Carthage 51 | # 52 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 53 | # Carthage/Checkouts 54 | 55 | Carthage/Build 56 | 57 | # fastlane 58 | # 59 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 60 | # screenshots whenever they are needed. 61 | # For more information about the recommended setup visit: 62 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 63 | 64 | fastlane/report.xml 65 | fastlane/Preview.html 66 | fastlane/screenshots 67 | fastlane/test_output 68 | -------------------------------------------------------------------------------- /Configs/Windless.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 | 0.1 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSHumanReadableCopyright 24 | Copyright © 2017 gwangbeom. All rights reserved. 25 | NSPrincipalClass 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Configs/WindlessTests.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 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /Example/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Example 4 | // 5 | // Created by gwangbeom on 2017. 10. 26.. 6 | // Copyright © 2017년 Windless. 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 | -------------------------------------------------------------------------------- /Example/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /Example/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Example/Assets.xcassets/background.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "snow-man-2933588_640.jpg", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Example/Assets.xcassets/background.imageset/snow-man-2933588_640.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParkGwangBeom/Windless/a2a0c0f5b3b75db6d5b7049b0d0b2163ac66cae3/Example/Assets.xcassets/background.imageset/snow-man-2933588_640.jpg -------------------------------------------------------------------------------- /Example/Assets.xcassets/star.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "if_star_285661.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Example/Assets.xcassets/star.imageset/if_star_285661.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParkGwangBeom/Windless/a2a0c0f5b3b75db6d5b7049b0d0b2163ac66cae3/Example/Assets.xcassets/star.imageset/if_star_285661.png -------------------------------------------------------------------------------- /Example/Assets.xcassets/user.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "user-2935373_640.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Example/Assets.xcassets/user.imageset/user-2935373_640.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParkGwangBeom/Windless/a2a0c0f5b3b75db6d5b7049b0d0b2163ac66cae3/Example/Assets.xcassets/user.imageset/user-2935373_640.png -------------------------------------------------------------------------------- /Example/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Example/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 62 | 75 | 87 | 88 | 89 | 90 | 91 | 92 | Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 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 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 235 | 251 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 337 | 353 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | -------------------------------------------------------------------------------- /Example/BasicViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // Example 4 | // 5 | // Created by gwangbeom on 2017. 10. 26.. 6 | // Copyright © 2017년 Windless. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import Windless 11 | 12 | class BasicViewController: UIViewController { 13 | 14 | @IBOutlet weak var contentsView: UIView! 15 | @IBOutlet weak var view1: UIImageView! 16 | @IBOutlet weak var view2: UILabel! 17 | @IBOutlet weak var view3: UILabel! 18 | @IBOutlet weak var view4: UIImageView! 19 | @IBOutlet weak var view5: UILabel! 20 | var flag = true 21 | 22 | override func viewDidLoad() { 23 | super.viewDidLoad() 24 | self.title = "Basic" 25 | view4.layer.cornerRadius = view4.frame.width / 2 26 | 27 | contentsView.windless 28 | .start() 29 | } 30 | 31 | @IBAction func tapped(_ sender: Any) { 32 | flag = !flag 33 | flag ? contentsView.windless.start() : contentsView.windless.end() 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Example/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /Example/ListViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ListViewController.swift 3 | // Example 4 | // 5 | // Created by gwangbeom on 2017. 11. 5.. 6 | // Copyright © 2017년 Windless. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | enum Items: String { 12 | case basic 13 | case table 14 | 15 | static var all: [Items] { 16 | return [.basic, .table] 17 | } 18 | } 19 | 20 | class ListViewController: UIViewController { 21 | 22 | override func viewDidLoad() { 23 | super.viewDidLoad() 24 | self.title = "Examples" 25 | } 26 | } 27 | 28 | extension ListViewController: UITableViewDataSource { 29 | 30 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 31 | return Items.all.count 32 | } 33 | 34 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 35 | let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) 36 | cell.textLabel?.text = Items.all[indexPath.row].rawValue 37 | cell.accessoryType = .disclosureIndicator 38 | return cell 39 | } 40 | } 41 | 42 | extension ListViewController: UITableViewDelegate { 43 | 44 | func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 45 | tableView.deselectRow(at: indexPath, animated: true) 46 | performSegue(withIdentifier: Items.all[indexPath.row].rawValue, sender: nil) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Example/TableViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TableViewController.swift 3 | // Example 4 | // 5 | // Created by gwangbeom on 2017. 10. 26.. 6 | // Copyright © 2017년 Windless. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import Windless 11 | 12 | class TableViewController: UIViewController { 13 | 14 | @IBOutlet weak var tableView: UITableView! 15 | 16 | lazy var randoms: [Int] = { 17 | var values: [Int] = [] 18 | for _ in 0..<10 { 19 | let random = arc4random() % 2 20 | values.append(Int(random)) 21 | } 22 | return values 23 | }() 24 | 25 | var flag = true 26 | 27 | override func viewDidLoad() { 28 | super.viewDidLoad() 29 | self.title = "Table" 30 | tableView.windless 31 | .apply { 32 | $0.beginTime = 2 33 | $0.duration = 4 34 | $0.animationLayerOpacity = 0.5 35 | } 36 | .start() 37 | } 38 | 39 | @IBAction func tapped(_ sender: Any) { 40 | flag = !flag 41 | flag ? tableView.windless.start() : tableView.windless.end() 42 | } 43 | } 44 | 45 | extension TableViewController: UITableViewDataSource { 46 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 47 | return 10 48 | } 49 | 50 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 51 | let identifier = "cell\(randoms[indexPath.row])" 52 | let cell = tableView.dequeueReusableCell(withIdentifier: identifier, for: indexPath) as! TestCell 53 | return cell 54 | } 55 | } 56 | 57 | class TestCell: UITableViewCell { 58 | 59 | @IBOutlet weak var view1: UIImageView! 60 | @IBOutlet weak var view2: UILabel! 61 | @IBOutlet weak var view3: UILabel! 62 | @IBOutlet weak var view4: UILabel! 63 | 64 | override func awakeFromNib() { 65 | super.awakeFromNib() 66 | view1.layer.cornerRadius = view1.frame.width / 2 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 gwangbeom 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:4.0 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "Windless", 8 | products: [ 9 | // Products define the executables and libraries produced by a package, and make them visible to other packages. 10 | .library( 11 | name: "Windless", 12 | targets: ["Windless"]), 13 | ], 14 | dependencies: [ 15 | // Dependencies declare other packages that this package depends on. 16 | // .package(url: /* package url */, from: "1.0.0"), 17 | ], 18 | targets: [ 19 | // Targets are the basic building blocks of a package. A target can define a module or a test suite. 20 | // Targets can depend on other targets in this package, and on products in packages which this package depends on. 21 | .target( 22 | name: "Windless", 23 | dependencies: []), 24 | .testTarget( 25 | name: "WindlessTests", 26 | dependencies: ["Windless"]), 27 | ] 28 | ) 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Windless 2 | 3 | [![Carthage compatible](https://img.shields.io/badge/Carthage-Compatible-brightgreen.svg?style=flat)](https://github.com/Carthage/Carthage) 4 | [![Version](https://img.shields.io/cocoapods/v/Hero.svg?style=flat)](http://cocoapods.org/pods/Hero) 5 | ![Xcode 9.0+](https://img.shields.io/badge/Xcode-9.0%2B-blue.svg) 6 | ![iOS 8.0+](https://img.shields.io/badge/iOS-8.0%2B-blue.svg) 7 | ![Swift 4.0+](https://img.shields.io/badge/Swift-4.0%2B-orange.svg) 8 | [![License](https://img.shields.io/cocoapods/l/Hero.svg?style=flat)](https://github.com/lkzhao/Hero/blob/master/LICENSE?raw=true) 9 | 10 | **Windless** makes it easy to implement invisible layout loading view. 11 | 12 | 13 | 14 | 17 | 20 | 23 | 24 |
15 | 16 | 18 | 19 | 21 | 22 |
25 | 26 | ## Contents 27 | 28 | - [Requirements](#requirements) 29 | - [Installation](#installation) 30 | - [Usage](#usage) 31 | - [Looks](#looks) 32 | - [Credits](#credits) 33 | - [Communication](#communication) 34 | - [License](#license) 35 | 36 | ## Requirements 37 | 38 | - iOS 8.0+ 39 | - Xcode 9.0+ 40 | - Swift 4.0+ 41 | 42 | ## Installation 43 | 44 | ### CocoaPods 45 | 46 | [CocoaPods](http://cocoapods.org) is a dependency manager for Cocoa projects. You can install it with the following command: 47 | 48 | ```bash 49 | $ gem install cocoapods 50 | ``` 51 | 52 | > CocoaPods 1.1+ is required to build Windless 4.0+. 53 | 54 | To integrate Windless into your Xcode project using CocoaPods, specify it in your `Podfile`: 55 | 56 | ```ruby 57 | source 'https://github.com/CocoaPods/Specs.git' 58 | platform :ios, '8.0' 59 | use_frameworks! 60 | 61 | target '' do 62 | pod 'Windless', '~> 0.1.5' 63 | end 64 | ``` 65 | 66 | Then, run the following command: 67 | 68 | ```bash 69 | $ pod install 70 | ``` 71 | 72 | ### Carthage 73 | 74 | [Carthage](https://github.com/Carthage/Carthage) is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks. 75 | 76 | You can install Carthage with [Homebrew](http://brew.sh/) using the following command: 77 | 78 | ```bash 79 | $ brew update 80 | $ brew install carthage 81 | ``` 82 | 83 | To integrate Windless into your Xcode project using Carthage, specify it in your `Cartfile`: 84 | 85 | ```ogdl 86 | github "Interactive-Studio/Windless" ~> 0.1.5 87 | ``` 88 | 89 | Run `carthage update` to build the framework and drag the built `Windless.framework` into your Xcode project. 90 | 91 | ### Manually 92 | 93 | If you prefer not to use either of the aforementioned dependency managers, you can integrate Windless into your project manually. 94 | 95 | --- 96 | 97 | ## Usage 98 | 99 | 100 | 101 | ### Code 102 | 103 | ```swift 104 | import Windless 105 | 106 | class ViewController: UIViewController { 107 | 108 | lazy var contentsView = UIView() 109 | 110 | var subView1 = UIView() 111 | var subView2 = UIView() 112 | 113 | override func viewDidLoad() { 114 | super.viewDidLoad() 115 | 116 | self.view.addSubview(contentsView) 117 | contentsView.addSubview(subView1) 118 | contentsView.addSubview(subView2) 119 | 120 | // start 121 | contentsView.windless 122 | .setupWindlessableViews([subView1, subView2]) 123 | .start() 124 | 125 | // stop 126 | contentsView.windless.end() 127 | } 128 | 129 | } 130 | ``` 131 | 132 | ### Storyboard, Xib 133 | 134 | If you use **Storyboard** or **xib**, you only need to set the `isWindlessable` flag to true for the views you want to show as fake in the view inspector of the view, and you do not have to pass the view through the `setupWindlessableViews` method. 135 | 136 | 137 | 138 | ```swift 139 | import Windless 140 | 141 | class ViewController: UIViewController { 142 | 143 | @IBOutlet weak var contentsView: UIView! 144 | 145 | override func viewDidLoad() { 146 | super.viewDidLoad() 147 | 148 | contentsView.windless.start() 149 | } 150 | } 151 | ``` 152 | 153 | ### Multiline 154 | 155 | Depending on the `lineHeight` value and the` spacing` value, UILabel and UITextView will reconstruct the layout when the windless animation runs. 156 | 157 | 158 | 159 | ```swift 160 | public protocol CanBeMultipleLines { 161 | 162 | var lineHeight: CGFloat { get set } 163 | 164 | var spacing: CGFloat { get set } 165 | } 166 | ``` 167 | 168 | | Configuration | Result 169 | |------- | ------- 170 | | | 171 | 172 | ### Custom Options 173 | 174 | There are several customizable options in **Windless**. 175 | 176 | ```swift 177 | public class WindlessConfiguration { 178 | 179 | /// The direction of windless animation. Defaults to rightDiagonal. 180 | public var direction: WindlessDirection = .rightDiagonal 181 | 182 | /// The speed of windless animation. Defaults to 1. 183 | public var speed: Float = 1 184 | 185 | /// The duration of the fade used when windless begins. Defaults to 0. 186 | public var beginTime: CFTimeInterval = 0 187 | 188 | /// The time interval windless in seconds. Defaults to 4. 189 | public var duration: CFTimeInterval = 4 190 | 191 | /// The time interval between windless in seconds. Defaults to 2. 192 | public var pauseDuration: CFTimeInterval = 2 193 | 194 | /// gradient animation timingFunction default easeOut 195 | public var timingFuction: CAMediaTimingFunction = .easeOut 196 | 197 | /// gradient layer center color default .lightGray 198 | public var animationLayerColor: UIColor = .lightGray 199 | 200 | /// Mask layer background color default .groupTableViewBackground 201 | public var animationBackgroundColor: UIColor = .groupTableViewBackground 202 | 203 | /// The opacity of the content while it is windless. Defaults to 0.8. 204 | public var animationLayerOpacity: CGFloat = 0.8 205 | } 206 | ``` 207 | 208 | To set the options, use the apply method as shown below. 209 | 210 | ```swift 211 | import Windless 212 | 213 | class ViewController: UIViewController { 214 | 215 | @IBOutlet weak var contentsView: UIView! 216 | 217 | override func viewDidLoad() { 218 | super.viewDidLoad() 219 | 220 | contentsView.windless 221 | .apply { 222 | $0.beginTime = 1 223 | $0.pauseDuration = 2 224 | $0.duration = 3 225 | $0.animationLayerOpacity = 0.5 226 | } 227 | .start() 228 | } 229 | } 230 | ``` 231 | 232 | If you want to know more detailed usage, please refer to Example. 233 | 234 | ## Looks 235 | 236 | The `isWindlessable` value determines how the loading view looks. The images below show how the loading screen will look according to the `isWindlessable` value. 237 | 238 | > ```isWindlessable```= 🌀 239 | 240 | | Configuration | Result 241 | |------- | ------- 242 | | | 243 | | | 244 | | | 245 | 246 | ## Communication 247 | 248 | - If you **found a bug**, open an issue. 249 | - If you **have a feature request**, open an issue. 250 | - If you **want to contribute**, submit a pull request. 251 | 252 | ## Credits 253 | 254 | - GwangBeom Park ([@gwangbeom](https://github.com/ParkGwangBeom)) 255 | 256 | ## License 257 | 258 | Windless is released under the MIT license. See LICENSE for details. 259 | 260 | -------------------------------------------------------------------------------- /Resource/basic.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParkGwangBeom/Windless/a2a0c0f5b3b75db6d5b7049b0d0b2163ac66cae3/Resource/basic.gif -------------------------------------------------------------------------------- /Resource/collection.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParkGwangBeom/Windless/a2a0c0f5b3b75db6d5b7049b0d0b2163ac66cae3/Resource/collection.gif -------------------------------------------------------------------------------- /Resource/configu1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParkGwangBeom/Windless/a2a0c0f5b3b75db6d5b7049b0d0b2163ac66cae3/Resource/configu1.png -------------------------------------------------------------------------------- /Resource/configu2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParkGwangBeom/Windless/a2a0c0f5b3b75db6d5b7049b0d0b2163ac66cae3/Resource/configu2.png -------------------------------------------------------------------------------- /Resource/configu3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParkGwangBeom/Windless/a2a0c0f5b3b75db6d5b7049b0d0b2163ac66cae3/Resource/configu3.png -------------------------------------------------------------------------------- /Resource/example1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParkGwangBeom/Windless/a2a0c0f5b3b75db6d5b7049b0d0b2163ac66cae3/Resource/example1.png -------------------------------------------------------------------------------- /Resource/multi1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParkGwangBeom/Windless/a2a0c0f5b3b75db6d5b7049b0d0b2163ac66cae3/Resource/multi1.png -------------------------------------------------------------------------------- /Resource/multi2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParkGwangBeom/Windless/a2a0c0f5b3b75db6d5b7049b0d0b2163ac66cae3/Resource/multi2.png -------------------------------------------------------------------------------- /Resource/multitext.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParkGwangBeom/Windless/a2a0c0f5b3b75db6d5b7049b0d0b2163ac66cae3/Resource/multitext.png -------------------------------------------------------------------------------- /Resource/result1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParkGwangBeom/Windless/a2a0c0f5b3b75db6d5b7049b0d0b2163ac66cae3/Resource/result1.png -------------------------------------------------------------------------------- /Resource/result2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParkGwangBeom/Windless/a2a0c0f5b3b75db6d5b7049b0d0b2163ac66cae3/Resource/result2.png -------------------------------------------------------------------------------- /Resource/result3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParkGwangBeom/Windless/a2a0c0f5b3b75db6d5b7049b0d0b2163ac66cae3/Resource/result3.png -------------------------------------------------------------------------------- /Resource/sample-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParkGwangBeom/Windless/a2a0c0f5b3b75db6d5b7049b0d0b2163ac66cae3/Resource/sample-1.png -------------------------------------------------------------------------------- /Resource/sample.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParkGwangBeom/Windless/a2a0c0f5b3b75db6d5b7049b0d0b2163ac66cae3/Resource/sample.gif -------------------------------------------------------------------------------- /Resource/table.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParkGwangBeom/Windless/a2a0c0f5b3b75db6d5b7049b0d0b2163ac66cae3/Resource/table.gif -------------------------------------------------------------------------------- /Sources/AnimationFactory.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AnimationFactory.swift 3 | // Windless-iOS 4 | // 5 | // Created by gwangbeom on 2017. 11. 12.. 6 | // Copyright © 2017년 Windless. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | enum AnimationType: String { 12 | case locations 13 | case scale 14 | case position 15 | 16 | var animation: CABasicAnimation { 17 | return CABasicAnimation(keyPath: rawValue) 18 | } 19 | } 20 | 21 | // TODO: add animation 22 | class AnimationFactory { 23 | 24 | fileprivate var configuration: WindlessConfiguration 25 | init(configuration: WindlessConfiguration) { 26 | self.configuration = configuration 27 | } 28 | 29 | func makeAnimation(type: AnimationType, from: T, to: T) -> CAAnimation { 30 | let animation = type.animation 31 | animation.fromValue = from 32 | animation.toValue = to 33 | animation.duration = configuration.duration 34 | return animation 35 | } 36 | 37 | func makeGroupAnimation(_ animations: [CAAnimation]) -> CAAnimation { 38 | let groupAnimation = CAAnimationGroup() 39 | groupAnimation.animations = animations 40 | groupAnimation.beginTime = CACurrentMediaTime() + configuration.beginTime 41 | groupAnimation.duration = configuration.duration + configuration.pauseDuration 42 | groupAnimation.speed = configuration.speed 43 | groupAnimation.timingFunction = configuration.timingFuction 44 | groupAnimation.repeatCount = .infinity 45 | return groupAnimation 46 | } 47 | } 48 | 49 | extension AnimationFactory { 50 | 51 | func locationAnimation() -> CAAnimation { 52 | let animation = makeAnimation(type: .locations, from: DefaultValue.Animation.Locations.from, to: DefaultValue.Animation.Locations.to) 53 | return makeGroupAnimation([animation]) 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Sources/CAMediaTimingFunction+Windless.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CAMediaTimingFunction+Windless.swift 3 | // Windless-iOS 4 | // 5 | // Created by gwangbeom on 2017. 11. 8.. 6 | // Copyright © 2017년 Windless. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public extension CAMediaTimingFunction { 12 | 13 | static let linear = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear) 14 | 15 | static let easeIn = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn) 16 | 17 | static let easeOut = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut) 18 | 19 | static let easeInOut = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut) 20 | } 21 | -------------------------------------------------------------------------------- /Sources/Constant+Windless.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Constant+Windless.swift 3 | // Windless-iOS 4 | // 5 | // Created by gwangbeom on 2017. 11. 13.. 6 | // Copyright © 2017년 Windless. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | struct AnimationKeys { 12 | static let locations = "locations" 13 | } 14 | 15 | struct TransitionKeys { 16 | static let fade = "fade" 17 | } 18 | 19 | struct DefaultValue { 20 | struct Animation { 21 | struct Locations { 22 | static let from: [NSNumber] = [-0.4, -0.2, 0.0] 23 | static let to: [NSNumber] = [1.0, 2.5, 3] 24 | } 25 | } 26 | 27 | struct MultipleLine { 28 | static let lineHeight: CGFloat = 21 29 | static let lineSpacing: CGFloat = 10 30 | } 31 | } 32 | 33 | struct AssociatedKeys { 34 | struct MultiLine { 35 | static var lineHeight = "lineHeightKey" 36 | static var lineSpacing = "lineSpacingKey" 37 | } 38 | 39 | struct Windless { 40 | static var isWindlessable = "isWindlessableKey" 41 | static var windless = "windlessKey" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Sources/Maker.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Maker.swift 3 | // Windless-iOS 4 | // 5 | // Created by gwangbeom on 2017. 11. 12.. 6 | // Copyright © 2017년 Windless. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | // TODO: Refactorig 12 | struct Maker { 13 | 14 | struct Path { 15 | static func makeWindlessableLayersPath(in container: UIView) -> UIBezierPath { 16 | let path = UIBezierPath(rect: container.bounds) 17 | path.usesEvenOddFillRule = true 18 | container.subviewsHierarchy.filter{ $0.isWindlessable && !($0 is CanBeMultipleLines) }.forEach { 19 | let rect = $0.convert($0.bounds, to: container) 20 | let subviewPath = UIBezierPath(roundedRect: rect, cornerRadius: $0.layer.cornerRadius) 21 | path.append(subviewPath) 22 | } 23 | return path 24 | } 25 | } 26 | 27 | struct Layer { 28 | static func makeNotWindlessableLayers(in container: UIView) -> [CALayer] { 29 | return container.subviewsHierarchy 30 | .filter{ !$0.isWindlessable && $0 != container } 31 | .flatMap { 32 | let copy = CALayer(layer: $0.layer) 33 | copy.contents = $0.layer.contents 34 | copy.contentsGravity = $0.layer.contentsGravity 35 | copy.backgroundColor = $0.backgroundColor?.cgColor 36 | copy.cornerRadius = $0.layer.cornerRadius 37 | copy.masksToBounds = $0.layer.masksToBounds 38 | copy.contentsScale = $0.layer.contentsScale 39 | copy.frame = $0.convert($0.bounds, to: container) 40 | return copy 41 | } 42 | } 43 | } 44 | } 45 | 46 | extension UIView { 47 | 48 | var subviewsHierarchy: [UIView] { 49 | if superview is CanBeMultipleLines { 50 | return [] 51 | } else { 52 | return [self] + subviews.flatMap { $0.subviewsHierarchy } 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Sources/MultipleLines.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MultipleLines.swift 3 | // Windless-iOS 4 | // 5 | // Created by gwangbeom on 2017. 11. 13.. 6 | // Copyright © 2017년 Windless. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public protocol CanBeMultipleLines { 12 | 13 | var lineHeight: CGFloat { get set } 14 | 15 | var spacing: CGFloat { get set } 16 | } 17 | 18 | extension CanBeMultipleLines { 19 | 20 | // TODO: Refactoring 21 | func appendMultilineLayersPath(on path: UIBezierPath, frame: CGRect) { 22 | let numberOfLines = Int(round(frame.height / (lineHeight + spacing))) 23 | for index in 0.. CATransition { 14 | let transition = CATransition() 15 | transition.type = kCATransitionFade 16 | return transition 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Sources/UIView+Windless.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+Windless.swift 3 | // Windless-iOS 4 | // 5 | // Created by gwangbeom on 2017. 11. 8.. 6 | // Copyright © 2017년 Windless. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public extension UIView { 12 | 13 | /** 14 | **isWindlessable** allows the view to be composed of skeletons. 15 | If true, the view becomes the skeleton of the loading view and is exposed to the animation. Default false 16 | */ 17 | @IBInspectable var isWindlessable: Bool { 18 | get { return objc_getAssociatedObject(self, &AssociatedKeys.Windless.isWindlessable) as? Bool ?? false } 19 | set { objc_setAssociatedObject(self, &AssociatedKeys.Windless.isWindlessable, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) } 20 | } 21 | 22 | /** 23 | **windless** makes subviews with a true isWindlessable value of true as a loading view with a skeleton and helps control the animation. 24 | */ 25 | var windless: Windless { 26 | guard let windless = objc_getAssociatedObject(self, &AssociatedKeys.Windless.windless) as? Windless else { 27 | let windless = Windless(container: self) 28 | objc_setAssociatedObject(self, &AssociatedKeys.Windless.windless, windless, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) 29 | return windless 30 | } 31 | return windless 32 | } 33 | } 34 | 35 | -------------------------------------------------------------------------------- /Sources/Windless.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Windless.swift 3 | // Windless-iOS 4 | // 5 | // Created by gwangbeom on 2017. 11. 5.. 6 | // Copyright © 2017년 Windless. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public class Windless { 12 | 13 | fileprivate var configuration: WindlessConfiguration 14 | fileprivate var context: WindlessContext 15 | fileprivate var windlessLayer: WindlessLayer 16 | 17 | init(container: UIView) { 18 | container.setNeedsLayout() 19 | container.layoutIfNeeded() 20 | configuration = WindlessConfiguration() 21 | context = WindlessContext(container: container) 22 | windlessLayer = WindlessLayer(frame: container.bounds, context: context) 23 | } 24 | } 25 | 26 | // MARK: setup 27 | public extension Windless { 28 | 29 | /** 30 | **apply** helps you define the information you need for windless. 31 | 32 | - Parameters: 33 | - config: WindlessConfiguration 34 | */ 35 | @discardableResult 36 | func apply(_ setup: (WindlessConfiguration) -> Void) -> Self { 37 | setup(configuration) 38 | return self 39 | } 40 | 41 | /** 42 | Set the isWindlessable value of views to true 43 | 44 | - Parameters: 45 | - views: Views that will be the skeleton of the loading view 46 | */ 47 | @discardableResult 48 | func setupWindlessableViews(_ views: [UIView]) -> Self { 49 | views.forEach { $0.isWindlessable = true } 50 | return self 51 | } 52 | } 53 | 54 | // MARK: animation 55 | public extension Windless { 56 | 57 | // TODO: animation custom 58 | /// Start windless animation 59 | func start() { 60 | context.updateAnimationLayer(configuration: configuration) 61 | CATransaction.begin() 62 | CATransaction.setCompletionBlock { [weak self] in 63 | guard let `self` = self else { 64 | return 65 | } 66 | let animation = AnimationFactory(configuration: self.configuration).locationAnimation() 67 | self.context.start(animation) 68 | self.setupScrollEnabled(false) 69 | } 70 | let transition = TransitionFactory.fade() 71 | context.container.layer.add(transition, forKey: TransitionKeys.fade) 72 | context.container.layer.addSublayer(windlessLayer) 73 | CATransaction.commit() 74 | } 75 | 76 | /// End windless animation 77 | func end() { 78 | CATransaction.begin() 79 | CATransaction.setCompletionBlock { [weak self] in 80 | self?.context.end() 81 | self?.setupScrollEnabled(true) 82 | } 83 | let transition = TransitionFactory.fade() 84 | context.container.layer.add(transition, forKey: TransitionKeys.fade) 85 | windlessLayer.removeFromSuperlayer() 86 | CATransaction.commit() 87 | } 88 | } 89 | 90 | private extension Windless { 91 | 92 | func setupScrollEnabled(_ flag: Bool) { 93 | guard let scrollView = context.container as? UIScrollView else { 94 | return 95 | } 96 | scrollView.isScrollEnabled = flag 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /Sources/WindlessConfiguration.swift: -------------------------------------------------------------------------------- 1 | // 2 | // WindlessConfiguration.swift 3 | // Windless-iOS 4 | // 5 | // Created by gwangbeom on 2017. 11. 5.. 6 | // Copyright © 2017년 Windless. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | /** 12 | Objects that define windless animations and skeletons 13 | */ 14 | public class WindlessConfiguration { 15 | 16 | /// The direction of windless animation. Defaults to rightDiagonal. 17 | public var direction: WindlessDirection = .rightDiagonal 18 | 19 | /// The speed of windless animation. Defaults to 1. 20 | public var speed: Float = 1 21 | 22 | /// The duration of the fade used when windless begins. Defaults to 0. 23 | public var beginTime: CFTimeInterval = 0 24 | 25 | /// The time interval windless in seconds. Defaults to 4. 26 | public var duration: CFTimeInterval = 4 27 | 28 | /// The time interval between windless in seconds. Defaults to 2. 29 | public var pauseDuration: CFTimeInterval = 2 30 | 31 | /// gradient animation timingFunction default easeOut 32 | public var timingFuction: CAMediaTimingFunction = .easeOut 33 | 34 | /// gradient layer center color default .lightGray 35 | public var animationLayerColor: UIColor = .lightGray 36 | 37 | /// Mask layer background color default .groupTableViewBackground 38 | public var animationBackgroundColor: UIColor = .groupTableViewBackground 39 | 40 | /// The opacity of the content while it is windless. Defaults to 0.8. 41 | public var animationLayerOpacity: CGFloat = 0.8 42 | } 43 | -------------------------------------------------------------------------------- /Sources/WindlessContext.swift: -------------------------------------------------------------------------------- 1 | // 2 | // WindlessContext.swift 3 | // Windless-iOS 4 | // 5 | // Created by gwangbeom on 2017. 11. 12.. 6 | // Copyright © 2017년 Windless. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | enum LayerType { 12 | case animation 13 | case cover 14 | } 15 | 16 | class WindlessContext { 17 | 18 | weak var container: UIView! 19 | fileprivate var animationLayer = CAGradientLayer() 20 | fileprivate var coverLayer = CAShapeLayer() 21 | 22 | init(container: UIView) { 23 | self.container = container 24 | animationLayer.frame = container.bounds 25 | coverLayer.frame = container.bounds 26 | coverLayer.backgroundColor = container.backgroundColor?.cgColor 27 | } 28 | 29 | func layer(for type: LayerType) -> CALayer { 30 | switch type { 31 | case .animation: return animationLayer 32 | case .cover: return coverLayer 33 | } 34 | } 35 | } 36 | 37 | // MARK: internal 38 | extension WindlessContext { 39 | 40 | // TODO: customizing 41 | func updateAnimationLayer(configuration: WindlessConfiguration) { 42 | animationLayer.startPoint = configuration.direction.location.start 43 | animationLayer.endPoint = configuration.direction.location.end 44 | animationLayer.colors = [configuration.animationBackgroundColor, 45 | configuration.animationLayerColor.withAlphaComponent(configuration.animationLayerOpacity), 46 | configuration.animationBackgroundColor].flatMap{ $0.cgColor } 47 | animationLayer.locations = DefaultValue.Animation.Locations.from 48 | animationLayer.backgroundColor = configuration.animationBackgroundColor.cgColor 49 | } 50 | 51 | func updateMask() { 52 | let path = Maker.Path.makeWindlessableLayersPath(in: container) 53 | appendMultilineLayersPathIfNeeded(on: path) 54 | let maskLayer = CAShapeLayer() 55 | maskLayer.path = path.cgPath 56 | maskLayer.fillRule = kCAFillRuleEvenOdd 57 | coverLayer.mask = maskLayer 58 | } 59 | 60 | func updateLayerFrame(_ frame: CGRect) { 61 | animationLayer.frame = frame 62 | coverLayer.frame = frame 63 | } 64 | } 65 | 66 | // MARK: animation 67 | extension WindlessContext { 68 | 69 | func start(_ animation: CAAnimation) { 70 | animationLayer.add(animation, forKey: AnimationKeys.locations) 71 | } 72 | 73 | func end() { 74 | animationLayer.removeAnimation(forKey: AnimationKeys.locations) 75 | } 76 | } 77 | 78 | // TODO: Refactorig 79 | private extension WindlessContext { 80 | 81 | func appendMultilineLayersPathIfNeeded(on path: UIBezierPath) { 82 | container.subviewsHierarchy.filter{ $0.isWindlessable && $0 is CanBeMultipleLines }.forEach { 83 | let rect = $0.convert($0.bounds, to: container) 84 | ($0 as? CanBeMultipleLines)?.appendMultilineLayersPath(on: path, frame: rect) 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /Sources/WindlessLayer.swift: -------------------------------------------------------------------------------- 1 | // 2 | // WindlessLayer.swift 3 | // Windless-iOS 4 | // 5 | // Created by gwangbeom on 2017. 11. 5.. 6 | // Copyright © 2017년 Windless. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class WindlessLayer: CALayer { 12 | 13 | private var context: WindlessContext 14 | init(frame: CGRect, context: WindlessContext) { 15 | self.context = context 16 | super.init() 17 | self.frame = frame 18 | addSublayer(context.layer(for: .animation)) 19 | addSublayer(context.layer(for: .cover)) 20 | Maker.Layer.makeNotWindlessableLayers(in: context.container).forEach { 21 | context.layer(for: .cover).addSublayer($0) 22 | } 23 | } 24 | 25 | required init?(coder aDecoder: NSCoder) { 26 | fatalError("init(coder:) has not been implemented") 27 | } 28 | 29 | override func layoutSublayers() { 30 | super.layoutSublayers() 31 | context.updateLayerFrame(bounds) 32 | context.updateMask() 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Sources/WindlessOptions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // WindlessOptions.swift 3 | // Windless-iOS 4 | // 5 | // Created by gwangbeom on 2017. 11. 8.. 6 | // Copyright © 2017년 Windless. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | struct Location { 12 | var start: CGPoint 13 | var end: CGPoint 14 | } 15 | 16 | public enum WindlessDirection: Int { 17 | 18 | /// Windless animation goes from left to right 19 | case right 20 | 21 | /// Windless animation goes from left to right diagonal 22 | case rightDiagonal 23 | 24 | /// Windless animation goes from right to left 25 | case left 26 | 27 | /// Windless animation goes from right to left diagonal 28 | case leftDiagonal 29 | 30 | /// Windless animation goes from down to up 31 | case up 32 | 33 | /// Windless animation goes from up to down 34 | case down 35 | 36 | var location: Location { 37 | switch self { 38 | case .right: 39 | return Location(start: CGPoint(x: 0, y: 0.5), end: CGPoint(x: 1, y: 0.5)) 40 | case .rightDiagonal: 41 | return Location(start: CGPoint(x: 0, y: 0.0), end: CGPoint(x: 1, y: 1)) 42 | case .left: 43 | return Location(start: CGPoint(x: 1, y: 0.5), end: CGPoint(x: 0, y: 0.5)) 44 | case .leftDiagonal: 45 | return Location(start: CGPoint(x: 1, y: 1), end: CGPoint(x: 0, y: 0)) 46 | case .up: 47 | return Location(start: CGPoint(x: 0.5, y: 1), end: CGPoint(x: 0.5, y: 0)) 48 | case .down: 49 | return Location(start: CGPoint(x: 0.5, y: 0), end: CGPoint(x: 0.5, y: 1)) 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Tests/LinuxMain.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | @testable import WindlessTests 3 | 4 | XCTMain([ 5 | testCase(WindlessTests.allTests), 6 | ]) 7 | -------------------------------------------------------------------------------- /Tests/WindlessTests/WindlessTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // WindlessTests.swift 3 | // Windless 4 | // 5 | // Created by gwangbeom on {TODAY}. 6 | // Copyright © 2017 Windless. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import XCTest 11 | import Windless 12 | 13 | class WindlessTests: XCTestCase { 14 | func testExample() { 15 | // This is an example of a functional test case. 16 | // Use XCTAssert and related functions to verify your tests produce the correct results. 17 | //// XCTAssertEqual(Windless().text, "Hello, World!") 18 | } 19 | 20 | static var allTests = [ 21 | ("testExample", testExample), 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /Windless.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "Windless" 3 | s.version = "0.1.5" 4 | s.summary = "loading view" 5 | s.description = "Windless makes it easy to implement invisible layout loading view." 6 | s.homepage = "https://github.com/Interactive-Studio/Windless" 7 | s.license = { :type => "MIT", :file => "LICENSE" } 8 | s.author = { "gwangbeom" => "battlerhkqo@naver.com" } 9 | s.ios.deployment_target = "8.0" 10 | s.source = { :git => "https://github.com/Interactive-Studio/Windless.git", :tag => s.version.to_s } 11 | s.source_files = "Sources/**/*" 12 | end 13 | -------------------------------------------------------------------------------- /Windless.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 47; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 4A1179411FAEEFA000164FC4 /* WindlessLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A1179401FAEEFA000164FC4 /* WindlessLayer.swift */; }; 11 | 4A1179431FAEFCC700164FC4 /* WindlessConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A1179421FAEFCC700164FC4 /* WindlessConfiguration.swift */; }; 12 | 4A1179451FAF1EBB00164FC4 /* ListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A1179441FAF1EBB00164FC4 /* ListViewController.swift */; }; 13 | 4A1C00B91FA102E5006DEA4C /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A1C00B81FA102E5006DEA4C /* AppDelegate.swift */; }; 14 | 4A1C00BB1FA102E5006DEA4C /* BasicViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A1C00BA1FA102E5006DEA4C /* BasicViewController.swift */; }; 15 | 4A1C00BE1FA102E5006DEA4C /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4A1C00BC1FA102E5006DEA4C /* Main.storyboard */; }; 16 | 4A1C00C01FA102E5006DEA4C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4A1C00BF1FA102E5006DEA4C /* Assets.xcassets */; }; 17 | 4A1C00C31FA102E5006DEA4C /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4A1C00C11FA102E5006DEA4C /* LaunchScreen.storyboard */; }; 18 | 4A1C00CD1FA1AB80006DEA4C /* TableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A1C00CC1FA1AB80006DEA4C /* TableViewController.swift */; }; 19 | 4A29B6E31FB9D13300F5B6E4 /* MultipleLines.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A29B6E21FB9D13300F5B6E4 /* MultipleLines.swift */; }; 20 | 4A29B6E61FBA018C00F5B6E4 /* MultipleLines.swift in Headers */ = {isa = PBXBuildFile; fileRef = 4A29B6E21FB9D13300F5B6E4 /* MultipleLines.swift */; settings = {ATTRIBUTES = (Public, ); }; }; 21 | 4A2F5D9E1FB8686800E0A6F5 /* WindlessContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A2F5D9D1FB8686800E0A6F5 /* WindlessContext.swift */; }; 22 | 4A51527A1FB88F3400BD905F /* AnimationFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A5152781FB88EE400BD905F /* AnimationFactory.swift */; }; 23 | 4A51527B1FB892EA00BD905F /* Windless.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52D6D97C1BEFF229002C0205 /* Windless.framework */; }; 24 | 4A51527C1FB892EA00BD905F /* Windless.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 52D6D97C1BEFF229002C0205 /* Windless.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 25 | 4A5152801FB8935F00BD905F /* Maker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A51527F1FB8935F00BD905F /* Maker.swift */; }; 26 | 4A5152821FB8AED700BD905F /* Constant+Windless.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A5152811FB8AED700BD905F /* Constant+Windless.swift */; }; 27 | 4A5152841FB8AEF300BD905F /* TransitionFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A5152831FB8AEF300BD905F /* TransitionFactory.swift */; }; 28 | 4A68FF851FB6193000F637B0 /* UIView+Windless.swift in Headers */ = {isa = PBXBuildFile; fileRef = 4AE437C11FB219FF00E22C5A /* UIView+Windless.swift */; settings = {ATTRIBUTES = (Public, ); }; }; 29 | 4AE437C21FB219FF00E22C5A /* UIView+Windless.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AE437C11FB219FF00E22C5A /* UIView+Windless.swift */; }; 30 | 4AE437C51FB21FF800E22C5A /* CAMediaTimingFunction+Windless.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AE437C41FB21FF800E22C5A /* CAMediaTimingFunction+Windless.swift */; }; 31 | 4AE437C71FB2B50200E22C5A /* WindlessOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AE437C61FB2B50200E22C5A /* WindlessOptions.swift */; }; 32 | 52D6D9871BEFF229002C0205 /* Windless.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52D6D97C1BEFF229002C0205 /* Windless.framework */; }; 33 | 8933C7851EB5B820000D00A4 /* Windless.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8933C7841EB5B820000D00A4 /* Windless.swift */; }; 34 | 8933C7901EB5B82D000D00A4 /* WindlessTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8933C7891EB5B82A000D00A4 /* WindlessTests.swift */; }; 35 | /* End PBXBuildFile section */ 36 | 37 | /* Begin PBXContainerItemProxy section */ 38 | 4A51527D1FB892EA00BD905F /* PBXContainerItemProxy */ = { 39 | isa = PBXContainerItemProxy; 40 | containerPortal = 52D6D9731BEFF229002C0205 /* Project object */; 41 | proxyType = 1; 42 | remoteGlobalIDString = 52D6D97B1BEFF229002C0205; 43 | remoteInfo = "Windless-iOS"; 44 | }; 45 | 52D6D9881BEFF229002C0205 /* PBXContainerItemProxy */ = { 46 | isa = PBXContainerItemProxy; 47 | containerPortal = 52D6D9731BEFF229002C0205 /* Project object */; 48 | proxyType = 1; 49 | remoteGlobalIDString = 52D6D97B1BEFF229002C0205; 50 | remoteInfo = Windless; 51 | }; 52 | /* End PBXContainerItemProxy section */ 53 | 54 | /* Begin PBXCopyFilesBuildPhase section */ 55 | 4A2F5DD71FB8780700E0A6F5 /* Embed Frameworks */ = { 56 | isa = PBXCopyFilesBuildPhase; 57 | buildActionMask = 2147483647; 58 | dstPath = ""; 59 | dstSubfolderSpec = 10; 60 | files = ( 61 | 4A51527C1FB892EA00BD905F /* Windless.framework in Embed Frameworks */, 62 | ); 63 | name = "Embed Frameworks"; 64 | runOnlyForDeploymentPostprocessing = 0; 65 | }; 66 | /* End PBXCopyFilesBuildPhase section */ 67 | 68 | /* Begin PBXFileReference section */ 69 | 4A1179401FAEEFA000164FC4 /* WindlessLayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WindlessLayer.swift; sourceTree = ""; }; 70 | 4A1179421FAEFCC700164FC4 /* WindlessConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WindlessConfiguration.swift; sourceTree = ""; }; 71 | 4A1179441FAF1EBB00164FC4 /* ListViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListViewController.swift; sourceTree = ""; }; 72 | 4A1C00B61FA102E5006DEA4C /* Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 73 | 4A1C00B81FA102E5006DEA4C /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 74 | 4A1C00BA1FA102E5006DEA4C /* BasicViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BasicViewController.swift; sourceTree = ""; }; 75 | 4A1C00BD1FA102E5006DEA4C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 76 | 4A1C00BF1FA102E5006DEA4C /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 77 | 4A1C00C21FA102E5006DEA4C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 78 | 4A1C00C41FA102E5006DEA4C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 79 | 4A1C00CC1FA1AB80006DEA4C /* TableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TableViewController.swift; sourceTree = ""; }; 80 | 4A29B6E21FB9D13300F5B6E4 /* MultipleLines.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultipleLines.swift; sourceTree = ""; }; 81 | 4A2F5D9D1FB8686800E0A6F5 /* WindlessContext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WindlessContext.swift; sourceTree = ""; }; 82 | 4A5152781FB88EE400BD905F /* AnimationFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnimationFactory.swift; sourceTree = ""; }; 83 | 4A51527F1FB8935F00BD905F /* Maker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Maker.swift; sourceTree = ""; }; 84 | 4A5152811FB8AED700BD905F /* Constant+Windless.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Constant+Windless.swift"; sourceTree = ""; }; 85 | 4A5152831FB8AEF300BD905F /* TransitionFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransitionFactory.swift; sourceTree = ""; }; 86 | 4AE437C11FB219FF00E22C5A /* UIView+Windless.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+Windless.swift"; sourceTree = ""; }; 87 | 4AE437C41FB21FF800E22C5A /* CAMediaTimingFunction+Windless.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CAMediaTimingFunction+Windless.swift"; sourceTree = ""; }; 88 | 4AE437C61FB2B50200E22C5A /* WindlessOptions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WindlessOptions.swift; sourceTree = ""; }; 89 | 52D6D97C1BEFF229002C0205 /* Windless.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Windless.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 90 | 52D6D9861BEFF229002C0205 /* Windless-iOS Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Windless-iOS Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 91 | 8933C7841EB5B820000D00A4 /* Windless.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Windless.swift; sourceTree = ""; }; 92 | 8933C7891EB5B82A000D00A4 /* WindlessTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WindlessTests.swift; sourceTree = ""; }; 93 | AD2FAA261CD0B6D800659CF4 /* Windless.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Windless.plist; sourceTree = ""; }; 94 | AD2FAA281CD0B6E100659CF4 /* WindlessTests.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = WindlessTests.plist; sourceTree = ""; }; 95 | /* End PBXFileReference section */ 96 | 97 | /* Begin PBXFrameworksBuildPhase section */ 98 | 4A1C00B31FA102E5006DEA4C /* Frameworks */ = { 99 | isa = PBXFrameworksBuildPhase; 100 | buildActionMask = 2147483647; 101 | files = ( 102 | 4A51527B1FB892EA00BD905F /* Windless.framework in Frameworks */, 103 | ); 104 | runOnlyForDeploymentPostprocessing = 0; 105 | }; 106 | 52D6D9781BEFF229002C0205 /* Frameworks */ = { 107 | isa = PBXFrameworksBuildPhase; 108 | buildActionMask = 2147483647; 109 | files = ( 110 | ); 111 | runOnlyForDeploymentPostprocessing = 0; 112 | }; 113 | 52D6D9831BEFF229002C0205 /* Frameworks */ = { 114 | isa = PBXFrameworksBuildPhase; 115 | buildActionMask = 2147483647; 116 | files = ( 117 | 52D6D9871BEFF229002C0205 /* Windless.framework in Frameworks */, 118 | ); 119 | runOnlyForDeploymentPostprocessing = 0; 120 | }; 121 | /* End PBXFrameworksBuildPhase section */ 122 | 123 | /* Begin PBXGroup section */ 124 | 4A1C00B71FA102E5006DEA4C /* Example */ = { 125 | isa = PBXGroup; 126 | children = ( 127 | 4A1C00B81FA102E5006DEA4C /* AppDelegate.swift */, 128 | 4A1179441FAF1EBB00164FC4 /* ListViewController.swift */, 129 | 4A1C00BA1FA102E5006DEA4C /* BasicViewController.swift */, 130 | 4A1C00CC1FA1AB80006DEA4C /* TableViewController.swift */, 131 | 4A1C00BC1FA102E5006DEA4C /* Main.storyboard */, 132 | 4A1C00BF1FA102E5006DEA4C /* Assets.xcassets */, 133 | 4A1C00C11FA102E5006DEA4C /* LaunchScreen.storyboard */, 134 | 4A1C00C41FA102E5006DEA4C /* Info.plist */, 135 | ); 136 | path = Example; 137 | sourceTree = ""; 138 | }; 139 | 4A1C00C81FA104D2006DEA4C /* Frameworks */ = { 140 | isa = PBXGroup; 141 | children = ( 142 | ); 143 | name = Frameworks; 144 | sourceTree = ""; 145 | }; 146 | 52D6D9721BEFF229002C0205 = { 147 | isa = PBXGroup; 148 | children = ( 149 | 8933C7811EB5B7E0000D00A4 /* Sources */, 150 | 8933C7831EB5B7EB000D00A4 /* Tests */, 151 | 52D6D99C1BEFF38C002C0205 /* Configs */, 152 | 4A1C00B71FA102E5006DEA4C /* Example */, 153 | 52D6D97D1BEFF229002C0205 /* Products */, 154 | 4A1C00C81FA104D2006DEA4C /* Frameworks */, 155 | ); 156 | sourceTree = ""; 157 | }; 158 | 52D6D97D1BEFF229002C0205 /* Products */ = { 159 | isa = PBXGroup; 160 | children = ( 161 | 52D6D97C1BEFF229002C0205 /* Windless.framework */, 162 | 52D6D9861BEFF229002C0205 /* Windless-iOS Tests.xctest */, 163 | 4A1C00B61FA102E5006DEA4C /* Example.app */, 164 | ); 165 | name = Products; 166 | sourceTree = ""; 167 | }; 168 | 52D6D99C1BEFF38C002C0205 /* Configs */ = { 169 | isa = PBXGroup; 170 | children = ( 171 | DD7502721C68FC1B006590AF /* Frameworks */, 172 | DD7502731C68FC20006590AF /* Tests */, 173 | ); 174 | path = Configs; 175 | sourceTree = ""; 176 | }; 177 | 8933C7811EB5B7E0000D00A4 /* Sources */ = { 178 | isa = PBXGroup; 179 | children = ( 180 | 8933C7841EB5B820000D00A4 /* Windless.swift */, 181 | 4A1179401FAEEFA000164FC4 /* WindlessLayer.swift */, 182 | 4A2F5D9D1FB8686800E0A6F5 /* WindlessContext.swift */, 183 | 4AE437C61FB2B50200E22C5A /* WindlessOptions.swift */, 184 | 4A1179421FAEFCC700164FC4 /* WindlessConfiguration.swift */, 185 | 4A51527F1FB8935F00BD905F /* Maker.swift */, 186 | 4A29B6E21FB9D13300F5B6E4 /* MultipleLines.swift */, 187 | 4A5152781FB88EE400BD905F /* AnimationFactory.swift */, 188 | 4A5152831FB8AEF300BD905F /* TransitionFactory.swift */, 189 | 4AE437C11FB219FF00E22C5A /* UIView+Windless.swift */, 190 | 4A5152811FB8AED700BD905F /* Constant+Windless.swift */, 191 | 4AE437C41FB21FF800E22C5A /* CAMediaTimingFunction+Windless.swift */, 192 | ); 193 | path = Sources; 194 | sourceTree = ""; 195 | }; 196 | 8933C7831EB5B7EB000D00A4 /* Tests */ = { 197 | isa = PBXGroup; 198 | children = ( 199 | 8933C7891EB5B82A000D00A4 /* WindlessTests.swift */, 200 | ); 201 | name = Tests; 202 | path = Tests/WindlessTests; 203 | sourceTree = ""; 204 | }; 205 | DD7502721C68FC1B006590AF /* Frameworks */ = { 206 | isa = PBXGroup; 207 | children = ( 208 | AD2FAA261CD0B6D800659CF4 /* Windless.plist */, 209 | ); 210 | name = Frameworks; 211 | sourceTree = ""; 212 | }; 213 | DD7502731C68FC20006590AF /* Tests */ = { 214 | isa = PBXGroup; 215 | children = ( 216 | AD2FAA281CD0B6E100659CF4 /* WindlessTests.plist */, 217 | ); 218 | name = Tests; 219 | sourceTree = ""; 220 | }; 221 | /* End PBXGroup section */ 222 | 223 | /* Begin PBXHeadersBuildPhase section */ 224 | 52D6D9791BEFF229002C0205 /* Headers */ = { 225 | isa = PBXHeadersBuildPhase; 226 | buildActionMask = 2147483647; 227 | files = ( 228 | 4A68FF851FB6193000F637B0 /* UIView+Windless.swift in Headers */, 229 | 4A29B6E61FBA018C00F5B6E4 /* MultipleLines.swift in Headers */, 230 | ); 231 | runOnlyForDeploymentPostprocessing = 0; 232 | }; 233 | /* End PBXHeadersBuildPhase section */ 234 | 235 | /* Begin PBXNativeTarget section */ 236 | 4A1C00B51FA102E5006DEA4C /* Example */ = { 237 | isa = PBXNativeTarget; 238 | buildConfigurationList = 4A1C00C51FA102E5006DEA4C /* Build configuration list for PBXNativeTarget "Example" */; 239 | buildPhases = ( 240 | 4A1C00B21FA102E5006DEA4C /* Sources */, 241 | 4A1C00B31FA102E5006DEA4C /* Frameworks */, 242 | 4A1C00B41FA102E5006DEA4C /* Resources */, 243 | 4A2F5DD71FB8780700E0A6F5 /* Embed Frameworks */, 244 | ); 245 | buildRules = ( 246 | ); 247 | dependencies = ( 248 | 4A51527E1FB892EA00BD905F /* PBXTargetDependency */, 249 | ); 250 | name = Example; 251 | productName = Example; 252 | productReference = 4A1C00B61FA102E5006DEA4C /* Example.app */; 253 | productType = "com.apple.product-type.application"; 254 | }; 255 | 52D6D97B1BEFF229002C0205 /* Windless-iOS */ = { 256 | isa = PBXNativeTarget; 257 | buildConfigurationList = 52D6D9901BEFF229002C0205 /* Build configuration list for PBXNativeTarget "Windless-iOS" */; 258 | buildPhases = ( 259 | 52D6D9771BEFF229002C0205 /* Sources */, 260 | 52D6D9781BEFF229002C0205 /* Frameworks */, 261 | 52D6D9791BEFF229002C0205 /* Headers */, 262 | 52D6D97A1BEFF229002C0205 /* Resources */, 263 | ); 264 | buildRules = ( 265 | ); 266 | dependencies = ( 267 | ); 268 | name = "Windless-iOS"; 269 | productName = Windless; 270 | productReference = 52D6D97C1BEFF229002C0205 /* Windless.framework */; 271 | productType = "com.apple.product-type.framework"; 272 | }; 273 | 52D6D9851BEFF229002C0205 /* Windless-iOS Tests */ = { 274 | isa = PBXNativeTarget; 275 | buildConfigurationList = 52D6D9931BEFF229002C0205 /* Build configuration list for PBXNativeTarget "Windless-iOS Tests" */; 276 | buildPhases = ( 277 | 52D6D9821BEFF229002C0205 /* Sources */, 278 | 52D6D9831BEFF229002C0205 /* Frameworks */, 279 | 52D6D9841BEFF229002C0205 /* Resources */, 280 | ); 281 | buildRules = ( 282 | ); 283 | dependencies = ( 284 | 52D6D9891BEFF229002C0205 /* PBXTargetDependency */, 285 | ); 286 | name = "Windless-iOS Tests"; 287 | productName = WindlessTests; 288 | productReference = 52D6D9861BEFF229002C0205 /* Windless-iOS Tests.xctest */; 289 | productType = "com.apple.product-type.bundle.unit-test"; 290 | }; 291 | /* End PBXNativeTarget section */ 292 | 293 | /* Begin PBXProject section */ 294 | 52D6D9731BEFF229002C0205 /* Project object */ = { 295 | isa = PBXProject; 296 | attributes = { 297 | LastSwiftUpdateCheck = 0900; 298 | LastUpgradeCheck = 0900; 299 | ORGANIZATIONNAME = Windless; 300 | TargetAttributes = { 301 | 4A1C00B51FA102E5006DEA4C = { 302 | CreatedOnToolsVersion = 9.0; 303 | ProvisioningStyle = Manual; 304 | }; 305 | 52D6D97B1BEFF229002C0205 = { 306 | CreatedOnToolsVersion = 7.1; 307 | LastSwiftMigration = 0800; 308 | }; 309 | 52D6D9851BEFF229002C0205 = { 310 | CreatedOnToolsVersion = 7.1; 311 | LastSwiftMigration = 0800; 312 | }; 313 | }; 314 | }; 315 | buildConfigurationList = 52D6D9761BEFF229002C0205 /* Build configuration list for PBXProject "Windless" */; 316 | compatibilityVersion = "Xcode 6.3"; 317 | developmentRegion = English; 318 | hasScannedForEncodings = 0; 319 | knownRegions = ( 320 | en, 321 | Base, 322 | ); 323 | mainGroup = 52D6D9721BEFF229002C0205; 324 | productRefGroup = 52D6D97D1BEFF229002C0205 /* Products */; 325 | projectDirPath = ""; 326 | projectRoot = ""; 327 | targets = ( 328 | 52D6D97B1BEFF229002C0205 /* Windless-iOS */, 329 | 52D6D9851BEFF229002C0205 /* Windless-iOS Tests */, 330 | 4A1C00B51FA102E5006DEA4C /* Example */, 331 | ); 332 | }; 333 | /* End PBXProject section */ 334 | 335 | /* Begin PBXResourcesBuildPhase section */ 336 | 4A1C00B41FA102E5006DEA4C /* Resources */ = { 337 | isa = PBXResourcesBuildPhase; 338 | buildActionMask = 2147483647; 339 | files = ( 340 | 4A1C00C31FA102E5006DEA4C /* LaunchScreen.storyboard in Resources */, 341 | 4A1C00C01FA102E5006DEA4C /* Assets.xcassets in Resources */, 342 | 4A1C00BE1FA102E5006DEA4C /* Main.storyboard in Resources */, 343 | ); 344 | runOnlyForDeploymentPostprocessing = 0; 345 | }; 346 | 52D6D97A1BEFF229002C0205 /* Resources */ = { 347 | isa = PBXResourcesBuildPhase; 348 | buildActionMask = 2147483647; 349 | files = ( 350 | ); 351 | runOnlyForDeploymentPostprocessing = 0; 352 | }; 353 | 52D6D9841BEFF229002C0205 /* Resources */ = { 354 | isa = PBXResourcesBuildPhase; 355 | buildActionMask = 2147483647; 356 | files = ( 357 | ); 358 | runOnlyForDeploymentPostprocessing = 0; 359 | }; 360 | /* End PBXResourcesBuildPhase section */ 361 | 362 | /* Begin PBXSourcesBuildPhase section */ 363 | 4A1C00B21FA102E5006DEA4C /* Sources */ = { 364 | isa = PBXSourcesBuildPhase; 365 | buildActionMask = 2147483647; 366 | files = ( 367 | 4A1C00BB1FA102E5006DEA4C /* BasicViewController.swift in Sources */, 368 | 4A1C00CD1FA1AB80006DEA4C /* TableViewController.swift in Sources */, 369 | 4A1C00B91FA102E5006DEA4C /* AppDelegate.swift in Sources */, 370 | 4A1179451FAF1EBB00164FC4 /* ListViewController.swift in Sources */, 371 | ); 372 | runOnlyForDeploymentPostprocessing = 0; 373 | }; 374 | 52D6D9771BEFF229002C0205 /* Sources */ = { 375 | isa = PBXSourcesBuildPhase; 376 | buildActionMask = 2147483647; 377 | files = ( 378 | 4A5152841FB8AEF300BD905F /* TransitionFactory.swift in Sources */, 379 | 4A29B6E31FB9D13300F5B6E4 /* MultipleLines.swift in Sources */, 380 | 4A2F5D9E1FB8686800E0A6F5 /* WindlessContext.swift in Sources */, 381 | 8933C7851EB5B820000D00A4 /* Windless.swift in Sources */, 382 | 4A51527A1FB88F3400BD905F /* AnimationFactory.swift in Sources */, 383 | 4A1179411FAEEFA000164FC4 /* WindlessLayer.swift in Sources */, 384 | 4AE437C51FB21FF800E22C5A /* CAMediaTimingFunction+Windless.swift in Sources */, 385 | 4A5152801FB8935F00BD905F /* Maker.swift in Sources */, 386 | 4A5152821FB8AED700BD905F /* Constant+Windless.swift in Sources */, 387 | 4AE437C21FB219FF00E22C5A /* UIView+Windless.swift in Sources */, 388 | 4AE437C71FB2B50200E22C5A /* WindlessOptions.swift in Sources */, 389 | 4A1179431FAEFCC700164FC4 /* WindlessConfiguration.swift in Sources */, 390 | ); 391 | runOnlyForDeploymentPostprocessing = 0; 392 | }; 393 | 52D6D9821BEFF229002C0205 /* Sources */ = { 394 | isa = PBXSourcesBuildPhase; 395 | buildActionMask = 2147483647; 396 | files = ( 397 | 8933C7901EB5B82D000D00A4 /* WindlessTests.swift in Sources */, 398 | ); 399 | runOnlyForDeploymentPostprocessing = 0; 400 | }; 401 | /* End PBXSourcesBuildPhase section */ 402 | 403 | /* Begin PBXTargetDependency section */ 404 | 4A51527E1FB892EA00BD905F /* PBXTargetDependency */ = { 405 | isa = PBXTargetDependency; 406 | target = 52D6D97B1BEFF229002C0205 /* Windless-iOS */; 407 | targetProxy = 4A51527D1FB892EA00BD905F /* PBXContainerItemProxy */; 408 | }; 409 | 52D6D9891BEFF229002C0205 /* PBXTargetDependency */ = { 410 | isa = PBXTargetDependency; 411 | target = 52D6D97B1BEFF229002C0205 /* Windless-iOS */; 412 | targetProxy = 52D6D9881BEFF229002C0205 /* PBXContainerItemProxy */; 413 | }; 414 | /* End PBXTargetDependency section */ 415 | 416 | /* Begin PBXVariantGroup section */ 417 | 4A1C00BC1FA102E5006DEA4C /* Main.storyboard */ = { 418 | isa = PBXVariantGroup; 419 | children = ( 420 | 4A1C00BD1FA102E5006DEA4C /* Base */, 421 | ); 422 | name = Main.storyboard; 423 | sourceTree = ""; 424 | }; 425 | 4A1C00C11FA102E5006DEA4C /* LaunchScreen.storyboard */ = { 426 | isa = PBXVariantGroup; 427 | children = ( 428 | 4A1C00C21FA102E5006DEA4C /* Base */, 429 | ); 430 | name = LaunchScreen.storyboard; 431 | sourceTree = ""; 432 | }; 433 | /* End PBXVariantGroup section */ 434 | 435 | /* Begin XCBuildConfiguration section */ 436 | 4A1C00C61FA102E5006DEA4C /* Debug */ = { 437 | isa = XCBuildConfiguration; 438 | buildSettings = { 439 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 440 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 441 | CLANG_ANALYZER_NONNULL = YES; 442 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 443 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 444 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 445 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 446 | CODE_SIGN_IDENTITY = "iPhone Developer"; 447 | CODE_SIGN_STYLE = Manual; 448 | DEVELOPMENT_TEAM = ""; 449 | GCC_C_LANGUAGE_STANDARD = gnu11; 450 | INFOPLIST_FILE = Example/Info.plist; 451 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 452 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 453 | PRODUCT_BUNDLE_IDENTIFIER = com.gwangbeom.Example; 454 | PRODUCT_NAME = "$(TARGET_NAME)"; 455 | PROVISIONING_PROFILE_SPECIFIER = ""; 456 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 457 | SWIFT_VERSION = 4.0; 458 | TARGETED_DEVICE_FAMILY = "1,2"; 459 | }; 460 | name = Debug; 461 | }; 462 | 4A1C00C71FA102E5006DEA4C /* Release */ = { 463 | isa = XCBuildConfiguration; 464 | buildSettings = { 465 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 466 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 467 | CLANG_ANALYZER_NONNULL = YES; 468 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 469 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 470 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 471 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 472 | CODE_SIGN_IDENTITY = "iPhone Developer"; 473 | CODE_SIGN_STYLE = Manual; 474 | DEVELOPMENT_TEAM = ""; 475 | GCC_C_LANGUAGE_STANDARD = gnu11; 476 | INFOPLIST_FILE = Example/Info.plist; 477 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 478 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 479 | PRODUCT_BUNDLE_IDENTIFIER = com.gwangbeom.Example; 480 | PRODUCT_NAME = "$(TARGET_NAME)"; 481 | PROVISIONING_PROFILE_SPECIFIER = ""; 482 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 483 | SWIFT_VERSION = 4.0; 484 | TARGETED_DEVICE_FAMILY = "1,2"; 485 | }; 486 | name = Release; 487 | }; 488 | 52D6D98E1BEFF229002C0205 /* Debug */ = { 489 | isa = XCBuildConfiguration; 490 | buildSettings = { 491 | ALWAYS_SEARCH_USER_PATHS = NO; 492 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 493 | CLANG_CXX_LIBRARY = "libc++"; 494 | CLANG_ENABLE_MODULES = YES; 495 | CLANG_ENABLE_OBJC_ARC = YES; 496 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 497 | CLANG_WARN_BOOL_CONVERSION = YES; 498 | CLANG_WARN_COMMA = YES; 499 | CLANG_WARN_CONSTANT_CONVERSION = YES; 500 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 501 | CLANG_WARN_EMPTY_BODY = YES; 502 | CLANG_WARN_ENUM_CONVERSION = YES; 503 | CLANG_WARN_INFINITE_RECURSION = YES; 504 | CLANG_WARN_INT_CONVERSION = YES; 505 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 506 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 507 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 508 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 509 | CLANG_WARN_STRICT_PROTOTYPES = YES; 510 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 511 | CLANG_WARN_UNREACHABLE_CODE = YES; 512 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 513 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 514 | COPY_PHASE_STRIP = NO; 515 | CURRENT_PROJECT_VERSION = 1; 516 | DEBUG_INFORMATION_FORMAT = dwarf; 517 | ENABLE_STRICT_OBJC_MSGSEND = YES; 518 | ENABLE_TESTABILITY = YES; 519 | GCC_C_LANGUAGE_STANDARD = gnu99; 520 | GCC_DYNAMIC_NO_PIC = NO; 521 | GCC_NO_COMMON_BLOCKS = YES; 522 | GCC_OPTIMIZATION_LEVEL = 0; 523 | GCC_PREPROCESSOR_DEFINITIONS = ( 524 | "DEBUG=1", 525 | "$(inherited)", 526 | ); 527 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 528 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 529 | GCC_WARN_UNDECLARED_SELECTOR = YES; 530 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 531 | GCC_WARN_UNUSED_FUNCTION = YES; 532 | GCC_WARN_UNUSED_VARIABLE = YES; 533 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 534 | MTL_ENABLE_DEBUG_INFO = YES; 535 | ONLY_ACTIVE_ARCH = YES; 536 | SDKROOT = iphoneos; 537 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 538 | SWIFT_VERSION = 4.0; 539 | TARGETED_DEVICE_FAMILY = "1,2"; 540 | VERSIONING_SYSTEM = "apple-generic"; 541 | VERSION_INFO_PREFIX = ""; 542 | }; 543 | name = Debug; 544 | }; 545 | 52D6D98F1BEFF229002C0205 /* Release */ = { 546 | isa = XCBuildConfiguration; 547 | buildSettings = { 548 | ALWAYS_SEARCH_USER_PATHS = NO; 549 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 550 | CLANG_CXX_LIBRARY = "libc++"; 551 | CLANG_ENABLE_MODULES = YES; 552 | CLANG_ENABLE_OBJC_ARC = YES; 553 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 554 | CLANG_WARN_BOOL_CONVERSION = YES; 555 | CLANG_WARN_COMMA = YES; 556 | CLANG_WARN_CONSTANT_CONVERSION = YES; 557 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 558 | CLANG_WARN_EMPTY_BODY = YES; 559 | CLANG_WARN_ENUM_CONVERSION = YES; 560 | CLANG_WARN_INFINITE_RECURSION = YES; 561 | CLANG_WARN_INT_CONVERSION = YES; 562 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 563 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 564 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 565 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 566 | CLANG_WARN_STRICT_PROTOTYPES = YES; 567 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 568 | CLANG_WARN_UNREACHABLE_CODE = YES; 569 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 570 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 571 | COPY_PHASE_STRIP = NO; 572 | CURRENT_PROJECT_VERSION = 1; 573 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 574 | ENABLE_NS_ASSERTIONS = NO; 575 | ENABLE_STRICT_OBJC_MSGSEND = YES; 576 | GCC_C_LANGUAGE_STANDARD = gnu99; 577 | GCC_NO_COMMON_BLOCKS = YES; 578 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 579 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 580 | GCC_WARN_UNDECLARED_SELECTOR = YES; 581 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 582 | GCC_WARN_UNUSED_FUNCTION = YES; 583 | GCC_WARN_UNUSED_VARIABLE = YES; 584 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 585 | MTL_ENABLE_DEBUG_INFO = NO; 586 | SDKROOT = iphoneos; 587 | SWIFT_VERSION = 4.0; 588 | TARGETED_DEVICE_FAMILY = "1,2"; 589 | VALIDATE_PRODUCT = YES; 590 | VERSIONING_SYSTEM = "apple-generic"; 591 | VERSION_INFO_PREFIX = ""; 592 | }; 593 | name = Release; 594 | }; 595 | 52D6D9911BEFF229002C0205 /* Debug */ = { 596 | isa = XCBuildConfiguration; 597 | buildSettings = { 598 | APPLICATION_EXTENSION_API_ONLY = YES; 599 | CLANG_ENABLE_MODULES = YES; 600 | CODE_SIGN_IDENTITY = "iPhone Developer"; 601 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 602 | DEFINES_MODULE = YES; 603 | DEVELOPMENT_TEAM = ""; 604 | DYLIB_COMPATIBILITY_VERSION = 1; 605 | DYLIB_CURRENT_VERSION = 1; 606 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 607 | INFOPLIST_FILE = Configs/Windless.plist; 608 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 609 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 610 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 611 | ONLY_ACTIVE_ARCH = NO; 612 | PRODUCT_BUNDLE_IDENTIFIER = "com.Windless.Windless-iOS"; 613 | PRODUCT_NAME = Windless; 614 | SKIP_INSTALL = YES; 615 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 616 | SWIFT_VERSION = 4.0; 617 | }; 618 | name = Debug; 619 | }; 620 | 52D6D9921BEFF229002C0205 /* Release */ = { 621 | isa = XCBuildConfiguration; 622 | buildSettings = { 623 | APPLICATION_EXTENSION_API_ONLY = YES; 624 | CLANG_ENABLE_MODULES = YES; 625 | CODE_SIGN_IDENTITY = "iPhone Developer"; 626 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 627 | DEFINES_MODULE = YES; 628 | DEVELOPMENT_TEAM = ""; 629 | DYLIB_COMPATIBILITY_VERSION = 1; 630 | DYLIB_CURRENT_VERSION = 1; 631 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 632 | INFOPLIST_FILE = Configs/Windless.plist; 633 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 634 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 635 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 636 | PRODUCT_BUNDLE_IDENTIFIER = "com.Windless.Windless-iOS"; 637 | PRODUCT_NAME = Windless; 638 | SKIP_INSTALL = YES; 639 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 640 | SWIFT_VERSION = 4.0; 641 | }; 642 | name = Release; 643 | }; 644 | 52D6D9941BEFF229002C0205 /* Debug */ = { 645 | isa = XCBuildConfiguration; 646 | buildSettings = { 647 | CLANG_ENABLE_MODULES = YES; 648 | INFOPLIST_FILE = Configs/WindlessTests.plist; 649 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 650 | PRODUCT_BUNDLE_IDENTIFIER = "com.Windless.Windless-iOS-Tests"; 651 | PRODUCT_NAME = "$(TARGET_NAME)"; 652 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 653 | SWIFT_VERSION = 4.0; 654 | }; 655 | name = Debug; 656 | }; 657 | 52D6D9951BEFF229002C0205 /* Release */ = { 658 | isa = XCBuildConfiguration; 659 | buildSettings = { 660 | CLANG_ENABLE_MODULES = YES; 661 | INFOPLIST_FILE = Configs/WindlessTests.plist; 662 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 663 | PRODUCT_BUNDLE_IDENTIFIER = "com.Windless.Windless-iOS-Tests"; 664 | PRODUCT_NAME = "$(TARGET_NAME)"; 665 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 666 | SWIFT_VERSION = 4.0; 667 | }; 668 | name = Release; 669 | }; 670 | /* End XCBuildConfiguration section */ 671 | 672 | /* Begin XCConfigurationList section */ 673 | 4A1C00C51FA102E5006DEA4C /* Build configuration list for PBXNativeTarget "Example" */ = { 674 | isa = XCConfigurationList; 675 | buildConfigurations = ( 676 | 4A1C00C61FA102E5006DEA4C /* Debug */, 677 | 4A1C00C71FA102E5006DEA4C /* Release */, 678 | ); 679 | defaultConfigurationIsVisible = 0; 680 | defaultConfigurationName = Release; 681 | }; 682 | 52D6D9761BEFF229002C0205 /* Build configuration list for PBXProject "Windless" */ = { 683 | isa = XCConfigurationList; 684 | buildConfigurations = ( 685 | 52D6D98E1BEFF229002C0205 /* Debug */, 686 | 52D6D98F1BEFF229002C0205 /* Release */, 687 | ); 688 | defaultConfigurationIsVisible = 0; 689 | defaultConfigurationName = Release; 690 | }; 691 | 52D6D9901BEFF229002C0205 /* Build configuration list for PBXNativeTarget "Windless-iOS" */ = { 692 | isa = XCConfigurationList; 693 | buildConfigurations = ( 694 | 52D6D9911BEFF229002C0205 /* Debug */, 695 | 52D6D9921BEFF229002C0205 /* Release */, 696 | ); 697 | defaultConfigurationIsVisible = 0; 698 | defaultConfigurationName = Release; 699 | }; 700 | 52D6D9931BEFF229002C0205 /* Build configuration list for PBXNativeTarget "Windless-iOS Tests" */ = { 701 | isa = XCConfigurationList; 702 | buildConfigurations = ( 703 | 52D6D9941BEFF229002C0205 /* Debug */, 704 | 52D6D9951BEFF229002C0205 /* Release */, 705 | ); 706 | defaultConfigurationIsVisible = 0; 707 | defaultConfigurationName = Release; 708 | }; 709 | /* End XCConfigurationList section */ 710 | }; 711 | rootObject = 52D6D9731BEFF229002C0205 /* Project object */; 712 | } 713 | -------------------------------------------------------------------------------- /Windless.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Windless.xcodeproj/xcshareddata/xcschemes/Windless-iOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 32 | 33 | 35 | 41 | 42 | 43 | 44 | 45 | 51 | 52 | 53 | 54 | 55 | 56 | 67 | 68 | 74 | 75 | 76 | 77 | 78 | 79 | 85 | 86 | 92 | 93 | 94 | 95 | 97 | 98 | 101 | 102 | 103 | --------------------------------------------------------------------------------