├── .fastlane └── Fastfile ├── .github ├── FUNDING.yml └── workflows │ ├── Checks.yml │ └── Release.yml ├── .gitignore ├── .swift-version ├── .travis.yml ├── CHANGELOG.md ├── Dangerfile ├── EasyPeasy.podspec ├── EasyPeasy ├── Attribute.swift ├── Collection+Easy.swift ├── CompoundAttribute.swift ├── Constant.swift ├── Context.swift ├── DimensionAttribute+AppKit.swift ├── DimensionAttribute+UIKit.swift ├── DimensionAttribute.swift ├── EasyPeasy.swift ├── Item+AppKit.swift ├── Item+UIKit.swift ├── Item.swift ├── NSLayoutGuide+Easy.swift ├── NSView+Easy.swift ├── Node.swift ├── PositionAttribute+AppKit.swift ├── PositionAttribute+UIKit.swift ├── PositionAttribute.swift ├── Priority.swift ├── ReferenceAttribute.swift ├── UILayoutGuide+Easy.swift └── UIView+Easy.swift ├── Example ├── Demo macOS │ ├── Demo macOS.xcodeproj │ │ ├── project.pbxproj │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── EasyPeasy-Example-macOS.xcscheme │ ├── Demo macOS │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ │ ├── AppIcon.appiconset │ │ │ │ ├── Contents.json │ │ │ │ ├── icon-mac-128.png │ │ │ │ ├── icon-mac-128@2x.png │ │ │ │ ├── icon-mac-16.png │ │ │ │ ├── icon-mac-16@2x.png │ │ │ │ ├── icon-mac-256.png │ │ │ │ ├── icon-mac-32.png │ │ │ │ ├── icon-mac-32@2x.png │ │ │ │ ├── icon-mac-512.png │ │ │ │ ├── icon-mac-512@2x.png │ │ │ │ └── icon-mac-513.png │ │ │ ├── Contents.json │ │ │ ├── Profile pictures │ │ │ │ ├── Contents.json │ │ │ │ ├── NatashaTheRobot.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── NatashaTheRobot.png │ │ │ │ ├── andy_matuschak.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── andy_matuschak.png │ │ │ │ ├── ashfurrow.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── ashfurrow.png │ │ │ │ ├── clattner_llvm.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── clattner_llvm.png │ │ │ │ ├── marcoshdezcif.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── marcoshdezcif.png │ │ │ │ ├── orta.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── orta.png │ │ │ │ ├── sandofsky.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── sandofsky.png │ │ │ │ └── steipete.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── steipete.png │ │ │ ├── icon-compose.imageset │ │ │ │ ├── ComposeTweet.png │ │ │ │ ├── ComposeTweet@2x.png │ │ │ │ └── Contents.json │ │ │ ├── icon-home.imageset │ │ │ │ ├── Contents.json │ │ │ │ ├── Home.png │ │ │ │ └── Home@2x.png │ │ │ ├── icon-messages.imageset │ │ │ │ ├── Contents.json │ │ │ │ ├── Messages.png │ │ │ │ └── Messages@2x.png │ │ │ ├── icon-moments.imageset │ │ │ │ ├── Contents.json │ │ │ │ ├── Moments.png │ │ │ │ └── Moments@2x.png │ │ │ ├── icon-notifications.imageset │ │ │ │ ├── Contents.json │ │ │ │ ├── Notifications.png │ │ │ │ └── Notifications@2x.png │ │ │ ├── icon-search.imageset │ │ │ │ ├── Contents.json │ │ │ │ ├── Search.png │ │ │ │ └── Search@2x.png │ │ │ └── thumb-easypeasy.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── thumb-easypeasy.png │ │ ├── Base.lproj │ │ │ └── MainMenu.xib │ │ ├── FeedController.swift │ │ ├── FeedView.swift │ │ ├── Info.plist │ │ ├── NSColor+Easy.swift │ │ ├── NSImage+Easy.swift │ │ ├── SideBarView.swift │ │ ├── TweetModel.swift │ │ └── TweetView.swift │ └── Demo macOSTests │ │ ├── Info.plist │ │ └── Tests macOS-Bridging-Header.h ├── EasyPeasy.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── xcshareddata │ │ └── xcschemes │ │ └── EasyPeasy-Example-iOS.xcscheme ├── EasyPeasy.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── EasyPeasy │ ├── AppDelegate.swift │ ├── Base.lproj │ │ ├── LaunchScreen.xib │ │ └── Main.storyboard │ ├── FeedController.swift │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ ├── Icon-40.png │ │ │ ├── Icon-40@2x.png │ │ │ ├── Icon-40@3x.png │ │ │ ├── Icon-60@2x.png │ │ │ ├── Icon-60@3x.png │ │ │ ├── Icon-76.png │ │ │ ├── Icon-76@2x.png │ │ │ ├── Icon-83.5@2x.png │ │ │ ├── Icon-Small.png │ │ │ ├── Icon-Small@2x.png │ │ │ └── Icon-Small@3x.png │ │ ├── Contents.json │ │ ├── easypeasy-logo.imageset │ │ │ ├── Contents.json │ │ │ └── easypeasy_logo@3x.png │ │ ├── icon-new-tweet.imageset │ │ │ ├── Contents.json │ │ │ └── icon_new_tweet@3x.png │ │ ├── icon-profile.imageset │ │ │ ├── Contents.json │ │ │ └── icon_profile@3x.png │ │ ├── icon-search.imageset │ │ │ ├── Contents.json │ │ │ └── icon_search@3x.png │ │ ├── new-tweets.imageset │ │ │ ├── Contents.json │ │ │ └── new_tweets@3x.png │ │ ├── thumb-eloy.imageset │ │ │ ├── Contents.json │ │ │ └── thumb-eloy.png │ │ ├── thumb-felix.imageset │ │ │ ├── Contents.json │ │ │ └── thumb_felix.jpeg │ │ ├── thumb-javi.imageset │ │ │ ├── Contents.json │ │ │ └── thumb-javi.jpeg │ │ ├── thumb-nacho.imageset │ │ │ ├── Contents.json │ │ │ └── thumb-nacho.jpg │ │ └── twitter-logo.imageset │ │ │ ├── Contents.json │ │ │ └── twitter_logo@3x.png │ ├── Info.plist │ ├── String+Easy.swift │ ├── TweetModel.swift │ ├── TweetView.swift │ └── UIImage+Easy.swift ├── Podfile ├── Podfile.lock ├── Pods │ ├── Local Podspecs │ │ └── EasyPeasy.podspec.json │ ├── Manifest.lock │ ├── Pods.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ └── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ ├── EasyPeasy-iOS.xcscheme │ │ │ └── EasyPeasy-macOS.xcscheme │ └── Target Support Files │ │ ├── EasyPeasy-iOS │ │ ├── EasyPeasy-iOS-dummy.m │ │ ├── EasyPeasy-iOS-prefix.pch │ │ ├── EasyPeasy-iOS-umbrella.h │ │ ├── EasyPeasy-iOS.modulemap │ │ ├── EasyPeasy-iOS.xcconfig │ │ └── Info.plist │ │ ├── EasyPeasy-macOS │ │ ├── EasyPeasy-macOS-dummy.m │ │ ├── EasyPeasy-macOS-prefix.pch │ │ ├── EasyPeasy-macOS-umbrella.h │ │ ├── EasyPeasy-macOS.modulemap │ │ ├── EasyPeasy-macOS.xcconfig │ │ └── Info.plist │ │ ├── Pods-Demo macOS │ │ ├── Info.plist │ │ ├── Pods-Demo macOS-acknowledgements.markdown │ │ ├── Pods-Demo macOS-acknowledgements.plist │ │ ├── Pods-Demo macOS-dummy.m │ │ ├── Pods-Demo macOS-frameworks.sh │ │ ├── Pods-Demo macOS-resources.sh │ │ ├── Pods-Demo macOS-umbrella.h │ │ ├── Pods-Demo macOS.debug.xcconfig │ │ ├── Pods-Demo macOS.modulemap │ │ └── Pods-Demo macOS.release.xcconfig │ │ ├── Pods-Demo │ │ ├── Info.plist │ │ ├── Pods-Demo-acknowledgements.markdown │ │ ├── Pods-Demo-acknowledgements.plist │ │ ├── Pods-Demo-dummy.m │ │ ├── Pods-Demo-frameworks.sh │ │ ├── Pods-Demo-resources.sh │ │ ├── Pods-Demo-umbrella.h │ │ ├── Pods-Demo.debug.xcconfig │ │ ├── Pods-Demo.modulemap │ │ └── Pods-Demo.release.xcconfig │ │ ├── Pods-Tests macOS │ │ ├── Info.plist │ │ ├── Pods-Tests macOS-acknowledgements.markdown │ │ ├── Pods-Tests macOS-acknowledgements.plist │ │ ├── Pods-Tests macOS-dummy.m │ │ ├── Pods-Tests macOS-frameworks.sh │ │ ├── Pods-Tests macOS-resources.sh │ │ ├── Pods-Tests macOS-umbrella.h │ │ ├── Pods-Tests macOS.debug.xcconfig │ │ ├── Pods-Tests macOS.modulemap │ │ └── Pods-Tests macOS.release.xcconfig │ │ └── Pods-Tests │ │ ├── Info.plist │ │ ├── Pods-Tests-acknowledgements.markdown │ │ ├── Pods-Tests-acknowledgements.plist │ │ ├── Pods-Tests-dummy.m │ │ ├── Pods-Tests-frameworks.sh │ │ ├── Pods-Tests-resources.sh │ │ ├── Pods-Tests-umbrella.h │ │ ├── Pods-Tests.debug.xcconfig │ │ ├── Pods-Tests.modulemap │ │ └── Pods-Tests.release.xcconfig └── Tests │ ├── AttributeTests.swift │ ├── CompoundAttributeTests.swift │ ├── ConstantTests.swift │ ├── ContextTests.swift │ ├── Info.plist │ ├── Item+Tests.swift │ ├── ItemTests.swift │ ├── NodeTests.swift │ ├── PriorityTests.swift │ ├── ReferenceAttributeTests.swift │ ├── UILayoutGuide+EasyTests.swift │ └── UIView+EasyTests.swift ├── Gemfile ├── Gemfile.lock ├── LICENSE ├── Package.swift ├── README.md ├── README ├── demo_ios.gif ├── demo_macos.gif ├── first_touch.png ├── logo.png ├── monzo.png └── playground.gif └── _Pods.xcodeproj /.fastlane/Fastfile: -------------------------------------------------------------------------------- 1 | fastlane_version "1.66.0" 2 | default_platform :ios 3 | 4 | platform :ios do 5 | 6 | desc "Runs all the tests" 7 | lane :travis do 8 | workspace = "Example/EasyPeasy.xcworkspace" 9 | 10 | # Run tests (iOS) 11 | scheme = "EasyPeasy-Example-iOS" 12 | scan( 13 | scheme: scheme, 14 | workspace: workspace, 15 | device: "iPhone 6s", 16 | code_coverage: true 17 | ) 18 | 19 | # Check code coverage (iOS) 20 | xcov( 21 | scheme: scheme, 22 | workspace: workspace, 23 | exclude_targets: "Demo.app,Demo macOS.app,EasyPeasy-OSX.framework", 24 | coveralls_service_name: "travis-ci", 25 | coveralls_service_job_id: ENV["TRAVIS_JOB_ID"] 26 | ) 27 | end 28 | 29 | end 30 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | ko_fi: nakiostudio 2 | -------------------------------------------------------------------------------- /.github/workflows/Checks.yml: -------------------------------------------------------------------------------- 1 | name: Checks 2 | 3 | on: [push] 4 | 5 | jobs: 6 | lint: 7 | runs-on: macos-latest 8 | 9 | steps: 10 | - uses: maxim-lobanov/setup-xcode@v1.1 11 | with: 12 | xcode-version: "12.3" 13 | - uses: actions/checkout@v2 14 | - name: Lint Cocoapods 15 | run: pod lib lint --allow-warnings 16 | -------------------------------------------------------------------------------- /.github/workflows/Release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | tags: 6 | - "*" 7 | 8 | jobs: 9 | pod-trunk-push: 10 | runs-on: macOS-latest 11 | steps: 12 | - uses: maxim-lobanov/setup-xcode@v1.1 13 | with: 14 | xcode-version: "12.3" 15 | - uses: actions/checkout@v2 16 | - name: Deploy 17 | env: 18 | COCOAPODS_TRUNK_TOKEN: ${{ secrets.COCOAPODS_TRUNK_TOKEN }} 19 | run: pod trunk push EasyPeasy.podspec --allow-warnings 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OS X 2 | .DS_Store 3 | 4 | # Xcode 5 | build/ 6 | *.pbxuser 7 | !default.pbxuser 8 | *.mode1v3 9 | !default.mode1v3 10 | *.mode2v3 11 | !default.mode2v3 12 | *.perspectivev3 13 | !default.perspectivev3 14 | xcuserdata 15 | *.xccheckout 16 | profile 17 | *.moved-aside 18 | DerivedData 19 | *.hmap 20 | *.ipa 21 | 22 | # Bundler 23 | .bundle 24 | 25 | # CI 26 | test_output/ 27 | .fastlane/report.xml 28 | .fastlane/README.md 29 | -------------------------------------------------------------------------------- /.swift-version: -------------------------------------------------------------------------------- 1 | 5.0 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: objective-c 2 | osx_image: xcode10.2 3 | branches: 4 | only: 5 | - master 6 | - develop 7 | before_install: 8 | - bundle install 9 | script: 10 | - set -o pipefail 11 | - fastlane travis 12 | - danger --verbose 13 | - pod lib lint --quick 14 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## v.1.9.0 4 | * Swift 5.0 support. 5 | 6 | ## v.1.8.0 7 | * Swift 4.2 support. 8 | 9 | ## v.1.7.0 10 | 11 | * Swift 4.1 support. 12 | 13 | ## v.1.6.0 14 | 15 | * Deprecated `<-` operator and the methods `easy_clear` and `easy_reload` in favour of 16 | `easy.layout`, `easy.clear` and `easy.reload`. 17 | 18 | ## v.1.5.1 19 | 20 | * Disabled `Enabled Code Coverage Support` for framework targets. 21 | * Fixed macOS `EdgeInsets` type aliasing. 22 | 23 | ## v.1.5.0 24 | 25 | * Swift 4 support (by [Bas van Kuijck](https://github.com/basvankuijck)). 26 | 27 | ## v.1.4.2 28 | 29 | * In previous versions `Priority.highPriority` matched with `UILayoutPriority.required`. This 30 | version introduces a new `Priority.required` case without breaking backwards compatibility as 31 | old priorities have been marked as deprecated in favour of `.low`, `.medium`, `.high` and 32 | `.custom`. Also `.low` now has a `Float` value of `250.0` instead of `1.0`. 33 | 34 | ## v.1.4.1 35 | 36 | * Fixed compilation error when `EASY_RELOAD` compiler flag is set. 37 | 38 | ## v.1.4 39 | 40 | * Swift 3 support. 41 | 42 | ## v.1.3.1 43 | 44 | * Fixed `podspec`. 45 | 46 | ## v.1.3 47 | 48 | * Swift 2.3 compatibility. 49 | 50 | ## v.1.2.1 51 | 52 | * Now you can apply `DimensionAttributes`, like `Width`, `Height` and `Size`, 53 | to views not in the view hierarchy, i.e. when `superview == nil`. 54 | 55 | ## v.1.2 56 | 57 | * Implemented `ContextualConditions`, a variant of the `Condition` closures 58 | where a `Context` struct is passed as parameter to the closure providing some 59 | extra information (size class and device) based on the `UITraitCollection` 60 | of the `UIView` the `Attributes` are going to be applied to. Examples: 61 | 62 | ```swift 63 | view <- [ 64 | Size(250), 65 | Center(0) 66 | ].when { $0.isHorizontalRegular } 67 | ``` 68 | 69 | ```swift 70 | view <- [ 71 | Top(0), 72 | Left(0), 73 | Right(0), 74 | Height(250) 75 | ].when { $0.isPad } 76 | ``` 77 | 78 | ## v.1.1.1 79 | 80 | * Grouped deactivation of `NSLayoutConstraints`. Before, the deactivation of `NSLayoutConstraints` was taking place upon finding 81 | a conflict, whereas now a single `NSLayoutConstraint.deactivateConstraints(_:)` takes place per `<-`, `easy_reload` or `easy_clear` 82 | operation. 83 | 84 | ## v.1.1.0 85 | 86 | * Now it's possible to combine `multipliers` with `Equal`, `GreaterThatOrEqual` 87 | and `LessThanOrEqual` relations. 88 | 89 | ```swift 90 | // i.e. 91 | Width(>=20*0.5) // value = 20, multiplier = 0.5, relation = .GreaterThanOrEqual 92 | Width(<=20*0.5) // value = 20, multiplier = 0.5, relation = .LessThanOrEqual 93 | Width(==20*0.5) // value = 20, multiplier = 0.5, relation = .Equal 94 | ``` 95 | 96 | # v.1.0.0 97 | 98 | * Improved performance, benchmarks show up to a 250% improvement applying `Attributes` with the apply operator `<-`, resolving 99 | conflicts and using `easy_clear` and `easy_reload` methods. 100 | * `NSLayoutConstraint` conflict resolution is more accurate and strict. 101 | * Added support to `NSLayoutGuide`. 102 | 103 | ## v.0.3.0 104 | 105 | * Supported tvOS and OS X. 106 | * Added OS X sample project. 107 | 108 | ## v.0.2.5 109 | 110 | * Added support to `UIViewController` top and bottom layout guides that conform 111 | the `UILayoutSupport` protocol. 112 | 113 | ```swift 114 | view <- [ 115 | Size(100), 116 | CenterX(0), 117 | Top(0).to(controller.topLayoutGuide) 118 | ] 119 | ``` 120 | 121 | ## v.0.2.4 122 | 123 | * `Priorities` and `Conditions` now can be easily applied to an `Array` of `Attributes`. 124 | 125 | ```swift 126 | view <- [ 127 | Width(200), 128 | Height(240) 129 | ].when { Device() == .iPad } 130 | 131 | view <- [ 132 | Width(120), 133 | Height(140) 134 | ].when { Device() == .iPhone } 135 | ``` 136 | 137 | ## v.0.2.3 138 | 139 | * Added `UILayoutGuide` support (iOS 9 and above). 140 | 141 | ## v.0.2.2 142 | 143 | * Fixed bug clearing conflicting `Attributes` using `easy_reload`. 144 | * Apply operator `<-` returns the `NSLayoutConstraints` created. 145 | 146 | ## v.0.2.1 147 | 148 | * `Constant` values of `CGFloat` type. 149 | * Optimized apply `<-` operation. 150 | 151 | ## v.0.2 152 | 153 | * Replaced `addConstraint` and `removeConstraint` methods with `activateConstraints` 154 | and `deactivateConstraints`. 155 | * Extended `UIView` with `easy_clear()`, a method to clear the constraints applied 156 | to the `UIView` using **EasyPeasy**. 157 | * Improved **README** file. 158 | -------------------------------------------------------------------------------- /Dangerfile: -------------------------------------------------------------------------------- 1 | workspace = "Example/EasyPeasy.xcworkspace" 2 | scheme = "EasyPeasy-Example-iOS" 3 | 4 | # Coverage report 5 | xcov.report( 6 | scheme: scheme, 7 | workspace: workspace, 8 | exclude_targets: 'Demo.app,Demo macOS.app,Pods_Demo.framework,Pods_Tests.framework', 9 | minimum_coverage_percentage: 90.0 10 | ) 11 | -------------------------------------------------------------------------------- /EasyPeasy.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "EasyPeasy" 3 | s.version = "1.10.0" 4 | s.summary = "EasyPeasy is a Swift framework that eases the creation of 5 | Autolayout constraints programmatically" 6 | s.description = <<-DESC 7 | EasyPeasy is a Swift framework that lets you create Autolayout constraints 8 | programmatically without headaches and never ending boilerplate code. Besides the 9 | basics, **EasyPeasy** resolves most of the constraint conflicts for you and lets 10 | you attach to a constraint conditional closures that are evaluated before applying 11 | a constraint, this lets you apply (or not) a constraint depending on platform, size 12 | classes, orientation... or the state of your controller, easy peasy! 13 | DESC 14 | s.homepage = "https://github.com/nakiostudio/EasyPeasy" 15 | s.license = 'MIT' 16 | s.author = { "Carlos Vidal" => "nakioparkour@gmail.com" } 17 | s.source = { :git => "https://github.com/nakiostudio/EasyPeasy.git", :tag => "v#{s.version.to_s}" } 18 | s.social_media_url = 'https://twitter.com/carlostify' 19 | 20 | s.ios.deployment_target = '8.0' 21 | s.tvos.deployment_target = '9.0' 22 | s.osx.deployment_target = '10.10' 23 | s.swift_version = '5.0' 24 | 25 | s.requires_arc = true 26 | s.source_files = 'EasyPeasy/**/*' 27 | end 28 | 29 | -------------------------------------------------------------------------------- /EasyPeasy/Collection+Easy.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) - Copyright (c) 2016 Carlos Vidal 2 | // 3 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 4 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 5 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 6 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 7 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 8 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 9 | // SOFTWARE. 10 | 11 | import Foundation 12 | 13 | extension Collection { 14 | 15 | func easy_flatMap(_ transform: (Element) throws -> ElementOfResult?) rethrows -> [ElementOfResult] { 16 | #if swift(>=4.1) 17 | return try self.compactMap(transform) 18 | #else 19 | return try self.flatMap(transform) 20 | #endif 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /EasyPeasy/CompoundAttribute.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) - Copyright (c) 2016 Carlos Vidal 2 | // 3 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 4 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 5 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 6 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 7 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 8 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 9 | // SOFTWARE. 10 | 11 | #if os(iOS) || os(tvOS) 12 | import UIKit 13 | #else 14 | import AppKit 15 | #endif 16 | 17 | /** 18 | `Attribute` that leads on the application of multiple 19 | `Attribute` objects 20 | */ 21 | open class CompoundAttribute: Attribute { 22 | 23 | /// Array of attributes that shape the `CompoundAttribute` 24 | open internal(set) var attributes: [Attribute] = [] 25 | 26 | // MARK: Public methods 27 | 28 | /** 29 | Sets the `priority` of the constraint and subconstraints 30 | - parameter priority: `Priority` enum specifying the 31 | priority of the constraint 32 | - returns: the `Attribute` instance 33 | */ 34 | @discardableResult open override func with(_ priority: Priority) -> Self { 35 | super.with(priority) 36 | for attribute in self.attributes { 37 | attribute.with(priority) 38 | } 39 | return self 40 | } 41 | 42 | /** 43 | Sets the `when` closure of the `Attribute` and each one 44 | of the `Attribute` objects shaping the `CompoundAttribute` 45 | - parameter closure: `Closure` to be called before 46 | installing a constraint 47 | - returns: the `Attribute` instance 48 | */ 49 | @discardableResult open override func when(_ closure: Condition?) -> Self { 50 | super.when(closure) 51 | for attribute in self.attributes { 52 | attribute.when(closure) 53 | } 54 | return self 55 | } 56 | 57 | #if os(iOS) 58 | /** 59 | Sets the `when` closure of the `Attribute` and each one 60 | of the `Attribute` objects shaping the `CompoundAttribute` 61 | - parameter closure: `Closure` to be called before installing a 62 | constraint 63 | - returns: the `Attribute` instance 64 | */ 65 | @discardableResult open override func when(_ closure: ContextualCondition?) -> Self { 66 | super.when(closure) 67 | for attribute in self.attributes { 68 | attribute.when(closure) 69 | } 70 | return self 71 | } 72 | #endif 73 | 74 | } 75 | -------------------------------------------------------------------------------- /EasyPeasy/Context.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) - Copyright (c) 2016 Carlos Vidal 2 | // 3 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 4 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 5 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 6 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 7 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 8 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 9 | // SOFTWARE. 10 | 11 | #if os(iOS) 12 | 13 | import UIKit 14 | 15 | /** 16 | Struct that from an `UITraitCollection` object populates some helper 17 | properties easing access to device and size class information 18 | */ 19 | public struct Context { 20 | 21 | /// `true` if the current device is an iPad 22 | public let isPad: Bool 23 | 24 | /// `true` if the current device is an iPhone 25 | public let isPhone: Bool 26 | 27 | /// `true` if both horizontal and vertical size classes are `.Compact` 28 | public let isHorizontalVerticalCompact: Bool 29 | 30 | /// `true` if horizontal size class is `.Compact` 31 | public let isHorizontalCompact: Bool 32 | 33 | /// `true` if vertical size class is `.Compact` 34 | public let isVerticalCompact: Bool 35 | 36 | /// `true` if both horizontal and vertical size classes are `.Regular` 37 | public let isHorizontalVerticalRegular: Bool 38 | 39 | /// `true` if horizontal size class is `.Regular` 40 | public let isHorizontalRegular: Bool 41 | 42 | /// `true` if vertical size class is `.Regular` 43 | public let isVerticalRegular: Bool 44 | 45 | /** 46 | Given an `UITraitCollection` object populates device and size class 47 | helper properties 48 | */ 49 | init(with traitCollection: UITraitCollection) { 50 | // Device info 51 | self.isPad = traitCollection.userInterfaceIdiom == .pad 52 | self.isPhone = UIDevice.current.userInterfaceIdiom == .phone 53 | 54 | // Compact size classes 55 | self.isHorizontalCompact = traitCollection.horizontalSizeClass == .compact 56 | self.isVerticalCompact = traitCollection.verticalSizeClass == .compact 57 | self.isHorizontalVerticalCompact = traitCollection.horizontalSizeClass == .compact && traitCollection.verticalSizeClass == .compact 58 | 59 | // Regular size classes 60 | self.isVerticalRegular = traitCollection.verticalSizeClass == .regular 61 | self.isHorizontalRegular = traitCollection.horizontalSizeClass == .regular 62 | self.isHorizontalVerticalRegular = traitCollection.horizontalSizeClass == .regular && traitCollection.verticalSizeClass == .regular 63 | } 64 | 65 | } 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /EasyPeasy/DimensionAttribute+AppKit.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) - Copyright (c) 2016 Carlos Vidal 2 | // 3 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 4 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 5 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 6 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 7 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 8 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 9 | // SOFTWARE. 10 | 11 | #if !(os(iOS) || os(tvOS)) 12 | 13 | import AppKit 14 | 15 | /** 16 | DimensionAttribute extension adding some convenience methods to operate with 17 | `NSViews` 18 | */ 19 | extension DimensionAttribute { 20 | 21 | /** 22 | Establishes a relationship between the dimension attribute 23 | applied to the `NSView` and the reference `NSView` passed as 24 | parameter. 25 | 26 | It's also possible to link this relationship to a particular 27 | attribute of the `view` parameter by supplying `attribute`. 28 | 29 | - parameter view: The reference view 30 | - parameter attribute: The attribute of `view` we are establishing the 31 | relationship to 32 | - returns: The current `Attribute` instance 33 | */ 34 | public func like(_ view: NSView, _ attribute: ReferenceAttribute? = nil) -> Self { 35 | self.referenceItem = view 36 | self.referenceAttribute = attribute 37 | return self 38 | } 39 | 40 | /** 41 | Establishes a relationship between the dimension attribute 42 | applied to the `NSView` and the reference `NSLayoutGuide` 43 | passed as parameter. 44 | 45 | It's also possible to link this relationship to a particular 46 | attribute of the `layoutGuide` parameter by supplying `attribute`. 47 | 48 | - parameter layoutGuide: The reference `NSLayoutGuide` 49 | - parameter attribute: The attribute of `layoutGuide` we are establishing 50 | the relationship to 51 | - returns: The current `Attribute` instance 52 | */ 53 | @available (OSX 10.11, *) 54 | public func like(_ layoutGuide: NSLayoutGuide, _ attribute: ReferenceAttribute? = nil) -> Self { 55 | self.referenceItem = layoutGuide 56 | self.referenceAttribute = attribute 57 | return self 58 | } 59 | 60 | } 61 | 62 | /** 63 | Size extension adding some convenience methods to let this CompoundAttribute 64 | operate with `NSViews` 65 | */ 66 | extension Size { 67 | 68 | /** 69 | Establishes a relationship between the dimension attribute 70 | applied to the `NSView` and the reference `NSView` passed as 71 | parameter. 72 | - parameter view: The reference view 73 | - returns: The current `CompoundAttribute` instance 74 | */ 75 | public func like(_ view: NSView) -> Self { 76 | self.referenceItem = view 77 | for attr in self.attributes { 78 | attr.referenceItem = view 79 | } 80 | return self 81 | } 82 | 83 | /** 84 | Establishes a relationship between the dimension attribute 85 | applied to the `NSView` and the reference `NSLayoutGuide` 86 | passed as parameter. 87 | - parameter layoutGuide: The reference `NSLayoutGuide` 88 | - returns: The current `CompoundAttribute` instance 89 | */ 90 | @available (OSX 10.11, *) 91 | public func like(_ layoutGuide: NSLayoutGuide) -> Self { 92 | self.referenceItem = layoutGuide 93 | for attr in self.attributes { 94 | attr.referenceItem = layoutGuide 95 | } 96 | return self 97 | } 98 | 99 | } 100 | 101 | #endif 102 | -------------------------------------------------------------------------------- /EasyPeasy/DimensionAttribute+UIKit.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) - Copyright (c) 2016 Carlos Vidal 2 | // 3 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 4 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 5 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 6 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 7 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 8 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 9 | // SOFTWARE. 10 | 11 | #if os(iOS) || os(tvOS) 12 | 13 | import UIKit 14 | 15 | /** 16 | DimensionAttribute extension adding some convenience methods to operate with 17 | UIKit elements as `UIViews` or `UILayoutGuides` 18 | */ 19 | public extension DimensionAttribute { 20 | 21 | /** 22 | Establishes a relationship between the dimension attribute 23 | applied to the `UIView` and the reference `UIView` passed as 24 | parameter. 25 | 26 | It's also possible to link this relationship to a particular 27 | attribute of the `view` parameter by supplying `attribute`. 28 | 29 | - parameter view: The reference view 30 | - parameter attribute: The attribute of `view` we are establishing the 31 | relationship to 32 | - returns: The current `Attribute` instance 33 | */ 34 | @discardableResult func like(_ view: UIView, _ attribute: ReferenceAttribute? = nil) -> Self { 35 | self.referenceItem = view 36 | self.referenceAttribute = attribute 37 | return self 38 | } 39 | 40 | /** 41 | Establishes a relationship between the dimension attribute 42 | applied to the `UIView` and the reference `UILayoutGuide` 43 | passed as parameter. 44 | 45 | It's also possible to link this relationship to a particular 46 | attribute of the `layoutGuide` parameter by supplying `attribute`. 47 | 48 | - parameter layoutGuide: The reference `UILayoutGuide` 49 | - parameter attribute: The attribute of `layoutGuide` we are establishing 50 | the relationship to 51 | - returns: The current `Attribute` instance 52 | */ 53 | @available (iOS 9.0, *) 54 | @discardableResult func like(_ layoutGuide: UILayoutGuide, _ attribute: ReferenceAttribute? = nil) -> Self { 55 | self.referenceItem = layoutGuide 56 | self.referenceAttribute = attribute 57 | return self 58 | } 59 | 60 | } 61 | 62 | /** 63 | Size extension adding some convenience methods to let this CompoundAttribute 64 | operate with UIKit elements like `UIViews` or `UILayoutGuides` 65 | */ 66 | public extension Size { 67 | 68 | /** 69 | Establishes a relationship between the dimension attribute 70 | applied to the `UIView` and the reference `UIView` passed as 71 | parameter. 72 | - parameter view: The reference view 73 | - returns: The current `CompoundAttribute` instance 74 | */ 75 | @discardableResult func like(_ view: UIView) -> Self { 76 | self.referenceItem = view 77 | for attr in self.attributes { 78 | attr.referenceItem = view 79 | } 80 | return self 81 | } 82 | 83 | /** 84 | Establishes a relationship between the dimension attribute 85 | applied to the `UIView` and the reference `UILayoutGuide` 86 | passed as parameter. 87 | - parameter layoutGuide: The reference `UILayoutGuide` 88 | - returns: The current `CompoundAttribute` instance 89 | */ 90 | @available (iOS 9.0, *) 91 | @discardableResult func like(_ layoutGuide: UILayoutGuide) -> Self { 92 | self.referenceItem = layoutGuide 93 | for attr in self.attributes { 94 | attr.referenceItem = layoutGuide 95 | } 96 | return self 97 | } 98 | 99 | } 100 | 101 | #endif 102 | -------------------------------------------------------------------------------- /EasyPeasy/DimensionAttribute.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) - Copyright (c) 2016 Carlos Vidal 2 | // 3 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 4 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 5 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 6 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 7 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 8 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 9 | // SOFTWARE. 10 | 11 | #if os(iOS) || os(tvOS) 12 | import UIKit 13 | #else 14 | import AppKit 15 | #endif 16 | 17 | /** 18 | Superclass for those `Attribute` objects that imply dimension 19 | constraints like width and height 20 | */ 21 | open class DimensionAttribute: Attribute { 22 | 23 | /// Whether the `NSLayoutConstraint` generated by the 24 | /// `Attribute` is owned by the the `createItem` 25 | open override var ownedByItem: Bool { 26 | return true 27 | } 28 | 29 | } 30 | 31 | /** 32 | The width of the object’s alignment rectangle 33 | */ 34 | public class Width: DimensionAttribute { 35 | 36 | /// `Attribute` applied to the view 37 | public override var createAttribute: ReferenceAttribute { 38 | return .width 39 | } 40 | 41 | } 42 | 43 | /** 44 | The height of the object’s alignment rectangle 45 | */ 46 | public class Height: DimensionAttribute { 47 | 48 | /// `Attribute` applied to the view 49 | public override var createAttribute: ReferenceAttribute { 50 | return .height 51 | } 52 | 53 | } 54 | 55 | /** 56 | The size of the object’s rectangle 57 | */ 58 | public class Size: CompoundAttribute { 59 | 60 | /** 61 | Initializer which creates a `CompountAttribute` instance formed 62 | by `Width` and `Height` attributes with `constant = 0.0`, 63 | `multiplier = 1.0` and `relatedBy = .Equal` 64 | - returns: the `CompoundAttribute` instance created 65 | */ 66 | public override init() { 67 | super.init() 68 | self.attributes = [ 69 | Width(), 70 | Height() 71 | ] 72 | } 73 | 74 | /** 75 | Initializer which creates a `CompountAttribute` instance formed 76 | by `Width` and `Height` attributes with `constant = value`, 77 | `multiplier = 1.0` and `relatedBy = .Equal` 78 | - parameter value: `constant` of the constraint 79 | - returns: the `CompoundAttribute` instance created 80 | */ 81 | public override init(_ value: CGFloat) { 82 | super.init() 83 | self.attributes = [ 84 | Width(value), 85 | Height(value) 86 | ] 87 | } 88 | 89 | /** 90 | Initializer which creates a `CompountAttribute` instance formed 91 | by `Width` and `Height` attributes with the `constant`, 92 | `multiplier` and `relatedBy` defined by the `Constant` supplied 93 | - parameter constant: `Constant` struct aggregating `constant`, 94 | `multiplier` and `relatedBy` properties 95 | - returns: the `CompoundAttribute` instance created 96 | */ 97 | public override init(_ constant: Constant) { 98 | super.init() 99 | self.attributes = [ 100 | Width(constant), 101 | Height(constant) 102 | ] 103 | } 104 | 105 | /** 106 | Initializer which creates a `CompountAttribute` instance formed 107 | by `Width` and `Height` attributes with `constant = size.width` 108 | and `constant = size.height` respectively, `multiplier = 1.0` 109 | and `relatedBy = .Equal` 110 | - parameter size: `CGSize` that sets the constants for the `Width` 111 | and `Height` *subattributes* 112 | - returns: the `CompoundAttribute` instance created 113 | */ 114 | public init(_ size: CGSize) { 115 | super.init() 116 | self.attributes = [ 117 | Width(CGFloat(size.width)), 118 | Height(CGFloat(size.height)) 119 | ] 120 | } 121 | 122 | } 123 | -------------------------------------------------------------------------------- /EasyPeasy/EasyPeasy.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) - Copyright (c) 2016 Carlos Vidal 2 | // 3 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 4 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 5 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 6 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 7 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 8 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 9 | // SOFTWARE. 10 | 11 | import Foundation 12 | 13 | #if os(iOS) || os(tvOS) 14 | import UIKit 15 | #elseif os(OSX) 16 | import AppKit 17 | #endif 18 | 19 | /** 20 | Struct holding the main **EasyPeasy** operations: `layout`, `reload` and 21 | `clear` 22 | */ 23 | public struct EasyPeasy { 24 | 25 | /// Weak reference to the `Item` that owns this wrapper 26 | weak var item: Item? 27 | 28 | /** 29 | Applies the attributes given to the current item 30 | - parameter attributes: `Attributes` applied to the `Item` 31 | - returns: The array of `NSLayoutConstraints` created and applied 32 | */ 33 | @discardableResult public func layout(_ attributes: Attribute...) -> [NSLayoutConstraint] { 34 | return self.item?.apply(attributes: attributes) ?? [] 35 | } 36 | 37 | /** 38 | Applies the attributes given to the current item 39 | - parameter attributes: `Attributes` applied to the `Item` 40 | - returns: The array of `NSLayoutConstraints` created and applied 41 | */ 42 | @discardableResult public func layout(_ attributes: [Attribute]) -> [NSLayoutConstraint] { 43 | return self.item?.apply(attributes: attributes) ?? [] 44 | } 45 | 46 | /** 47 | This method will trigger the recreation of the created using 48 | *EasyPeasy* for the current view. `Condition` closures will 49 | be evaluated again 50 | */ 51 | public func reload() { 52 | self.item?.reload() 53 | } 54 | 55 | /** 56 | Clears all the constraints applied with EasyPeasy to current 57 | `Item` 58 | */ 59 | public func clear() { 60 | self.item?.clear() 61 | } 62 | 63 | } 64 | 65 | -------------------------------------------------------------------------------- /EasyPeasy/Item+AppKit.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) - Copyright (c) 2016 Carlos Vidal 2 | // 3 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 4 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 5 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 6 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 7 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 8 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 9 | // SOFTWARE. 10 | 11 | #if !(os(iOS) || os(tvOS)) 12 | 13 | import AppKit 14 | 15 | /// Alias of NSView 16 | public typealias View = NSView 17 | 18 | /** 19 | Extension making `NSView` conform the `Item` protocol and 20 | therefore inherit the extended methods and properties 21 | */ 22 | extension NSView: Item { 23 | 24 | /// Owning `NSView` for the current `Item`. The concept varies 25 | /// depending on the class conforming the protocol 26 | public var owningView: View? { 27 | // Owning view for `NSView` is the `superview` 28 | return self.superview 29 | } 30 | 31 | } 32 | 33 | /** 34 | Extension making `UILayoutGuide` conform the `Item` protocol 35 | therefore and inherit the extended methods and properties 36 | */ 37 | @available(OSX 10.11, *) 38 | extension NSLayoutGuide: Item { 39 | 40 | /// Constraints in `owningView` with the current `NSLayoutGuide` 41 | /// as `firstItem` 42 | public var constraints: [NSLayoutConstraint] { 43 | return self.owningView?.constraints.filter { $0.firstItem === self } ?? [] 44 | } 45 | 46 | } 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /EasyPeasy/Item+UIKit.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) - Copyright (c) 2016 Carlos Vidal 2 | // 3 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 4 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 5 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 6 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 7 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 8 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 9 | // SOFTWARE. 10 | 11 | #if os(iOS) || os(tvOS) 12 | 13 | import UIKit 14 | 15 | /// Alias of UIView 16 | public typealias View = UIView 17 | 18 | /** 19 | Extension making `UIView` conform the `Item` protocol and 20 | therefore inherit the extended methods and properties 21 | */ 22 | extension UIView: Item { 23 | 24 | /// Owning `UIView` for the current `Item`. The concept varies 25 | /// depending on the class conforming the protocol 26 | public var owningView: View? { 27 | return self.superview 28 | } 29 | 30 | } 31 | 32 | /** 33 | Extension making `UILayoutGuide` conform the `Item` protocol 34 | therefore and inherit the extended methods and properties 35 | */ 36 | @available(iOS 9.0, *) 37 | extension UILayoutGuide: Item { 38 | 39 | /// Constraints in `owningView` with the current `UILayoutGuide` 40 | /// as `firstItem` 41 | public var constraints: [NSLayoutConstraint] { 42 | return self.owningView?.constraints.filter { $0.firstItem === self } ?? [] 43 | } 44 | 45 | } 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /EasyPeasy/NSLayoutGuide+Easy.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) - Copyright (c) 2016 Carlos Vidal 2 | // 3 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 4 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 5 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 6 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 7 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 8 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 9 | // SOFTWARE. 10 | 11 | #if !(os(iOS) || os(tvOS)) 12 | 13 | import AppKit 14 | 15 | /** 16 | Apply operator definitions 17 | */ 18 | @available (OSX 10.11, *) 19 | extension NSLayoutGuide { 20 | 21 | /** 22 | Operator which applies the attribute given to the `NSLayoutGuide` 23 | located in the left hand side of it 24 | - parameter lhs: `NSLayoutGuide` the attributes will apply to 25 | - parameter rhs: Attribute applied to the `NSLayoutGuide` 26 | - returns: The array of `NSLayoutConstraints` applied 27 | */ 28 | @discardableResult public static func <- (lhs: NSLayoutGuide, rhs: Attribute) -> [NSLayoutConstraint] { 29 | return lhs <- [rhs] 30 | } 31 | 32 | /** 33 | Opeator which applies the attributes given to the `NSLayoutGuide` 34 | located in the left hand side of it 35 | - parameter lhs: `NSLayoutGuide` the attributes will apply to 36 | - parameter rhs: Attributes applied to the `NSLayoutGuide` 37 | - returns: The array of `NSLayoutConstraints` applied 38 | */ 39 | @discardableResult public static func <- (lhs: NSLayoutGuide, rhs: [Attribute]) -> [NSLayoutConstraint] { 40 | // Apply attributes and return the installed `NSLayoutConstraints` 41 | return lhs.apply(attributes: rhs) 42 | } 43 | 44 | } 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /EasyPeasy/NSView+Easy.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) - Copyright (c) 2016 Carlos Vidal 2 | // 3 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 4 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 5 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 6 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 7 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 8 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 9 | // SOFTWARE. 10 | 11 | #if !(os(iOS) || os(tvOS)) 12 | 13 | import AppKit 14 | 15 | infix operator <- 16 | 17 | /** 18 | Apply operator definitions 19 | */ 20 | public extension NSView { 21 | 22 | /** 23 | Operator which applies the attribute given to the view located 24 | in the left hand side of it 25 | - parameter lhs: `NSView` the attributes will apply to 26 | - parameter rhs: Attribute applied to the `NSView` 27 | - returns: The array of `NSLayoutConstraints` applied 28 | */ 29 | @available(iOS, deprecated: 1.5.1, message: "Use easy.layout(_:) instead") 30 | @discardableResult static func <- (lhs: NSView, rhs: Attribute) -> [NSLayoutConstraint] { 31 | return lhs <- [rhs] 32 | } 33 | 34 | /** 35 | Opeator which applies the attributes given to the view located 36 | in the left hand side of it 37 | - parameter lhs: NSView the attributes will apply to 38 | - parameter rhs: Attributes applied to the NSView 39 | - returns: The array of `NSLayoutConstraints` applied 40 | */ 41 | @available(iOS, deprecated: 1.5.1, message: "Use easy.layout(_:) instead") 42 | @discardableResult static func <- (lhs: NSView, rhs: [Attribute]) -> [NSLayoutConstraint] { 43 | // Disable autoresizing to constraints translation 44 | lhs.translatesAutoresizingMaskIntoConstraints = false 45 | 46 | // Apply attributes and return the installed `NSLayoutConstraints` 47 | return lhs.apply(attributes: rhs) 48 | } 49 | 50 | } 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /EasyPeasy/PositionAttribute+AppKit.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) - Copyright (c) 2016 Carlos Vidal 2 | // 3 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 4 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 5 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 6 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 7 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 8 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 9 | // SOFTWARE. 10 | 11 | #if !(os(iOS) || os(tvOS)) 12 | 13 | import AppKit 14 | 15 | /** 16 | DimensionAttribute extension adding some convenience methods to operate with 17 | `NSViews` 18 | */ 19 | extension PositionAttribute { 20 | 21 | /** 22 | Establishes a position relationship between the `NSView` the attribute 23 | is applied to and the `NSView` passed as parameter. 24 | 25 | It's also possible to link this relationship to a particular attribute 26 | of the `view` parameter by supplying `attribute`. 27 | 28 | - parameter view: The reference view 29 | - parameter attribute: The attribute of `view` we are establishing the 30 | relationship to 31 | - returns: The current `Attribute` instance 32 | */ 33 | @discardableResult public func to(_ view: NSView, _ attribute: ReferenceAttribute? = nil) -> Self { 34 | self.referenceItem = view 35 | self.referenceAttribute = attribute 36 | return self 37 | } 38 | 39 | /** 40 | Establishes a position relationship between the `NSView` the attribute 41 | is applied to and the `NSLayoutGuide` passed as parameter. 42 | 43 | It's also possible to link this relationship to a particular attribute 44 | of the `view` parameter by supplying `attribute`. 45 | 46 | - parameter layoutGuide: The reference `NSLayoutGuide` 47 | - parameter attribute: The attribute of `view` we are establishing the 48 | relationship to 49 | - returns: The current `Attribute` instance 50 | */ 51 | @available(OSX 10.11, *) 52 | @discardableResult public func to(_ layoutGuide: NSLayoutGuide, _ attribute: ReferenceAttribute? = nil) -> Self { 53 | self.referenceItem = layoutGuide 54 | self.referenceAttribute = attribute 55 | return self 56 | } 57 | 58 | } 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /EasyPeasy/Priority.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) - Copyright (c) 2016 Carlos Vidal 2 | // 3 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 4 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 5 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 6 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 7 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 8 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 9 | // SOFTWARE. 10 | 11 | import Foundation 12 | 13 | /** 14 | Enum which offers 3 pre-defined levels of `UILayoutPriority` 15 | as well as a case wrapping a `Float` value to specify actual 16 | values 17 | */ 18 | public enum Priority { 19 | 20 | case custom(Float) 21 | case required 22 | case high 23 | case medium 24 | case low 25 | 26 | @available(*, deprecated, message: "Use custom case instead") 27 | case customPriority(Float) 28 | @available(*, deprecated, message: "Use required case instead") 29 | case highPriority 30 | @available(*, deprecated, message: "Use medium case instead") 31 | case mediumPriority 32 | @available(*, deprecated, message: "Use low case instead") 33 | case lowPriority 34 | 35 | /** 36 | `UILayoutPriority` equivalent to the current case 37 | - returns `UILayoutPriority` 38 | */ 39 | func layoutPriority() -> Float { 40 | switch self { 41 | case .customPriority(let value): return value 42 | case .highPriority: return 1000.0 43 | case .mediumPriority: return 500.0 44 | case .lowPriority: return 1.0 45 | case .custom(let value): return value 46 | case .required: return 1000.0 47 | case .high: return 750.0 48 | case .medium: return 500.0 49 | case .low: return 250.0 50 | } 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /EasyPeasy/UILayoutGuide+Easy.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) - Copyright (c) 2016 Carlos Vidal 2 | // 3 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 4 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 5 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 6 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 7 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 8 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 9 | // SOFTWARE. 10 | 11 | #if os(iOS) || os(tvOS) 12 | 13 | import UIKit 14 | 15 | /** 16 | Apply operator definitions 17 | */ 18 | @available (iOS 9.0, *) 19 | public extension UILayoutGuide { 20 | 21 | /** 22 | Operator which applies the attribute given to the `UILayoutGuide` 23 | located in the left hand side of it 24 | - parameter lhs: `UILayoutGuide` the attributes will apply to 25 | - parameter rhs: Attribute applied to the `UILayoutGuide` 26 | - returns: The array of `NSLayoutConstraints` applied 27 | */ 28 | @available(iOS, deprecated: 1.5.1, message: "Use easy.layout(_:) instead") 29 | @discardableResult static func <- (lhs: UILayoutGuide, rhs: Attribute) -> [NSLayoutConstraint] { 30 | return lhs <- [rhs] 31 | } 32 | 33 | /** 34 | Opeator which applies the attributes given to the `UILayoutGuide` 35 | located in the left hand side of it 36 | - parameter lhs: `UILayoutGuide` the attributes will apply to 37 | - parameter rhs: Attributes applied to the `UILayoutGuide` 38 | - returns: The array of `NSLayoutConstraints` applied 39 | */ 40 | @available(iOS, deprecated: 1.5.1, message: "Use easy.layout(_:) instead") 41 | @discardableResult static func <- (lhs: UILayoutGuide, rhs: [Attribute]) -> [NSLayoutConstraint] { 42 | // Apply attributes and return the installed `NSLayoutConstraints` 43 | return lhs.apply(attributes: rhs) 44 | } 45 | 46 | } 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /EasyPeasy/UIView+Easy.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) - Copyright (c) 2016 Carlos Vidal 2 | // 3 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 4 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 5 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 6 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 7 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 8 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 9 | // SOFTWARE. 10 | 11 | #if os(iOS) || os(tvOS) 12 | 13 | import UIKit 14 | 15 | infix operator <- 16 | 17 | /** 18 | Apply operator definitions 19 | */ 20 | public extension UIView { 21 | 22 | /** 23 | Operator which applies the attribute given to the view located 24 | in the left hand side of it 25 | - parameter lhs: `UIView` the attributes will apply to 26 | - parameter rhs: Attribute applied to the `UIView` 27 | - returns: The array of `NSLayoutConstraints` applied 28 | */ 29 | @available(iOS, deprecated: 1.5.1, message: "Use easy.layout(_:) instead") 30 | @discardableResult static func <- (lhs: UIView, rhs: Attribute) -> [NSLayoutConstraint] { 31 | return lhs <- [rhs] 32 | } 33 | 34 | /** 35 | Opeator which applies the attributes given to the view located 36 | in the left hand side of it 37 | - parameter lhs: UIView the attributes will apply to 38 | - parameter rhs: Attributes applied to the UIView 39 | - returns: The array of `NSLayoutConstraints` applied 40 | */ 41 | @available(iOS, deprecated: 1.5.1, message: "Use easy.layout(_:) instead") 42 | @discardableResult static func <- (lhs: UIView, rhs: [Attribute]) -> [NSLayoutConstraint] { 43 | // Disable autoresizing to constraints translation 44 | lhs.translatesAutoresizingMaskIntoConstraints = false 45 | 46 | // Apply attributes and return the installed `NSLayoutConstraints` 47 | return lhs.apply(attributes: rhs) 48 | } 49 | 50 | } 51 | 52 | #endif 53 | 54 | #if os(iOS) && EASY_RELOAD 55 | 56 | /** 57 | Method that sets up the swizzling of `traitCollectionDidChange` if the 58 | compiler flag `EASY_RELOAD` has been defined 59 | */ 60 | private let traitCollectionDidChangeSwizzling: (UIView.Type) -> () = { view in 61 | let originalSelector = #selector(view.traitCollectionDidChange(_:)) 62 | let swizzledSelector = #selector(view.easy_traitCollectionDidChange(_:)) 63 | let originalMethod = class_getInstanceMethod(view, originalSelector) 64 | let swizzledMethod = class_getInstanceMethod(view, swizzledSelector) 65 | 66 | method_exchangeImplementations(originalMethod, swizzledMethod) 67 | } 68 | 69 | /** 70 | `UIView` extension that swizzles `traitCollectionDidChange` if the 71 | compiler flag `EASY_RELOAD` has been defined 72 | */ 73 | extension UIView { 74 | 75 | /** 76 | `traitCollectionDidChange` swizzling 77 | */ 78 | open override class func initialize() { 79 | guard self === UIView.self else { 80 | return 81 | } 82 | 83 | traitCollectionDidChangeSwizzling(self) 84 | } 85 | 86 | /** 87 | Performs `easy_reload` when the `UITraitCollection` has changed for 88 | the current `UIView`, triggering the re-evaluation of the `Attributes` 89 | applied 90 | */ 91 | func easy_traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { 92 | self.easy_traitCollectionDidChange(previousTraitCollection) 93 | 94 | // If at least one `Attribute has been applied to the current 95 | // `UIView` then perform `easy_reload` 96 | if self.traitCollection.containsTraits(in: previousTraitCollection) == false && self.nodes.values.count > 0 { 97 | self.easy.reload() 98 | } 99 | } 100 | 101 | } 102 | 103 | #endif 104 | -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS.xcodeproj/xcshareddata/xcschemes/EasyPeasy-Example-macOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 46 | 47 | 49 | 55 | 56 | 57 | 58 | 59 | 65 | 66 | 67 | 68 | 69 | 70 | 81 | 83 | 89 | 90 | 91 | 92 | 93 | 94 | 100 | 102 | 108 | 109 | 110 | 111 | 113 | 114 | 117 | 118 | 119 | -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) - Copyright (c) 2016 Carlos Vidal 2 | // 3 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 4 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 5 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 6 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 7 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 8 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 9 | // SOFTWARE. 10 | 11 | import Cocoa 12 | 13 | @NSApplicationMain 14 | class AppDelegate: NSObject, NSApplicationDelegate { 15 | 16 | @IBOutlet weak var window: NSWindow! 17 | 18 | func applicationDidFinishLaunching(_ aNotification: Notification) { 19 | self.window.styleMask = [self.window.styleMask, .fullSizeContentView] 20 | self.window.titleVisibility = .hidden 21 | self.window.titlebarAppearsTransparent = true 22 | } 23 | 24 | } 25 | 26 | -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "16x16", 5 | "idiom" : "mac", 6 | "filename" : "icon-mac-16.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "16x16", 11 | "idiom" : "mac", 12 | "filename" : "icon-mac-16@2x.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "32x32", 17 | "idiom" : "mac", 18 | "filename" : "icon-mac-32.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "32x32", 23 | "idiom" : "mac", 24 | "filename" : "icon-mac-32@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "128x128", 29 | "idiom" : "mac", 30 | "filename" : "icon-mac-128.png", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "size" : "128x128", 35 | "idiom" : "mac", 36 | "filename" : "icon-mac-128@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "256x256", 41 | "idiom" : "mac", 42 | "filename" : "icon-mac-256.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "256x256", 47 | "idiom" : "mac", 48 | "filename" : "icon-mac-512.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "512x512", 53 | "idiom" : "mac", 54 | "filename" : "icon-mac-513.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "512x512", 59 | "idiom" : "mac", 60 | "filename" : "icon-mac-512@2x.png", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/Assets.xcassets/AppIcon.appiconset/icon-mac-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/Example/Demo macOS/Demo macOS/Assets.xcassets/AppIcon.appiconset/icon-mac-128.png -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/Assets.xcassets/AppIcon.appiconset/icon-mac-128@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/Example/Demo macOS/Demo macOS/Assets.xcassets/AppIcon.appiconset/icon-mac-128@2x.png -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/Assets.xcassets/AppIcon.appiconset/icon-mac-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/Example/Demo macOS/Demo macOS/Assets.xcassets/AppIcon.appiconset/icon-mac-16.png -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/Assets.xcassets/AppIcon.appiconset/icon-mac-16@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/Example/Demo macOS/Demo macOS/Assets.xcassets/AppIcon.appiconset/icon-mac-16@2x.png -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/Assets.xcassets/AppIcon.appiconset/icon-mac-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/Example/Demo macOS/Demo macOS/Assets.xcassets/AppIcon.appiconset/icon-mac-256.png -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/Assets.xcassets/AppIcon.appiconset/icon-mac-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/Example/Demo macOS/Demo macOS/Assets.xcassets/AppIcon.appiconset/icon-mac-32.png -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/Assets.xcassets/AppIcon.appiconset/icon-mac-32@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/Example/Demo macOS/Demo macOS/Assets.xcassets/AppIcon.appiconset/icon-mac-32@2x.png -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/Assets.xcassets/AppIcon.appiconset/icon-mac-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/Example/Demo macOS/Demo macOS/Assets.xcassets/AppIcon.appiconset/icon-mac-512.png -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/Assets.xcassets/AppIcon.appiconset/icon-mac-512@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/Example/Demo macOS/Demo macOS/Assets.xcassets/AppIcon.appiconset/icon-mac-512@2x.png -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/Assets.xcassets/AppIcon.appiconset/icon-mac-513.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/Example/Demo macOS/Demo macOS/Assets.xcassets/AppIcon.appiconset/icon-mac-513.png -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/Assets.xcassets/Profile pictures/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/Assets.xcassets/Profile pictures/NatashaTheRobot.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "NatashaTheRobot.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/Assets.xcassets/Profile pictures/NatashaTheRobot.imageset/NatashaTheRobot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/Example/Demo macOS/Demo macOS/Assets.xcassets/Profile pictures/NatashaTheRobot.imageset/NatashaTheRobot.png -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/Assets.xcassets/Profile pictures/andy_matuschak.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "andy_matuschak.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/Assets.xcassets/Profile pictures/andy_matuschak.imageset/andy_matuschak.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/Example/Demo macOS/Demo macOS/Assets.xcassets/Profile pictures/andy_matuschak.imageset/andy_matuschak.png -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/Assets.xcassets/Profile pictures/ashfurrow.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "ashfurrow.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/Assets.xcassets/Profile pictures/ashfurrow.imageset/ashfurrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/Example/Demo macOS/Demo macOS/Assets.xcassets/Profile pictures/ashfurrow.imageset/ashfurrow.png -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/Assets.xcassets/Profile pictures/clattner_llvm.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "clattner_llvm.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/Assets.xcassets/Profile pictures/clattner_llvm.imageset/clattner_llvm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/Example/Demo macOS/Demo macOS/Assets.xcassets/Profile pictures/clattner_llvm.imageset/clattner_llvm.png -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/Assets.xcassets/Profile pictures/marcoshdezcif.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "marcoshdezcif.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/Assets.xcassets/Profile pictures/marcoshdezcif.imageset/marcoshdezcif.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/Example/Demo macOS/Demo macOS/Assets.xcassets/Profile pictures/marcoshdezcif.imageset/marcoshdezcif.png -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/Assets.xcassets/Profile pictures/orta.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "orta.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/Assets.xcassets/Profile pictures/orta.imageset/orta.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/Example/Demo macOS/Demo macOS/Assets.xcassets/Profile pictures/orta.imageset/orta.png -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/Assets.xcassets/Profile pictures/sandofsky.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "sandofsky.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/Assets.xcassets/Profile pictures/sandofsky.imageset/sandofsky.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/Example/Demo macOS/Demo macOS/Assets.xcassets/Profile pictures/sandofsky.imageset/sandofsky.png -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/Assets.xcassets/Profile pictures/steipete.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "steipete.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/Assets.xcassets/Profile pictures/steipete.imageset/steipete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/Example/Demo macOS/Demo macOS/Assets.xcassets/Profile pictures/steipete.imageset/steipete.png -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/Assets.xcassets/icon-compose.imageset/ComposeTweet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/Example/Demo macOS/Demo macOS/Assets.xcassets/icon-compose.imageset/ComposeTweet.png -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/Assets.xcassets/icon-compose.imageset/ComposeTweet@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/Example/Demo macOS/Demo macOS/Assets.xcassets/icon-compose.imageset/ComposeTweet@2x.png -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/Assets.xcassets/icon-compose.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "ComposeTweet.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "ComposeTweet@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/Assets.xcassets/icon-home.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Home.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "Home@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/Assets.xcassets/icon-home.imageset/Home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/Example/Demo macOS/Demo macOS/Assets.xcassets/icon-home.imageset/Home.png -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/Assets.xcassets/icon-home.imageset/Home@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/Example/Demo macOS/Demo macOS/Assets.xcassets/icon-home.imageset/Home@2x.png -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/Assets.xcassets/icon-messages.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Messages.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "Messages@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/Assets.xcassets/icon-messages.imageset/Messages.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/Example/Demo macOS/Demo macOS/Assets.xcassets/icon-messages.imageset/Messages.png -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/Assets.xcassets/icon-messages.imageset/Messages@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/Example/Demo macOS/Demo macOS/Assets.xcassets/icon-messages.imageset/Messages@2x.png -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/Assets.xcassets/icon-moments.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Moments.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "Moments@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/Assets.xcassets/icon-moments.imageset/Moments.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/Example/Demo macOS/Demo macOS/Assets.xcassets/icon-moments.imageset/Moments.png -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/Assets.xcassets/icon-moments.imageset/Moments@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/Example/Demo macOS/Demo macOS/Assets.xcassets/icon-moments.imageset/Moments@2x.png -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/Assets.xcassets/icon-notifications.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Notifications.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "Notifications@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/Assets.xcassets/icon-notifications.imageset/Notifications.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/Example/Demo macOS/Demo macOS/Assets.xcassets/icon-notifications.imageset/Notifications.png -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/Assets.xcassets/icon-notifications.imageset/Notifications@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/Example/Demo macOS/Demo macOS/Assets.xcassets/icon-notifications.imageset/Notifications@2x.png -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/Assets.xcassets/icon-search.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Search.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "Search@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/Assets.xcassets/icon-search.imageset/Search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/Example/Demo macOS/Demo macOS/Assets.xcassets/icon-search.imageset/Search.png -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/Assets.xcassets/icon-search.imageset/Search@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/Example/Demo macOS/Demo macOS/Assets.xcassets/icon-search.imageset/Search@2x.png -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/Assets.xcassets/thumb-easypeasy.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "thumb-easypeasy.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/Assets.xcassets/thumb-easypeasy.imageset/thumb-easypeasy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/Example/Demo macOS/Demo macOS/Assets.xcassets/thumb-easypeasy.imageset/thumb-easypeasy.png -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/FeedController.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) - Copyright (c) 2016 Carlos Vidal 2 | // 3 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 4 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 5 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 6 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 7 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 8 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 9 | // SOFTWARE. 10 | 11 | import AppKit 12 | import EasyPeasy 13 | 14 | // NOTE: 15 | // I know this controller could be easily achievable with a regular table 16 | // but this way is much easier to show the potential of EasyPeasy 17 | class FeedController: NSViewController { 18 | 19 | fileprivate let stubData = TweetModel.stubData() 20 | 21 | fileprivate lazy var sideBarView: SideBarView = { 22 | let view = SideBarView(frame: CGRect.zero) 23 | return view 24 | }() 25 | 26 | fileprivate lazy var feedView: FeedView = { 27 | let view = FeedView(frame: CGRect.zero) 28 | return view 29 | }() 30 | 31 | override func viewDidLoad() { 32 | super.viewDidLoad() 33 | 34 | self.setup() 35 | self.feedView.title = "Home" 36 | self.feedView.configure(with: self.stubData) 37 | self.sideBarView.configure( 38 | with: "thumb-easypeasy", 39 | tabs: "icon-home", 40 | "icon-moments", 41 | "icon-notifications", 42 | "icon-messages", 43 | "icon-search" 44 | ) 45 | } 46 | 47 | } 48 | 49 | /** 50 | Autolayout constraints 51 | */ 52 | extension FeedController { 53 | 54 | fileprivate func setup() { 55 | // Side bar 56 | self.view.addSubview(self.sideBarView) 57 | self.sideBarView.easy.layout( 58 | Width(80.0), 59 | Left(0.0), 60 | Top(0.0), 61 | Bottom(0.0) 62 | ) 63 | 64 | // Feed view 65 | self.view.addSubview(self.feedView) 66 | self.feedView.easy.layout( 67 | Top(0.0), 68 | Right(0.0), 69 | Bottom(0.0), 70 | Left(0.0).to(self.sideBarView) 71 | ) 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/FeedView.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) - Copyright (c) 2016 Carlos Vidal 2 | // 3 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 4 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 5 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 6 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 7 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 8 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 9 | // SOFTWARE. 10 | 11 | import AppKit 12 | import EasyPeasy 13 | 14 | class FeedView: NSView { 15 | 16 | fileprivate static let headerPadding: CGFloat = 12.0 17 | 18 | fileprivate lazy var titleLabel: NSTextField = { 19 | let label = NSTextField(frame: CGRect.zero) 20 | label.font = NSFont.boldSystemFont(ofSize: 14.0) 21 | label.textColor = NSColor.darkGray 22 | label.isBezeled = false 23 | label.isEditable = false 24 | label.isSelectable = false 25 | return label 26 | }() 27 | 28 | fileprivate lazy var scrollView: NSScrollView = { 29 | let view = NSScrollView(frame: CGRect.zero) 30 | return view 31 | }() 32 | 33 | fileprivate lazy var contentView: NSView = { 34 | let view = NSView(frame: CGRect.zero) 35 | return view 36 | }() 37 | 38 | fileprivate lazy var separatorView: NSView = { 39 | let view = NSView(frame: CGRect.zero) 40 | view.alphaValue = 0.4 41 | return view 42 | }() 43 | 44 | var title: String? { 45 | didSet { 46 | self.titleLabel.stringValue = self.title ?? "" 47 | } 48 | } 49 | 50 | required init?(coder: NSCoder) { 51 | super.init(coder: coder) 52 | self.setup() 53 | } 54 | 55 | override init(frame frameRect: NSRect) { 56 | super.init(frame: frameRect) 57 | self.setup() 58 | } 59 | 60 | override func draw(_ dirtyRect: NSRect) { 61 | NSColor.white.setFill() 62 | dirtyRect.fill() 63 | super.draw(dirtyRect) 64 | } 65 | 66 | override func layout() { 67 | super.layout() 68 | 69 | self.separatorView.layer?.backgroundColor = NSColor.lightGray.cgColor 70 | } 71 | 72 | // MARK: Public methods 73 | 74 | func configure(with tweets: [TweetModel]) { 75 | var priority = 500 - Float(tweets.count) 76 | var previousItem: NSView = self.contentView 77 | // Creates a tweetView for every tweet model within tweets array 78 | for tweet in tweets { 79 | let tweetView = TweetView(frame: CGRect.zero) 80 | tweetView.configure(with: tweet) 81 | 82 | // Layout "cells" 83 | self.contentView.addSubview(tweetView) 84 | tweetView.easy.layout( 85 | Top(0.0).to(previousItem), 86 | Left(0.0), 87 | Right(0.0), 88 | Height(>=TweetView.minimumHeight) 89 | ) 90 | 91 | // Pins contentView to bottom of the this item 92 | self.contentView.easy.layout( 93 | Bottom(>=0.0).to(tweetView, .bottom).with(.custom(priority)) 94 | ) 95 | 96 | // Set properties that apply to next tweetview creation 97 | previousItem = tweetView 98 | priority += 1.0 99 | } 100 | } 101 | 102 | } 103 | 104 | /** 105 | Autolayout constraints 106 | */ 107 | extension FeedView { 108 | 109 | fileprivate func setup() { 110 | // Title header 111 | self.addSubview(self.titleLabel) 112 | self.titleLabel.easy.layout( 113 | Top(FeedView.headerPadding), 114 | Size(>=0.0), 115 | CenterX(0.0) 116 | ) 117 | 118 | // Separator beneath title 119 | self.addSubview(self.separatorView) 120 | self.separatorView.easy.layout( 121 | Top(FeedView.headerPadding).to(self.titleLabel), 122 | Left(0.0), 123 | Right(0.0), 124 | Height(1.0) 125 | ) 126 | 127 | // Scroll view 128 | self.addSubview(self.scrollView) 129 | self.scrollView.easy.layout( 130 | Top(0.0).to(self.separatorView), 131 | Left(0.0), 132 | Right(0.0), 133 | Bottom(0.0) 134 | ) 135 | 136 | // Content of the scroll 137 | self.scrollView.documentView = self.contentView 138 | self.contentView.easy.layout( 139 | Top(0.0), 140 | Left(0.0), 141 | Bottom(>=0.0), 142 | Width(0.0).like(self.scrollView), 143 | Height(>=0.0) 144 | ) 145 | } 146 | 147 | } 148 | -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSMinimumSystemVersion 26 | $(MACOSX_DEPLOYMENT_TARGET) 27 | NSHumanReadableCopyright 28 | Copyright © 2016 nakioStudio. All rights reserved. 29 | NSMainNibFile 30 | MainMenu 31 | NSPrincipalClass 32 | NSApplication 33 | 34 | 35 | -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/NSColor+Easy.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) - Copyright (c) 2016 Carlos Vidal 2 | // 3 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 4 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 5 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 6 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 7 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 8 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 9 | // SOFTWARE. 10 | 11 | import Cocoa 12 | 13 | extension NSColor { 14 | 15 | static func easy_blue() -> NSColor { 16 | return NSColor(red: 112.0/255.0, green: 144.0/255.0, blue: 173.0/255.0, alpha: 1.0) 17 | } 18 | 19 | static func easy_backgroundBlue() -> NSColor { 20 | return NSColor(red: 35.0/255.0, green: 71.0/255.0, blue: 113.0/255.0, alpha: 1.0) 21 | } 22 | 23 | static func easy_highlightedBlue() -> NSColor { 24 | return NSColor(red: 76.0/255.0, green: 158.0/255.0, blue: 235.0/255.0, alpha: 1.0) 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/NSImage+Easy.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) - Copyright (c) 2016 Carlos Vidal 2 | // 3 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 4 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 5 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 6 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 7 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 8 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 9 | // SOFTWARE. 10 | 11 | import AppKit 12 | 13 | extension NSImage { 14 | 15 | func easy_tint(with color: NSColor) -> NSImage? { 16 | if let image = self.copy() as? NSImage { 17 | let bounds = CGRect(origin: CGPoint.zero, size: self.size) 18 | image.lockFocus() 19 | color.set() 20 | bounds.fill(using: .sourceAtop) 21 | image.unlockFocus() 22 | return image 23 | } 24 | 25 | return nil 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/SideBarView.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) - Copyright (c) 2016 Carlos Vidal 2 | // 3 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 4 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 5 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 6 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 7 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 8 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 9 | // SOFTWARE. 10 | 11 | import AppKit 12 | import EasyPeasy 13 | 14 | class SideBarView: NSView { 15 | 16 | fileprivate lazy var profileImageView: NSImageView = { 17 | let imageView = NSImageView(frame: CGRect.zero) 18 | return imageView 19 | }() 20 | 21 | fileprivate lazy var composeImageView: NSImageView = { 22 | let composeImageView = NSImageView(frame: CGRect.zero) 23 | return composeImageView 24 | }() 25 | 26 | required init?(coder: NSCoder) { 27 | super.init(coder: coder) 28 | self.setup() 29 | } 30 | 31 | override init(frame frameRect: NSRect) { 32 | super.init(frame: frameRect) 33 | self.setup() 34 | } 35 | 36 | override func draw(_ dirtyRect: NSRect) { 37 | NSColor.easy_backgroundBlue().setFill() 38 | dirtyRect.fill() 39 | super.draw(dirtyRect) 40 | } 41 | 42 | override func layout() { 43 | super.layout() 44 | self.profileImageView.layer?.cornerRadius = 4.0 45 | self.profileImageView.layer?.masksToBounds = true 46 | } 47 | 48 | // MARK: Public methods 49 | 50 | func configure(with profileImage: String, tabs: String...) { 51 | self.restore() 52 | self.profileImageView.image = NSImage(named: NSImage.Name(rawValue: profileImage)) 53 | self.composeImageView.image = NSImage(named: NSImage.Name(rawValue: "icon-compose"))?.easy_tint(with: NSColor.easy_highlightedBlue()) 54 | 55 | var previousItem: NSView = self.profileImageView 56 | var color: NSColor = NSColor.easy_highlightedBlue() 57 | var topPadding: CGFloat = 20.0 58 | 59 | // Creates an UImageView per string within tabs array 60 | for tabImage in tabs { 61 | // Create tab 62 | let tab = NSImageView(frame: CGRect.zero) 63 | tab.image = NSImage(named: NSImage.Name(rawValue: tabImage))?.easy_tint(with: color) 64 | 65 | // Layout UIImageView 66 | self.addSubview(tab) 67 | tab.easy.layout( 68 | Size(33.0), 69 | CenterX(0.0), 70 | Top(topPadding).to(previousItem) 71 | ) 72 | 73 | // Set properties that apply to next UIImageView creation 74 | color = NSColor.easy_blue() 75 | previousItem = tab 76 | topPadding = 14.0 77 | } 78 | } 79 | 80 | // MARK: Private methods 81 | 82 | fileprivate func restore() { 83 | let tabs = self.subviews.filter { $0 !== self.profileImageView && $0 !== self.composeImageView } 84 | for tab in tabs { 85 | tab.removeFromSuperview() 86 | } 87 | } 88 | 89 | } 90 | 91 | /** 92 | Autolayout constraints 93 | */ 94 | extension SideBarView { 95 | 96 | fileprivate func setup() { 97 | // Profile picture 98 | self.addSubview(self.profileImageView) 99 | self.profileImageView.easy.layout( 100 | Size(46.0), 101 | Top(60.0), 102 | CenterX(0.0) 103 | ) 104 | 105 | // Compose tweet icon 106 | self.addSubview(self.composeImageView) 107 | self.composeImageView.easy.layout( 108 | Size(33.0), 109 | Bottom(20.0), 110 | CenterX(0.0) 111 | ) 112 | } 113 | 114 | } 115 | -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOS/TweetModel.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) - Copyright (c) 2016 Carlos Vidal 2 | // 3 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 4 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 5 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 6 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 7 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 8 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 9 | // SOFTWARE. 10 | 11 | import AppKit 12 | 13 | struct TweetModel { 14 | 15 | let name: String 16 | let username: String 17 | let displayableDate: String 18 | let tweet: String 19 | 20 | var thumbnail: NSImage? { 21 | get { 22 | return NSImage(named: NSImage.Name(rawValue: self.username)) 23 | } 24 | } 25 | 26 | var displayableUsername: String { 27 | get { 28 | return "@\(self.username)" 29 | } 30 | } 31 | 32 | init(name: String, username: String, displayableDate: String, tweet: String) { 33 | self.name = name 34 | self.username = username 35 | self.displayableDate = displayableDate 36 | self.tweet = tweet 37 | } 38 | 39 | } 40 | 41 | extension TweetModel { 42 | 43 | static func stubData() -> [TweetModel] { 44 | var tweets: [TweetModel] = [] 45 | 46 | let tweetPete = TweetModel( 47 | name: "Peter Steinberger", 48 | username: "steipete", 49 | displayableDate: "1h", 50 | tweet: "My enhance request to incorporate EasyPeasy into UIKit is ready: rdar://27192334" 51 | ) 52 | tweets.append(tweetPete) 53 | 54 | let tweetBen = TweetModel( 55 | name: "Ben Sandofsky", 56 | username: "sandofsky", 57 | displayableDate: "2h", 58 | tweet: "In 2016, it's nuts to not be using Auto-Layout... in July 2016, it's nuts not" + 59 | " to be using EasyPeasy" 60 | ) 61 | tweets.append(tweetBen) 62 | 63 | let tweetChris = TweetModel( 64 | name: "Chris Lattner", 65 | username: "clattner_llvm", 66 | displayableDate: "4h", 67 | tweet: "Wouldn't mind sherlocking this EasyPeasy thing 😄" 68 | ) 69 | tweets.append(tweetChris) 70 | 71 | let tweetOrta = TweetModel( 72 | name: "Orta Therox", 73 | username: "orta", 74 | displayableDate: "4h", 75 | tweet: "EasyPeasy was nice, aye, but now is rockin' it on OS X too" 76 | ) 77 | tweets.append(tweetOrta) 78 | 79 | let tweetNatasha = TweetModel( 80 | name: "NatashaTheRobot", 81 | username: "NatashaTheRobot", 82 | displayableDate: "5h", 83 | tweet: "The talk \"Mastering Auto Layout with EasyPeasy\" at @tryswiftnyc is now live!" 84 | ) 85 | tweets.append(tweetNatasha) 86 | 87 | let tweetAsh = TweetModel( 88 | name: "Ash Furrow", 89 | username: "ashfurrow", 90 | displayableDate: "6h", 91 | tweet: "Cool Auto Layout framework, the creator is not available in button format though... 🙃" 92 | ) 93 | tweets.append(tweetAsh) 94 | 95 | let tweetAndy = TweetModel( 96 | name: "Andy Matuschak", 97 | username: "andy_matuschak", 98 | displayableDate: "7h", 99 | tweet: "EasyPeasy? hummm... fancy abstraction you should look at" 100 | ) 101 | tweets.append(tweetAndy) 102 | 103 | return tweets 104 | } 105 | 106 | } 107 | -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOSTests/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 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /Example/Demo macOS/Demo macOSTests/Tests macOS-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | 5 | -------------------------------------------------------------------------------- /Example/EasyPeasy.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/EasyPeasy.xcodeproj/xcshareddata/xcschemes/EasyPeasy-Example-iOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 46 | 47 | 49 | 55 | 56 | 57 | 58 | 59 | 65 | 66 | 67 | 68 | 69 | 70 | 81 | 83 | 89 | 90 | 91 | 92 | 93 | 94 | 100 | 102 | 108 | 109 | 110 | 111 | 113 | 114 | 117 | 118 | 119 | -------------------------------------------------------------------------------- /Example/EasyPeasy.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Example/EasyPeasy.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/EasyPeasy/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) - Copyright (c) 2016 Carlos Vidal 2 | // 3 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 4 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 5 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 6 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 7 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 8 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 9 | // SOFTWARE. 10 | 11 | import UIKit 12 | 13 | @UIApplicationMain 14 | class AppDelegate: UIResponder, UIApplicationDelegate { 15 | 16 | var window: UIWindow? 17 | 18 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 19 | return true 20 | } 21 | 22 | } 23 | 24 | -------------------------------------------------------------------------------- /Example/EasyPeasy/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /Example/EasyPeasy/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 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /Example/EasyPeasy/FeedController.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) - Copyright (c) 2016 Carlos Vidal 2 | // 3 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 4 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 5 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 6 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 7 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 8 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 9 | // SOFTWARE. 10 | 11 | import UIKit 12 | import EasyPeasy 13 | 14 | // NOTE: 15 | // I know this controller could be easily achievable with a regular 16 | // UITableViewController but this way is much easier to show the 17 | // potential of EasyPeasy 18 | 19 | class FeedController: UIViewController { 20 | 21 | fileprivate var tweets: [TweetModel] = [] 22 | fileprivate var tweetViews: [TweetView] = [] 23 | 24 | fileprivate lazy var scrollView: UIScrollView = { 25 | let scrollView = UIScrollView(frame: CGRect.zero) 26 | return scrollView 27 | }() 28 | 29 | fileprivate lazy var newTweetsView: UIImageView = { 30 | let imageView = UIImageView(image: UIImage.easy_newTweets()) 31 | return imageView 32 | }() 33 | 34 | override func viewDidLoad() { 35 | super.viewDidLoad() 36 | 37 | self.setup() 38 | self.populateFeed() 39 | } 40 | 41 | override func viewDidAppear(_ animated: Bool) { 42 | super.viewDidAppear(animated) 43 | 44 | // An example of UIView animation 45 | self.showNewTweetsIndicator(true) 46 | } 47 | 48 | // MARK: Private 49 | 50 | fileprivate func setup() { 51 | // Set stub data 52 | self.tweets = TweetModel.stubData() 53 | 54 | // Background color 55 | self.view.backgroundColor = UIColor(red: 0.937, green: 0.937, blue: 0.937, alpha: 1.0) 56 | 57 | // Set title view 58 | let logoImageView = UIImageView(image: UIImage.easy_twitterLogo()) 59 | self.navigationItem.titleView = logoImageView 60 | 61 | // Scrollview 62 | self.view.addSubview(self.scrollView) 63 | self.scrollView.easy.layout( 64 | Edges() 65 | ) 66 | 67 | // New tweets indicator 68 | self.view.addSubview(self.newTweetsView) 69 | self.newTweetsView.easy.layout( 70 | Size(CGSize(width: 118.0, height: 30.0)), 71 | Top(-100), 72 | CenterX() 73 | ) 74 | } 75 | 76 | fileprivate func populateFeed() { 77 | // It creates the constraints for each entry 78 | for (index, tweet) in self.tweets.enumerated() { 79 | let view = TweetView(frame: CGRect.zero) 80 | view.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 1000), for: .vertical) 81 | view.setContentHuggingPriority(UILayoutPriority(rawValue: 600), for: .vertical) 82 | self.scrollView.addSubview(view) 83 | view.easy.layout( 84 | Width(<=420), 85 | Height(>=78), 86 | CenterX(), 87 | Left().with(.medium), 88 | Right().with(.medium), 89 | // Pins to top only when we place the first row 90 | Top().when { index == 0 }, 91 | // Pins to bottom of the preivous item for the other cases 92 | Top(1).to(self.tweetViews.last ?? self.scrollView).when { index > 0 } 93 | ) 94 | 95 | view.configureWithModel(tweet) 96 | self.tweetViews.append(view) 97 | } 98 | 99 | // Establishes constraint with the bottom of the scroll view to adjust 100 | // the content size 101 | self.tweetViews.last!.easy.layout( 102 | Bottom().to(self.scrollView, .bottom) 103 | ) 104 | } 105 | 106 | fileprivate func showNewTweetsIndicator(_ show: Bool) { 107 | UIView.animate(withDuration: 0.3, delay: 2.0, options: UIView.AnimationOptions(), animations: { 108 | self.newTweetsView.easy.layout(Top(10).when { show }) 109 | self.newTweetsView.easy.layout(Top(-100).when { !show }) 110 | self.view.layoutIfNeeded() 111 | }, completion: { complete in 112 | if show { 113 | self.showNewTweetsIndicator(false) 114 | } 115 | }) 116 | } 117 | 118 | } 119 | -------------------------------------------------------------------------------- /Example/EasyPeasy/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "29x29", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-Small@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "29x29", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-Small@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "40x40", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-40@2x.png", 19 | "scale" : "2x" 20 | }, 21 | { 22 | "size" : "40x40", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-40@3x.png", 25 | "scale" : "3x" 26 | }, 27 | { 28 | "size" : "60x60", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-60@2x.png", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "size" : "60x60", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-60@3x.png", 37 | "scale" : "3x" 38 | }, 39 | { 40 | "size" : "29x29", 41 | "idiom" : "ipad", 42 | "filename" : "Icon-Small.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "29x29", 47 | "idiom" : "ipad", 48 | "filename" : "Icon-Small@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "40x40", 53 | "idiom" : "ipad", 54 | "filename" : "Icon-40.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "40x40", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-40@2x.png", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "size" : "76x76", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-76.png", 67 | "scale" : "1x" 68 | }, 69 | { 70 | "size" : "76x76", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-76@2x.png", 73 | "scale" : "2x" 74 | }, 75 | { 76 | "size" : "83.5x83.5", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-83.5@2x.png", 79 | "scale" : "2x" 80 | } 81 | ], 82 | "info" : { 83 | "version" : 1, 84 | "author" : "xcode" 85 | } 86 | } -------------------------------------------------------------------------------- /Example/EasyPeasy/Images.xcassets/AppIcon.appiconset/Icon-40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/Example/EasyPeasy/Images.xcassets/AppIcon.appiconset/Icon-40.png -------------------------------------------------------------------------------- /Example/EasyPeasy/Images.xcassets/AppIcon.appiconset/Icon-40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/Example/EasyPeasy/Images.xcassets/AppIcon.appiconset/Icon-40@2x.png -------------------------------------------------------------------------------- /Example/EasyPeasy/Images.xcassets/AppIcon.appiconset/Icon-40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/Example/EasyPeasy/Images.xcassets/AppIcon.appiconset/Icon-40@3x.png -------------------------------------------------------------------------------- /Example/EasyPeasy/Images.xcassets/AppIcon.appiconset/Icon-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/Example/EasyPeasy/Images.xcassets/AppIcon.appiconset/Icon-60@2x.png -------------------------------------------------------------------------------- /Example/EasyPeasy/Images.xcassets/AppIcon.appiconset/Icon-60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/Example/EasyPeasy/Images.xcassets/AppIcon.appiconset/Icon-60@3x.png -------------------------------------------------------------------------------- /Example/EasyPeasy/Images.xcassets/AppIcon.appiconset/Icon-76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/Example/EasyPeasy/Images.xcassets/AppIcon.appiconset/Icon-76.png -------------------------------------------------------------------------------- /Example/EasyPeasy/Images.xcassets/AppIcon.appiconset/Icon-76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/Example/EasyPeasy/Images.xcassets/AppIcon.appiconset/Icon-76@2x.png -------------------------------------------------------------------------------- /Example/EasyPeasy/Images.xcassets/AppIcon.appiconset/Icon-83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/Example/EasyPeasy/Images.xcassets/AppIcon.appiconset/Icon-83.5@2x.png -------------------------------------------------------------------------------- /Example/EasyPeasy/Images.xcassets/AppIcon.appiconset/Icon-Small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/Example/EasyPeasy/Images.xcassets/AppIcon.appiconset/Icon-Small.png -------------------------------------------------------------------------------- /Example/EasyPeasy/Images.xcassets/AppIcon.appiconset/Icon-Small@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/Example/EasyPeasy/Images.xcassets/AppIcon.appiconset/Icon-Small@2x.png -------------------------------------------------------------------------------- /Example/EasyPeasy/Images.xcassets/AppIcon.appiconset/Icon-Small@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/Example/EasyPeasy/Images.xcassets/AppIcon.appiconset/Icon-Small@3x.png -------------------------------------------------------------------------------- /Example/EasyPeasy/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Example/EasyPeasy/Images.xcassets/easypeasy-logo.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x" 10 | }, 11 | { 12 | "idiom" : "universal", 13 | "filename" : "easypeasy_logo@3x.png", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Example/EasyPeasy/Images.xcassets/easypeasy-logo.imageset/easypeasy_logo@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/Example/EasyPeasy/Images.xcassets/easypeasy-logo.imageset/easypeasy_logo@3x.png -------------------------------------------------------------------------------- /Example/EasyPeasy/Images.xcassets/icon-new-tweet.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x" 10 | }, 11 | { 12 | "idiom" : "universal", 13 | "filename" : "icon_new_tweet@3x.png", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "template" 23 | } 24 | } -------------------------------------------------------------------------------- /Example/EasyPeasy/Images.xcassets/icon-new-tweet.imageset/icon_new_tweet@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/Example/EasyPeasy/Images.xcassets/icon-new-tweet.imageset/icon_new_tweet@3x.png -------------------------------------------------------------------------------- /Example/EasyPeasy/Images.xcassets/icon-profile.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x" 10 | }, 11 | { 12 | "idiom" : "universal", 13 | "filename" : "icon_profile@3x.png", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "template" 23 | } 24 | } -------------------------------------------------------------------------------- /Example/EasyPeasy/Images.xcassets/icon-profile.imageset/icon_profile@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/Example/EasyPeasy/Images.xcassets/icon-profile.imageset/icon_profile@3x.png -------------------------------------------------------------------------------- /Example/EasyPeasy/Images.xcassets/icon-search.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x" 10 | }, 11 | { 12 | "idiom" : "universal", 13 | "filename" : "icon_search@3x.png", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "template" 23 | } 24 | } -------------------------------------------------------------------------------- /Example/EasyPeasy/Images.xcassets/icon-search.imageset/icon_search@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/Example/EasyPeasy/Images.xcassets/icon-search.imageset/icon_search@3x.png -------------------------------------------------------------------------------- /Example/EasyPeasy/Images.xcassets/new-tweets.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x" 10 | }, 11 | { 12 | "idiom" : "universal", 13 | "filename" : "new_tweets@3x.png", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Example/EasyPeasy/Images.xcassets/new-tweets.imageset/new_tweets@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/Example/EasyPeasy/Images.xcassets/new-tweets.imageset/new_tweets@3x.png -------------------------------------------------------------------------------- /Example/EasyPeasy/Images.xcassets/thumb-eloy.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "thumb-eloy.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Example/EasyPeasy/Images.xcassets/thumb-eloy.imageset/thumb-eloy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/Example/EasyPeasy/Images.xcassets/thumb-eloy.imageset/thumb-eloy.png -------------------------------------------------------------------------------- /Example/EasyPeasy/Images.xcassets/thumb-felix.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "thumb_felix.jpeg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Example/EasyPeasy/Images.xcassets/thumb-felix.imageset/thumb_felix.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/Example/EasyPeasy/Images.xcassets/thumb-felix.imageset/thumb_felix.jpeg -------------------------------------------------------------------------------- /Example/EasyPeasy/Images.xcassets/thumb-javi.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "thumb-javi.jpeg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Example/EasyPeasy/Images.xcassets/thumb-javi.imageset/thumb-javi.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/Example/EasyPeasy/Images.xcassets/thumb-javi.imageset/thumb-javi.jpeg -------------------------------------------------------------------------------- /Example/EasyPeasy/Images.xcassets/thumb-nacho.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "thumb-nacho.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Example/EasyPeasy/Images.xcassets/thumb-nacho.imageset/thumb-nacho.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/Example/EasyPeasy/Images.xcassets/thumb-nacho.imageset/thumb-nacho.jpg -------------------------------------------------------------------------------- /Example/EasyPeasy/Images.xcassets/twitter-logo.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x" 10 | }, 11 | { 12 | "idiom" : "universal", 13 | "filename" : "twitter_logo@3x.png", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Example/EasyPeasy/Images.xcassets/twitter-logo.imageset/twitter_logo@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/Example/EasyPeasy/Images.xcassets/twitter-logo.imageset/twitter_logo@3x.png -------------------------------------------------------------------------------- /Example/EasyPeasy/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 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /Example/EasyPeasy/String+Easy.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) - Copyright (c) 2016 Carlos Vidal 2 | // 3 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 4 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 5 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 6 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 7 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 8 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 9 | // SOFTWARE. 10 | 11 | import Foundation 12 | 13 | extension String { 14 | 15 | private static let regex = try! NSRegularExpression( 16 | pattern: "#\\w+", 17 | options: .caseInsensitive 18 | ) 19 | 20 | func easy_hashtagRanges() -> [NSRange] { 21 | let matches = String.regex.matches( 22 | in: self, 23 | options: .reportCompletion, 24 | range: NSMakeRange(0, self.count) 25 | ) 26 | 27 | return matches.map { $0.range } 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /Example/EasyPeasy/TweetModel.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) - Copyright (c) 2016 Carlos Vidal 2 | // 3 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 4 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 5 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 6 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 7 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 8 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 9 | // SOFTWARE. 10 | 11 | import UIKit 12 | 13 | struct TweetModel { 14 | 15 | let name: String 16 | let username: String 17 | let displayableDate: String 18 | let tweet: String 19 | let thumbnail: UIImage? 20 | 21 | init(name: String, username: String, displayableDate: String, tweet: String, thumbnail: UIImage?) { 22 | self.name = name 23 | self.username = username 24 | self.displayableDate = displayableDate 25 | self.tweet = tweet 26 | self.thumbnail = thumbnail 27 | } 28 | 29 | } 30 | 31 | extension TweetModel { 32 | 33 | static func stubData() -> [TweetModel] { 34 | let tweetFelix = TweetModel( 35 | name: "Felix Krause", 36 | username: "@KrauseFX", 37 | displayableDate: "30m", 38 | tweet: "With Fastlane nobody has to deal with xcodebuild anymore. Say goodbye to NSLayoutConstraints thanks to EasyPeasy 🚀", 39 | thumbnail: UIImage.easy_thumbFelix() 40 | ) 41 | let tweetEloy = TweetModel( 42 | name: "Eloy Durán", 43 | username: "@alloy", 44 | displayableDate: "1h", 45 | tweet: "EasyPeasy, best thing since CocoaPods socks were announced!", 46 | thumbnail: UIImage.easy_thumbEloy() 47 | ) 48 | let tweetJavi = TweetModel( 49 | name: "Javi.swift", 50 | username: "@Javi", 51 | displayableDate: "2h", 52 | tweet: "EasyPeasy? another autolayout library? Okay, I can give it a try!", 53 | thumbnail: UIImage.easy_thumbJavi() 54 | ) 55 | let tweetNacho = TweetModel( 56 | name: "NeoGazpatchOS", 57 | username: "@NeoNacho", 58 | displayableDate: "4h", 59 | tweet: "Just discovered EasyPeasy... silly name, great framework #yatusabes", 60 | thumbnail: UIImage.easy_thumbNacho() 61 | ) 62 | return [tweetFelix, tweetEloy, tweetJavi, tweetNacho] 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /Example/EasyPeasy/UIImage+Easy.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) - Copyright (c) 2016 Carlos Vidal 2 | // 3 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 4 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 5 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 6 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 7 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 8 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 9 | // SOFTWARE. 10 | 11 | import UIKit 12 | 13 | extension UIImage { 14 | 15 | static func easy_twitterLogo() -> UIImage { 16 | return UIImage(named: "twitter-logo")! 17 | } 18 | 19 | static func easy_thumbFelix() -> UIImage { 20 | return UIImage(named: "thumb-felix")! 21 | } 22 | 23 | static func easy_thumbEloy() -> UIImage { 24 | return UIImage(named: "thumb-eloy")! 25 | } 26 | 27 | static func easy_thumbJavi() -> UIImage { 28 | return UIImage(named: "thumb-javi")! 29 | } 30 | 31 | static func easy_thumbNacho() -> UIImage { 32 | return UIImage(named: "thumb-nacho")! 33 | } 34 | 35 | static func easy_newTweets() -> UIImage { 36 | return UIImage(named: "new-tweets")! 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /Example/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | use_frameworks! 3 | 4 | workspace 'EasyPeasy' 5 | 6 | # iOS 7 | 8 | target 'Demo' do 9 | project 'EasyPeasy.xcodeproj' 10 | pod 'EasyPeasy', :path => '../' 11 | end 12 | 13 | target 'Tests' do 14 | project 'EasyPeasy.xcodeproj' 15 | pod 'EasyPeasy', :path => '../' 16 | end 17 | 18 | # macOS 19 | 20 | target 'Demo macOS' do 21 | project 'Demo macOS/Demo macOS.xcodeproj' 22 | pod 'EasyPeasy', :path => '../' 23 | end 24 | 25 | target 'Tests macOS' do 26 | project 'Demo macOS/Demo macOS.xcodeproj' 27 | pod 'EasyPeasy', :path => '../' 28 | end 29 | -------------------------------------------------------------------------------- /Example/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - EasyPeasy (1.4.2) 3 | 4 | DEPENDENCIES: 5 | - EasyPeasy (from `../`) 6 | 7 | EXTERNAL SOURCES: 8 | EasyPeasy: 9 | :path: ../ 10 | 11 | SPEC CHECKSUMS: 12 | EasyPeasy: f7c02e00e722cda30454beb3496f40f4c0b1f8e8 13 | 14 | PODFILE CHECKSUM: af7a68a3145027932758a0afae88cb4387fa896f 15 | 16 | COCOAPODS: 1.3.1 17 | -------------------------------------------------------------------------------- /Example/Pods/Local Podspecs/EasyPeasy.podspec.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "EasyPeasy", 3 | "version": "1.4.2", 4 | "summary": "EasyPeasy is a Swift framework that eases the creation of\n Autolayout constraints programmatically", 5 | "description": "EasyPeasy is a Swift framework that lets you create Autolayout constraints\nprogrammatically without headaches and never ending boilerplate code. Besides the\nbasics, **EasyPeasy** resolves most of the constraint conflicts for you and lets\nyou attach to a constraint conditional closures that are evaluated before applying\na constraint, this lets you apply (or not) a constraint depending on platform, size\nclasses, orientation... or the state of your controller, easy peasy!", 6 | "homepage": "https://github.com/nakiostudio/EasyPeasy", 7 | "license": "MIT", 8 | "authors": { 9 | "Carlos Vidal": "nakioparkour@gmail.com" 10 | }, 11 | "source": { 12 | "git": "https://github.com/nakiostudio/EasyPeasy.git", 13 | "tag": "1.4.2" 14 | }, 15 | "social_media_url": "https://twitter.com/carlostify", 16 | "platforms": { 17 | "ios": "8.0", 18 | "tvos": "9.0", 19 | "osx": "10.10" 20 | }, 21 | "requires_arc": true, 22 | "source_files": "EasyPeasy/**/*" 23 | } 24 | -------------------------------------------------------------------------------- /Example/Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - EasyPeasy (1.4.2) 3 | 4 | DEPENDENCIES: 5 | - EasyPeasy (from `../`) 6 | 7 | EXTERNAL SOURCES: 8 | EasyPeasy: 9 | :path: ../ 10 | 11 | SPEC CHECKSUMS: 12 | EasyPeasy: f7c02e00e722cda30454beb3496f40f4c0b1f8e8 13 | 14 | PODFILE CHECKSUM: af7a68a3145027932758a0afae88cb4387fa896f 15 | 16 | COCOAPODS: 1.3.1 17 | -------------------------------------------------------------------------------- /Example/Pods/Pods.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/Pods/Pods.xcodeproj/xcshareddata/xcschemes/EasyPeasy-iOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 38 | 39 | 40 | 41 | 43 | 49 | 50 | 53 | 54 | 55 | 56 | 57 | 67 | 68 | 74 | 75 | 76 | 77 | 83 | 84 | 90 | 91 | 92 | 93 | 95 | 96 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /Example/Pods/Pods.xcodeproj/xcshareddata/xcschemes/EasyPeasy-macOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 50 | 51 | 57 | 58 | 59 | 60 | 62 | 63 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/EasyPeasy-iOS/EasyPeasy-iOS-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_EasyPeasy_iOS : NSObject 3 | @end 4 | @implementation PodsDummy_EasyPeasy_iOS 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/EasyPeasy-iOS/EasyPeasy-iOS-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/EasyPeasy-iOS/EasyPeasy-iOS-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double EasyPeasyVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char EasyPeasyVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/EasyPeasy-iOS/EasyPeasy-iOS.modulemap: -------------------------------------------------------------------------------- 1 | framework module EasyPeasy { 2 | umbrella header "EasyPeasy-iOS-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/EasyPeasy-iOS/EasyPeasy-iOS.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = $PODS_CONFIGURATION_BUILD_DIR/EasyPeasy-iOS 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public" 4 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 5 | PODS_BUILD_DIR = $BUILD_DIR 6 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_ROOT = ${SRCROOT} 8 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../.. 9 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 10 | SKIP_INSTALL = YES 11 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/EasyPeasy-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 | FMWK 17 | CFBundleShortVersionString 18 | 1.8.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/EasyPeasy-macOS/EasyPeasy-macOS-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_EasyPeasy_macOS : NSObject 3 | @end 4 | @implementation PodsDummy_EasyPeasy_macOS 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/EasyPeasy-macOS/EasyPeasy-macOS-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/EasyPeasy-macOS/EasyPeasy-macOS-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double EasyPeasyVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char EasyPeasyVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/EasyPeasy-macOS/EasyPeasy-macOS.modulemap: -------------------------------------------------------------------------------- 1 | framework module EasyPeasy { 2 | umbrella header "EasyPeasy-macOS-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/EasyPeasy-macOS/EasyPeasy-macOS.xcconfig: -------------------------------------------------------------------------------- 1 | CODE_SIGN_IDENTITY = 2 | CONFIGURATION_BUILD_DIR = $PODS_CONFIGURATION_BUILD_DIR/EasyPeasy-macOS 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public" 5 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 6 | PODS_BUILD_DIR = $BUILD_DIR 7 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 8 | PODS_ROOT = ${SRCROOT} 9 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../.. 10 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 11 | SKIP_INSTALL = YES 12 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/EasyPeasy-macOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.8.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Demo macOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Demo macOS/Pods-Demo macOS-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## EasyPeasy 5 | 6 | Copyright (c) 2016 Carlos Vidal 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in 16 | all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | THE SOFTWARE. 25 | 26 | Generated by CocoaPods - https://cocoapods.org 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Demo macOS/Pods-Demo macOS-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | Copyright (c) 2016 Carlos Vidal <nakioparkour@gmail.com> 18 | 19 | Permission is hereby granted, free of charge, to any person obtaining a copy 20 | of this software and associated documentation files (the "Software"), to deal 21 | in the Software without restriction, including without limitation the rights 22 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 23 | copies of the Software, and to permit persons to whom the Software is 24 | furnished to do so, subject to the following conditions: 25 | 26 | The above copyright notice and this permission notice shall be included in 27 | all copies or substantial portions of the Software. 28 | 29 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 30 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 31 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 32 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 33 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 34 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 35 | THE SOFTWARE. 36 | 37 | License 38 | MIT 39 | Title 40 | EasyPeasy 41 | Type 42 | PSGroupSpecifier 43 | 44 | 45 | FooterText 46 | Generated by CocoaPods - https://cocoapods.org 47 | Title 48 | 49 | Type 50 | PSGroupSpecifier 51 | 52 | 53 | StringsTable 54 | Acknowledgements 55 | Title 56 | Acknowledgements 57 | 58 | 59 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Demo macOS/Pods-Demo macOS-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_Demo_macOS : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_Demo_macOS 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Demo macOS/Pods-Demo macOS-frameworks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 5 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 6 | 7 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" 8 | 9 | # This protects against multiple targets copying the same framework dependency at the same time. The solution 10 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html 11 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") 12 | 13 | install_framework() 14 | { 15 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then 16 | local source="${BUILT_PRODUCTS_DIR}/$1" 17 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then 18 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" 19 | elif [ -r "$1" ]; then 20 | local source="$1" 21 | fi 22 | 23 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 24 | 25 | if [ -L "${source}" ]; then 26 | echo "Symlinked..." 27 | source="$(readlink "${source}")" 28 | fi 29 | 30 | # Use filter instead of exclude so missing patterns don't throw errors. 31 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" 32 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" 33 | 34 | local basename 35 | basename="$(basename -s .framework "$1")" 36 | binary="${destination}/${basename}.framework/${basename}" 37 | if ! [ -r "$binary" ]; then 38 | binary="${destination}/${basename}" 39 | fi 40 | 41 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 42 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then 43 | strip_invalid_archs "$binary" 44 | fi 45 | 46 | # Resign the code if required by the build settings to avoid unstable apps 47 | code_sign_if_enabled "${destination}/$(basename "$1")" 48 | 49 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. 50 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then 51 | local swift_runtime_libs 52 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) 53 | for lib in $swift_runtime_libs; do 54 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" 55 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" 56 | code_sign_if_enabled "${destination}/${lib}" 57 | done 58 | fi 59 | } 60 | 61 | # Copies the dSYM of a vendored framework 62 | install_dsym() { 63 | local source="$1" 64 | if [ -r "$source" ]; then 65 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DWARF_DSYM_FOLDER_PATH}\"" 66 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DWARF_DSYM_FOLDER_PATH}" 67 | fi 68 | } 69 | 70 | # Signs a framework with the provided identity 71 | code_sign_if_enabled() { 72 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then 73 | # Use the current code_sign_identitiy 74 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" 75 | local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements '$1'" 76 | 77 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 78 | code_sign_cmd="$code_sign_cmd &" 79 | fi 80 | echo "$code_sign_cmd" 81 | eval "$code_sign_cmd" 82 | fi 83 | } 84 | 85 | # Strip invalid architectures 86 | strip_invalid_archs() { 87 | binary="$1" 88 | # Get architectures for current file 89 | archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)" 90 | stripped="" 91 | for arch in $archs; do 92 | if ! [[ "${ARCHS}" == *"$arch"* ]]; then 93 | # Strip non-valid architectures in-place 94 | lipo -remove "$arch" -output "$binary" "$binary" || exit 1 95 | stripped="$stripped $arch" 96 | fi 97 | done 98 | if [[ "$stripped" ]]; then 99 | echo "Stripped $binary of architectures:$stripped" 100 | fi 101 | } 102 | 103 | 104 | if [[ "$CONFIGURATION" == "Debug" ]]; then 105 | install_framework "${BUILT_PRODUCTS_DIR}/EasyPeasy-macOS/EasyPeasy.framework" 106 | fi 107 | if [[ "$CONFIGURATION" == "Release" ]]; then 108 | install_framework "${BUILT_PRODUCTS_DIR}/EasyPeasy-macOS/EasyPeasy.framework" 109 | fi 110 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 111 | wait 112 | fi 113 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Demo macOS/Pods-Demo macOS-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_Demo_macOSVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_Demo_macOSVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Demo macOS/Pods-Demo macOS.debug.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | CODE_SIGN_IDENTITY = 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/EasyPeasy-macOS" 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/../Frameworks' '@loader_path/Frameworks' 6 | OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/EasyPeasy-macOS/EasyPeasy.framework/Headers" 7 | OTHER_LDFLAGS = $(inherited) -framework "EasyPeasy" 8 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 9 | PODS_BUILD_DIR = $BUILD_DIR 10 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 11 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.. 12 | PODS_ROOT = ${SRCROOT}/../Pods 13 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Demo macOS/Pods-Demo macOS.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_Demo_macOS { 2 | umbrella header "Pods-Demo macOS-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Demo macOS/Pods-Demo macOS.release.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | CODE_SIGN_IDENTITY = 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/EasyPeasy-macOS" 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/../Frameworks' '@loader_path/Frameworks' 6 | OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/EasyPeasy-macOS/EasyPeasy.framework/Headers" 7 | OTHER_LDFLAGS = $(inherited) -framework "EasyPeasy" 8 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 9 | PODS_BUILD_DIR = $BUILD_DIR 10 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 11 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.. 12 | PODS_ROOT = ${SRCROOT}/../Pods 13 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Demo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Demo/Pods-Demo-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## EasyPeasy 5 | 6 | Copyright (c) 2016 Carlos Vidal 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in 16 | all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | THE SOFTWARE. 25 | 26 | Generated by CocoaPods - https://cocoapods.org 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Demo/Pods-Demo-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | Copyright (c) 2016 Carlos Vidal <nakioparkour@gmail.com> 18 | 19 | Permission is hereby granted, free of charge, to any person obtaining a copy 20 | of this software and associated documentation files (the "Software"), to deal 21 | in the Software without restriction, including without limitation the rights 22 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 23 | copies of the Software, and to permit persons to whom the Software is 24 | furnished to do so, subject to the following conditions: 25 | 26 | The above copyright notice and this permission notice shall be included in 27 | all copies or substantial portions of the Software. 28 | 29 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 30 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 31 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 32 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 33 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 34 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 35 | THE SOFTWARE. 36 | 37 | License 38 | MIT 39 | Title 40 | EasyPeasy 41 | Type 42 | PSGroupSpecifier 43 | 44 | 45 | FooterText 46 | Generated by CocoaPods - https://cocoapods.org 47 | Title 48 | 49 | Type 50 | PSGroupSpecifier 51 | 52 | 53 | StringsTable 54 | Acknowledgements 55 | Title 56 | Acknowledgements 57 | 58 | 59 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Demo/Pods-Demo-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_Demo : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_Demo 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Demo/Pods-Demo-frameworks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 5 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 6 | 7 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" 8 | 9 | # This protects against multiple targets copying the same framework dependency at the same time. The solution 10 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html 11 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") 12 | 13 | install_framework() 14 | { 15 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then 16 | local source="${BUILT_PRODUCTS_DIR}/$1" 17 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then 18 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" 19 | elif [ -r "$1" ]; then 20 | local source="$1" 21 | fi 22 | 23 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 24 | 25 | if [ -L "${source}" ]; then 26 | echo "Symlinked..." 27 | source="$(readlink "${source}")" 28 | fi 29 | 30 | # Use filter instead of exclude so missing patterns don't throw errors. 31 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" 32 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" 33 | 34 | local basename 35 | basename="$(basename -s .framework "$1")" 36 | binary="${destination}/${basename}.framework/${basename}" 37 | if ! [ -r "$binary" ]; then 38 | binary="${destination}/${basename}" 39 | fi 40 | 41 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 42 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then 43 | strip_invalid_archs "$binary" 44 | fi 45 | 46 | # Resign the code if required by the build settings to avoid unstable apps 47 | code_sign_if_enabled "${destination}/$(basename "$1")" 48 | 49 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. 50 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then 51 | local swift_runtime_libs 52 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) 53 | for lib in $swift_runtime_libs; do 54 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" 55 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" 56 | code_sign_if_enabled "${destination}/${lib}" 57 | done 58 | fi 59 | } 60 | 61 | # Copies the dSYM of a vendored framework 62 | install_dsym() { 63 | local source="$1" 64 | if [ -r "$source" ]; then 65 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DWARF_DSYM_FOLDER_PATH}\"" 66 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DWARF_DSYM_FOLDER_PATH}" 67 | fi 68 | } 69 | 70 | # Signs a framework with the provided identity 71 | code_sign_if_enabled() { 72 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then 73 | # Use the current code_sign_identitiy 74 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" 75 | local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements '$1'" 76 | 77 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 78 | code_sign_cmd="$code_sign_cmd &" 79 | fi 80 | echo "$code_sign_cmd" 81 | eval "$code_sign_cmd" 82 | fi 83 | } 84 | 85 | # Strip invalid architectures 86 | strip_invalid_archs() { 87 | binary="$1" 88 | # Get architectures for current file 89 | archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)" 90 | stripped="" 91 | for arch in $archs; do 92 | if ! [[ "${ARCHS}" == *"$arch"* ]]; then 93 | # Strip non-valid architectures in-place 94 | lipo -remove "$arch" -output "$binary" "$binary" || exit 1 95 | stripped="$stripped $arch" 96 | fi 97 | done 98 | if [[ "$stripped" ]]; then 99 | echo "Stripped $binary of architectures:$stripped" 100 | fi 101 | } 102 | 103 | 104 | if [[ "$CONFIGURATION" == "Debug" ]]; then 105 | install_framework "${BUILT_PRODUCTS_DIR}/EasyPeasy-iOS/EasyPeasy.framework" 106 | fi 107 | if [[ "$CONFIGURATION" == "Release" ]]; then 108 | install_framework "${BUILT_PRODUCTS_DIR}/EasyPeasy-iOS/EasyPeasy.framework" 109 | fi 110 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 111 | wait 112 | fi 113 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Demo/Pods-Demo-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_DemoVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_DemoVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Demo/Pods-Demo.debug.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/EasyPeasy-iOS" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 5 | OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/EasyPeasy-iOS/EasyPeasy.framework/Headers" 6 | OTHER_LDFLAGS = $(inherited) -framework "EasyPeasy" 7 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 8 | PODS_BUILD_DIR = $BUILD_DIR 9 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 11 | PODS_ROOT = ${SRCROOT}/Pods 12 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Demo/Pods-Demo.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_Demo { 2 | umbrella header "Pods-Demo-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Demo/Pods-Demo.release.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/EasyPeasy-iOS" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 5 | OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/EasyPeasy-iOS/EasyPeasy.framework/Headers" 6 | OTHER_LDFLAGS = $(inherited) -framework "EasyPeasy" 7 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 8 | PODS_BUILD_DIR = $BUILD_DIR 9 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 11 | PODS_ROOT = ${SRCROOT}/Pods 12 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Tests macOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Tests macOS/Pods-Tests macOS-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## EasyPeasy 5 | 6 | Copyright (c) 2016 Carlos Vidal 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in 16 | all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | THE SOFTWARE. 25 | 26 | Generated by CocoaPods - https://cocoapods.org 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Tests macOS/Pods-Tests macOS-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | Copyright (c) 2016 Carlos Vidal <nakioparkour@gmail.com> 18 | 19 | Permission is hereby granted, free of charge, to any person obtaining a copy 20 | of this software and associated documentation files (the "Software"), to deal 21 | in the Software without restriction, including without limitation the rights 22 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 23 | copies of the Software, and to permit persons to whom the Software is 24 | furnished to do so, subject to the following conditions: 25 | 26 | The above copyright notice and this permission notice shall be included in 27 | all copies or substantial portions of the Software. 28 | 29 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 30 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 31 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 32 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 33 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 34 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 35 | THE SOFTWARE. 36 | 37 | License 38 | MIT 39 | Title 40 | EasyPeasy 41 | Type 42 | PSGroupSpecifier 43 | 44 | 45 | FooterText 46 | Generated by CocoaPods - https://cocoapods.org 47 | Title 48 | 49 | Type 50 | PSGroupSpecifier 51 | 52 | 53 | StringsTable 54 | Acknowledgements 55 | Title 56 | Acknowledgements 57 | 58 | 59 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Tests macOS/Pods-Tests macOS-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_Tests_macOS : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_Tests_macOS 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Tests macOS/Pods-Tests macOS-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_Tests_macOSVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_Tests_macOSVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Tests macOS/Pods-Tests macOS.debug.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | CODE_SIGN_IDENTITY = 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/EasyPeasy-macOS" 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/../Frameworks' '@loader_path/../Frameworks' 6 | OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/EasyPeasy-macOS/EasyPeasy.framework/Headers" 7 | OTHER_LDFLAGS = $(inherited) -framework "EasyPeasy" 8 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 9 | PODS_BUILD_DIR = $BUILD_DIR 10 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 11 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.. 12 | PODS_ROOT = ${SRCROOT}/../Pods 13 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Tests macOS/Pods-Tests macOS.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_Tests_macOS { 2 | umbrella header "Pods-Tests macOS-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Tests macOS/Pods-Tests macOS.release.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | CODE_SIGN_IDENTITY = 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/EasyPeasy-macOS" 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/../Frameworks' '@loader_path/../Frameworks' 6 | OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/EasyPeasy-macOS/EasyPeasy.framework/Headers" 7 | OTHER_LDFLAGS = $(inherited) -framework "EasyPeasy" 8 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 9 | PODS_BUILD_DIR = $BUILD_DIR 10 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 11 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.. 12 | PODS_ROOT = ${SRCROOT}/../Pods 13 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Tests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Tests/Pods-Tests-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## EasyPeasy 5 | 6 | Copyright (c) 2016 Carlos Vidal 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in 16 | all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | THE SOFTWARE. 25 | 26 | Generated by CocoaPods - https://cocoapods.org 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Tests/Pods-Tests-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | Copyright (c) 2016 Carlos Vidal <nakioparkour@gmail.com> 18 | 19 | Permission is hereby granted, free of charge, to any person obtaining a copy 20 | of this software and associated documentation files (the "Software"), to deal 21 | in the Software without restriction, including without limitation the rights 22 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 23 | copies of the Software, and to permit persons to whom the Software is 24 | furnished to do so, subject to the following conditions: 25 | 26 | The above copyright notice and this permission notice shall be included in 27 | all copies or substantial portions of the Software. 28 | 29 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 30 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 31 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 32 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 33 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 34 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 35 | THE SOFTWARE. 36 | 37 | License 38 | MIT 39 | Title 40 | EasyPeasy 41 | Type 42 | PSGroupSpecifier 43 | 44 | 45 | FooterText 46 | Generated by CocoaPods - https://cocoapods.org 47 | Title 48 | 49 | Type 50 | PSGroupSpecifier 51 | 52 | 53 | StringsTable 54 | Acknowledgements 55 | Title 56 | Acknowledgements 57 | 58 | 59 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Tests/Pods-Tests-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_Tests : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_Tests 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Tests/Pods-Tests-frameworks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 5 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 6 | 7 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" 8 | 9 | # This protects against multiple targets copying the same framework dependency at the same time. The solution 10 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html 11 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") 12 | 13 | install_framework() 14 | { 15 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then 16 | local source="${BUILT_PRODUCTS_DIR}/$1" 17 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then 18 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" 19 | elif [ -r "$1" ]; then 20 | local source="$1" 21 | fi 22 | 23 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 24 | 25 | if [ -L "${source}" ]; then 26 | echo "Symlinked..." 27 | source="$(readlink "${source}")" 28 | fi 29 | 30 | # Use filter instead of exclude so missing patterns don't throw errors. 31 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" 32 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" 33 | 34 | local basename 35 | basename="$(basename -s .framework "$1")" 36 | binary="${destination}/${basename}.framework/${basename}" 37 | if ! [ -r "$binary" ]; then 38 | binary="${destination}/${basename}" 39 | fi 40 | 41 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 42 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then 43 | strip_invalid_archs "$binary" 44 | fi 45 | 46 | # Resign the code if required by the build settings to avoid unstable apps 47 | code_sign_if_enabled "${destination}/$(basename "$1")" 48 | 49 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. 50 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then 51 | local swift_runtime_libs 52 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) 53 | for lib in $swift_runtime_libs; do 54 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" 55 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" 56 | code_sign_if_enabled "${destination}/${lib}" 57 | done 58 | fi 59 | } 60 | 61 | # Copies the dSYM of a vendored framework 62 | install_dsym() { 63 | local source="$1" 64 | if [ -r "$source" ]; then 65 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DWARF_DSYM_FOLDER_PATH}\"" 66 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DWARF_DSYM_FOLDER_PATH}" 67 | fi 68 | } 69 | 70 | # Signs a framework with the provided identity 71 | code_sign_if_enabled() { 72 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then 73 | # Use the current code_sign_identitiy 74 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" 75 | local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements '$1'" 76 | 77 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 78 | code_sign_cmd="$code_sign_cmd &" 79 | fi 80 | echo "$code_sign_cmd" 81 | eval "$code_sign_cmd" 82 | fi 83 | } 84 | 85 | # Strip invalid architectures 86 | strip_invalid_archs() { 87 | binary="$1" 88 | # Get architectures for current file 89 | archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)" 90 | stripped="" 91 | for arch in $archs; do 92 | if ! [[ "${ARCHS}" == *"$arch"* ]]; then 93 | # Strip non-valid architectures in-place 94 | lipo -remove "$arch" -output "$binary" "$binary" || exit 1 95 | stripped="$stripped $arch" 96 | fi 97 | done 98 | if [[ "$stripped" ]]; then 99 | echo "Stripped $binary of architectures:$stripped" 100 | fi 101 | } 102 | 103 | 104 | if [[ "$CONFIGURATION" == "Debug" ]]; then 105 | install_framework "${BUILT_PRODUCTS_DIR}/EasyPeasy-iOS/EasyPeasy.framework" 106 | fi 107 | if [[ "$CONFIGURATION" == "Release" ]]; then 108 | install_framework "${BUILT_PRODUCTS_DIR}/EasyPeasy-iOS/EasyPeasy.framework" 109 | fi 110 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 111 | wait 112 | fi 113 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Tests/Pods-Tests-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_TestsVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_TestsVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Tests/Pods-Tests.debug.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/EasyPeasy-iOS" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 5 | OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/EasyPeasy-iOS/EasyPeasy.framework/Headers" 6 | OTHER_LDFLAGS = $(inherited) -framework "EasyPeasy" 7 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 8 | PODS_BUILD_DIR = $BUILD_DIR 9 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 11 | PODS_ROOT = ${SRCROOT}/Pods 12 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Tests/Pods-Tests.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_Tests { 2 | umbrella header "Pods-Tests-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Tests/Pods-Tests.release.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/EasyPeasy-iOS" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 5 | OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/EasyPeasy-iOS/EasyPeasy.framework/Headers" 6 | OTHER_LDFLAGS = $(inherited) -framework "EasyPeasy" 7 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 8 | PODS_BUILD_DIR = $BUILD_DIR 9 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 11 | PODS_ROOT = ${SRCROOT}/Pods 12 | -------------------------------------------------------------------------------- /Example/Tests/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 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /Example/Tests/Item+Tests.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) - Copyright (c) 2016 Carlos Vidal 2 | // 3 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 4 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 5 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 6 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 7 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 8 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 9 | // SOFTWARE. 10 | 11 | @testable import EasyPeasy 12 | 13 | extension Item { 14 | 15 | var test_attributes: [Attribute] { 16 | var attributes: [Attribute] = [] 17 | for node in self.nodes.values { 18 | attributes.append(contentsOf: node.inactiveAttributes) 19 | attributes.append(contentsOf: node.activeAttributes.easy_flatMap { $0 }) 20 | } 21 | return attributes 22 | } 23 | 24 | var test_activeAttributes: [Attribute] { 25 | var attributes: [Attribute] = [] 26 | for node in self.nodes.values { 27 | attributes.append(contentsOf: node.activeAttributes.easy_flatMap { $0 }) 28 | } 29 | return attributes 30 | } 31 | 32 | var test_inactiveAttributes: [Attribute] { 33 | var attributes: [Attribute] = [] 34 | for node in self.nodes.values { 35 | attributes.append(contentsOf: node.inactiveAttributes) 36 | } 37 | return attributes 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /Example/Tests/ItemTests.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) - Copyright (c) 2016 Carlos Vidal 2 | // 3 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 4 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 5 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 6 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 7 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 8 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 9 | // SOFTWARE. 10 | 11 | import XCTest 12 | @testable import EasyPeasy 13 | 14 | class ItemTests: XCTestCase { 15 | 16 | override func setUp() { 17 | super.setUp() 18 | } 19 | 20 | override func tearDown() { 21 | super.tearDown() 22 | } 23 | 24 | func testThatOwningViewReturnsViewSuperview() { 25 | // given 26 | let superview = UIView(frame: CGRect.zero) 27 | let viewA = UIView(frame: CGRect.zero) 28 | superview.addSubview(viewA) 29 | 30 | // when 31 | let owningView = viewA.owningView 32 | 33 | // then 34 | XCTAssertNotNil(owningView) 35 | XCTAssertTrue(owningView === superview) 36 | } 37 | 38 | @available (iOS 9.0, *) 39 | func testThatOwningViewReturnsLayoutGuideOwningView() { 40 | // given 41 | let view = UIView(frame: CGRect.zero) 42 | let layoutGuide = UILayoutGuide() 43 | view.addLayoutGuide(layoutGuide) 44 | 45 | // when 46 | let owningView = layoutGuide.owningView 47 | 48 | // then 49 | XCTAssertNotNil(owningView) 50 | XCTAssertTrue(owningView === view) 51 | } 52 | 53 | func testThatConstraintsArrayReturnsViewConstraints() { 54 | // given 55 | let superview = UIView(frame: CGRect.zero) 56 | let viewA = UIView(frame: CGRect.zero) 57 | superview.addSubview(viewA) 58 | 59 | // when 60 | let constraints = viewA.easy.layout(Size(100)) 61 | 62 | // then 63 | XCTAssertTrue(constraints.count > 0) 64 | XCTAssertTrue(constraints == viewA.constraints) 65 | } 66 | 67 | @available (iOS 9.0, *) 68 | func testThatConstraintsArrayReturnsLayoutGuideConstraints() { 69 | // given 70 | let view = UIView(frame: CGRect.zero) 71 | let layoutGuide = UILayoutGuide() 72 | view.addLayoutGuide(layoutGuide) 73 | 74 | // when 75 | let constraints = layoutGuide.easy.layout(Edges()) 76 | 77 | // then 78 | XCTAssertTrue(constraints.count > 0) 79 | XCTAssertTrue(constraints == layoutGuide.constraints) 80 | } 81 | 82 | @available (iOS 9.0, *) 83 | func testThatConstraintsArrayReturnsLayoutGuideConstraintsOwnedByGuide() { 84 | // given 85 | let view = UIView(frame: CGRect.zero) 86 | let layoutGuide = UILayoutGuide() 87 | view.addLayoutGuide(layoutGuide) 88 | 89 | // when 90 | let constraints = layoutGuide.easy.layout(Size(40)) 91 | 92 | // then 93 | XCTAssertTrue(constraints.count > 0) 94 | XCTAssertTrue(constraints == layoutGuide.constraints) 95 | } 96 | 97 | func testThatItemConformingClassThatIsNotViewOrLayoutGuideDoesNotHaveOwningView() { 98 | // given 99 | class TestClass: NSObject, Item { 100 | var constraints: [NSLayoutConstraint] { 101 | get { 102 | return self.owningView?.constraints.filter { $0.firstItem === self } ?? [] 103 | } 104 | } 105 | 106 | fileprivate var owningView: View? 107 | 108 | } 109 | let testClassInstance = TestClass() 110 | 111 | // when 112 | let owningView = testClassInstance.owningView 113 | 114 | // then 115 | XCTAssertNil(owningView) 116 | } 117 | 118 | } 119 | -------------------------------------------------------------------------------- /Example/Tests/PriorityTests.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) - Copyright (c) 2016 Carlos Vidal 2 | // 3 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 4 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 5 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 6 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 7 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 8 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 9 | // SOFTWARE. 10 | 11 | import XCTest 12 | @testable import EasyPeasy 13 | 14 | class PriorityTests: XCTestCase { 15 | 16 | override func setUp() { 17 | super.setUp() 18 | } 19 | 20 | override func tearDown() { 21 | super.tearDown() 22 | } 23 | 24 | func testThatThatOrderIsCorrect() { 25 | // given 26 | let required = Priority.required 27 | let high = Priority.high 28 | let medium = Priority.medium 29 | let low = Priority.low 30 | 31 | // when 32 | // then 33 | XCTAssertTrue(required.layoutPriority() > high.layoutPriority()) 34 | XCTAssertTrue(high.layoutPriority() > medium.layoutPriority()) 35 | XCTAssertTrue(medium.layoutPriority() > low.layoutPriority()) 36 | } 37 | 38 | func testThatCustomPriorityRetursTheValueGiven() { 39 | // given 40 | let myCustomValue: Float = 234.0 41 | 42 | // when 43 | let priority = Priority.custom(myCustomValue) 44 | 45 | // then 46 | XCTAssertTrue(priority.layoutPriority() == myCustomValue) 47 | } 48 | 49 | func testThatThatOrderIsCorrect_deprecatedCases() { 50 | // given 51 | let high = Priority.high 52 | let medium = Priority.medium 53 | let low = Priority.low 54 | 55 | // when 56 | // then 57 | XCTAssertTrue(high.layoutPriority() > medium.layoutPriority()) 58 | XCTAssertTrue(medium.layoutPriority() > low.layoutPriority()) 59 | } 60 | 61 | func testThatCustomPriorityRetursTheValueGiven_deprecatedCases() { 62 | // given 63 | let myCustomValue: Float = 234.0 64 | 65 | // when 66 | let priority = Priority.custom(myCustomValue) 67 | 68 | // then 69 | XCTAssertTrue(priority.layoutPriority() == myCustomValue) 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /Example/Tests/ReferenceAttributeTests.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) - Copyright (c) 2016 Carlos Vidal 2 | // 3 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 4 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 5 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 6 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 7 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 8 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 9 | // SOFTWARE. 10 | 11 | import XCTest 12 | @testable import EasyPeasy 13 | 14 | class ReferenceAttributeTests: XCTestCase { 15 | 16 | override func setUp() { 17 | super.setUp() 18 | } 19 | 20 | override func tearDown() { 21 | super.tearDown() 22 | } 23 | 24 | func testThatOppositeAttributesAreCorrect() { 25 | // given 26 | // when 27 | // then 28 | XCTAssertTrue(ReferenceAttribute.width.opposite == .width) 29 | XCTAssertTrue(ReferenceAttribute.height.opposite == .height) 30 | XCTAssertTrue(ReferenceAttribute.left.opposite == .right) 31 | XCTAssertTrue(ReferenceAttribute.right.opposite == .left) 32 | XCTAssertTrue(ReferenceAttribute.top.opposite == .bottom) 33 | XCTAssertTrue(ReferenceAttribute.bottom.opposite == .top) 34 | XCTAssertTrue(ReferenceAttribute.leading.opposite == .trailing) 35 | XCTAssertTrue(ReferenceAttribute.trailing.opposite == .leading) 36 | XCTAssertTrue(ReferenceAttribute.centerX.opposite == .centerX) 37 | XCTAssertTrue(ReferenceAttribute.centerY.opposite == .centerY) 38 | XCTAssertTrue(ReferenceAttribute.lastBaseline.opposite == .lastBaseline) 39 | 40 | } 41 | 42 | func testThatOppositeAttributesAreCorrectiOS8AndAbove() { 43 | XCTAssertTrue(ReferenceAttribute.firstBaseline.opposite == .firstBaseline) 44 | XCTAssertTrue(ReferenceAttribute.leftMargin.opposite == .rightMargin) 45 | XCTAssertTrue(ReferenceAttribute.rightMargin.opposite == .leftMargin) 46 | XCTAssertTrue(ReferenceAttribute.topMargin.opposite == .bottomMargin) 47 | XCTAssertTrue(ReferenceAttribute.bottomMargin.opposite == .topMargin) 48 | XCTAssertTrue(ReferenceAttribute.leadingMargin.opposite == .trailingMargin) 49 | XCTAssertTrue(ReferenceAttribute.trailingMargin.opposite == .leadingMargin) 50 | XCTAssertTrue(ReferenceAttribute.centerXWithinMargins.opposite == .centerXWithinMargins) 51 | XCTAssertTrue(ReferenceAttribute.centerYWithinMargins.opposite == .centerYWithinMargins) 52 | } 53 | 54 | func testThatAutoLayoutEquivalentIsTheExpected() { 55 | // given 56 | // when 57 | // then 58 | XCTAssertTrue(ReferenceAttribute.width.layoutAttribute == .width) 59 | XCTAssertTrue(ReferenceAttribute.height.layoutAttribute == .height) 60 | XCTAssertTrue(ReferenceAttribute.left.layoutAttribute == .left) 61 | XCTAssertTrue(ReferenceAttribute.right.layoutAttribute == .right) 62 | XCTAssertTrue(ReferenceAttribute.top.layoutAttribute == .top) 63 | XCTAssertTrue(ReferenceAttribute.bottom.layoutAttribute == .bottom) 64 | XCTAssertTrue(ReferenceAttribute.leading.layoutAttribute == .leading) 65 | XCTAssertTrue(ReferenceAttribute.trailing.layoutAttribute == .trailing) 66 | XCTAssertTrue(ReferenceAttribute.centerX.layoutAttribute == .centerX) 67 | XCTAssertTrue(ReferenceAttribute.centerY.layoutAttribute == .centerY) 68 | XCTAssertTrue(ReferenceAttribute.lastBaseline.layoutAttribute == .lastBaseline) 69 | XCTAssertTrue(ReferenceAttribute.width.layoutAttribute == .width) 70 | } 71 | 72 | func testThatAutoLayoutEquivalentIsTheExpectediOS8AndAbove() { 73 | // given 74 | // when 75 | // then 76 | XCTAssertTrue(ReferenceAttribute.firstBaseline.layoutAttribute == .firstBaseline) 77 | XCTAssertTrue(ReferenceAttribute.leftMargin.layoutAttribute == .leftMargin) 78 | XCTAssertTrue(ReferenceAttribute.rightMargin.layoutAttribute == .rightMargin) 79 | XCTAssertTrue(ReferenceAttribute.topMargin.layoutAttribute == .topMargin) 80 | XCTAssertTrue(ReferenceAttribute.bottomMargin.layoutAttribute == .bottomMargin) 81 | XCTAssertTrue(ReferenceAttribute.leadingMargin.layoutAttribute == .leadingMargin) 82 | XCTAssertTrue(ReferenceAttribute.trailingMargin.layoutAttribute == .trailingMargin) 83 | XCTAssertTrue(ReferenceAttribute.centerXWithinMargins.layoutAttribute == .centerXWithinMargins) 84 | XCTAssertTrue(ReferenceAttribute.centerYWithinMargins.layoutAttribute == .centerYWithinMargins) 85 | } 86 | 87 | } 88 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # Dependency manager 4 | gem 'cocoapods', '1.6.0.beta.2' 5 | 6 | # Coverage reports 7 | gem 'danger-xcov' 8 | 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 Carlos Vidal 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.1 2 | 3 | import PackageDescription 4 | 5 | let package = Package( 6 | name: "EasyPeasy", 7 | platforms: [ 8 | .iOS(.v8), 9 | .macOS(.v10_10), 10 | .tvOS(.v9) 11 | ], 12 | products: [ 13 | .library(name: "EasyPeasy", targets: ["EasyPeasy"]) 14 | ], 15 | dependencies: [], 16 | targets: [ 17 | .target( 18 | name: "EasyPeasy", 19 | dependencies: [], 20 | path: "EasyPeasy" 21 | ) 22 | ] 23 | ) 24 | -------------------------------------------------------------------------------- /README/demo_ios.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/README/demo_ios.gif -------------------------------------------------------------------------------- /README/demo_macos.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/README/demo_macos.gif -------------------------------------------------------------------------------- /README/first_touch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/README/first_touch.png -------------------------------------------------------------------------------- /README/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/README/logo.png -------------------------------------------------------------------------------- /README/monzo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/README/monzo.png -------------------------------------------------------------------------------- /README/playground.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakiostudio/EasyPeasy/b0028f63d47bcb32e37d8abb9cc5d5a781742a4e/README/playground.gif -------------------------------------------------------------------------------- /_Pods.xcodeproj: -------------------------------------------------------------------------------- 1 | Example/Pods/Pods.xcodeproj --------------------------------------------------------------------------------