├── .circleci ├── SWIFT_4.2.xcconfig ├── SWIFT_5.0.xcconfig └── config.yml ├── .gitignore ├── .swiftpm └── xcode │ └── package.xcworkspace │ └── contents.xcworkspacedata ├── Anchorage.podspec ├── Anchorage.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── xcshareddata │ └── xcschemes │ ├── Anchorage-iOS.xcscheme │ ├── Anchorage-macOS.xcscheme │ ├── Anchorage-tvOS.xcscheme │ ├── AnchorageDemo.xcscheme │ └── RunAllTests.xcscheme ├── AnchorageDemo ├── AppDelegate.swift ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Base.lproj │ └── LaunchScreen.storyboard ├── Cells │ ├── AnimatableConstraintCell.swift │ ├── BaseCell.swift │ ├── EdgeContainedLabelCell.swift │ ├── EqualSpaceViewCell.swift │ ├── MinimumWidthViewCell.swift │ └── ToggleActiveHeightCell.swift ├── Info.plist └── RootViewController.swift ├── AnchorageTests ├── AnchorageTests.swift └── Info.plist ├── Gemfile ├── Gemfile.lock ├── LICENSE ├── Package.swift ├── README.md ├── Source ├── AnchorGroupProvider.swift ├── Anchorage.swift ├── Compatability.swift ├── Info.plist ├── Internal.swift ├── NSLayoutAnchor+MultiplierConstraints.swift └── Priority.swift └── scripts ├── iOS_Swift.sh ├── iOS_demo_Swift.sh ├── macOS_Swift.sh └── tvOS_Swift.sh /.circleci/SWIFT_4.2.xcconfig: -------------------------------------------------------------------------------- 1 | SWIFT_VERSION=4.2 2 | -------------------------------------------------------------------------------- /.circleci/SWIFT_5.0.xcconfig: -------------------------------------------------------------------------------- 1 | SWIFT_VERSION=5.0 2 | -------------------------------------------------------------------------------- /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2.1 2 | 3 | jobs: 4 | test-swift-package: 5 | executor: xcode-12 6 | steps: 7 | - checkout 8 | - run: swift test 9 | 10 | test-swift-5: 11 | executor: xcode-12 12 | steps: 13 | - setup 14 | - test-scripts 15 | - lint-pod: 16 | swift-version: "5.0" 17 | 18 | test-swift-4: 19 | executor: xcode-12 20 | steps: 21 | - setup 22 | - test-scripts: 23 | swift-version: "4.2" 24 | - lint-pod: 25 | swift-version: "4.2" 26 | 27 | carthage-build-swift-4: 28 | executor: xcode-12 29 | environment: 30 | XCODE_XCCONFIG_FILE: ./.circleci/SWIFT_5.0.xcconfig 31 | steps: 32 | - build-carthage 33 | 34 | carthage-build-swift-5: 35 | executor: xcode-12 36 | environment: 37 | XCODE_XCCONFIG_FILE: ./.circleci/SWIFT_4.2.xcconfig 38 | steps: 39 | - build-carthage 40 | 41 | deploy-to-cocoapods: 42 | executor: xcode-12 43 | steps: 44 | - checkout 45 | - restore-gems 46 | - run: bundle exec pod trunk push 47 | 48 | executors: 49 | xcode-12: 50 | macos: 51 | xcode: "12.1.0" 52 | environment: 53 | LC_ALL: en_US.UTF-8 54 | LANG: en_US.UTF-8 55 | HOMEBREW_NO_AUTO_UPDATE: 1 56 | shell: /bin/bash --login -eo pipefail 57 | 58 | commands: 59 | setup: 60 | description: "Shared setup" 61 | steps: 62 | - checkout 63 | - restore-gems 64 | 65 | restore-gems: 66 | description: "Restore Ruby Gems" 67 | steps: 68 | - run: 69 | name: Set Ruby Version 70 | command: echo "ruby-2.5" > ~/.ruby-version 71 | - restore_cache: 72 | key: 1-gems-{{ checksum "Gemfile.lock" }} 73 | - run: bundle check || bundle install --path vendor/bundle 74 | - save_cache: 75 | key: 1-gems-{{ checksum "Gemfile.lock" }} 76 | paths: 77 | - vendor/bundle 78 | 79 | update-homebrew: 80 | description: "Update Homebrew" 81 | steps: 82 | - run: 83 | name: Update homebrew dependencies 84 | command: brew update 1> /dev/null 2> /dev/null 85 | 86 | update-carthage: 87 | description: "Update Carthage" 88 | steps: 89 | - run: 90 | name: Update Carthage 91 | command: brew outdated carthage || (brew uninstall carthage --force; HOMEBREW_NO_AUTO_UPDATE=1 brew install carthage --force-bottle) 92 | 93 | build-carthage: 94 | description: "Build Carthage" 95 | steps: 96 | - checkout 97 | - update-homebrew 98 | - update-carthage 99 | # Carthage does not work on Xcode 12 https://github.com/Carthage/Carthage/issues/3019 100 | # - run: carthage build --no-skip-current && for platform in Mac iOS tvOS; do test -d Carthage/Build/${platform}/Anchorage.framework || exit 1; done 101 | 102 | lint-pod: 103 | description: "Lints podspec with specified Swift version" 104 | parameters: 105 | swift-version: 106 | type: string 107 | default: "5.0" 108 | steps: 109 | - run: bundle exec pod lib lint --swift-version=<< parameters.swift-version >> 110 | 111 | test-scripts: 112 | description: "Runs test scripts with specified versions" 113 | parameters: 114 | swift-version: 115 | type: string 116 | default: "5.0" 117 | ios-version: 118 | type: string 119 | default: "14.2" 120 | tvos-version: 121 | type: string 122 | default: "13.4" 123 | steps: 124 | - run: ./scripts/iOS_demo_Swift.sh << parameters.ios-version >> << parameters.swift-version >> 125 | - run: ./scripts/iOS_Swift.sh << parameters.ios-version >> << parameters.swift-version >> 126 | - run: ./scripts/macOS_Swift.sh << parameters.swift-version >> 127 | - run: ./scripts/tvOS_Swift.sh << parameters.tvos-version >> << parameters.swift-version >> 128 | 129 | workflows: 130 | version: 2 131 | build-test-deploy: 132 | jobs: 133 | - test-swift-package: 134 | filters: 135 | tags: 136 | only: /.*/ 137 | - test-swift-5: 138 | filters: 139 | tags: 140 | only: /.*/ 141 | - test-swift-4: 142 | filters: 143 | tags: 144 | only: /.*/ 145 | - carthage-build-swift-4: 146 | filters: 147 | tags: 148 | only: /.*/ 149 | - carthage-build-swift-5: 150 | filters: 151 | tags: 152 | only: /.*/ 153 | - deploy-to-cocoapods: 154 | context: CocoaPods 155 | requires: 156 | - test-swift-package 157 | - test-swift-5 158 | - test-swift-4 159 | - carthage-build-swift-4 160 | - carthage-build-swift-5 161 | filters: 162 | tags: 163 | only: /\d+(\.\d+)*(-.*)*/ 164 | branches: 165 | ignore: /.*/ 166 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.DS_Store 2 | 3 | # Xcode 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xcuserstate 23 | 24 | ## Obj-C/Swift specific 25 | *.hmap 26 | *.ipa 27 | *.dSYM.zip 28 | *.dSYM 29 | 30 | ## Playgrounds 31 | timeline.xctimeline 32 | playground.xcworkspace 33 | 34 | # Swift Package Manager 35 | # 36 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 37 | # Packages/ 38 | .build/ 39 | 40 | # Carthage 41 | Carthage/Checkouts 42 | Carthage/Build 43 | 44 | # fastlane 45 | fastlane/report.xml 46 | fastlane/Preview.html 47 | fastlane/screenshots 48 | fastlane/test_output 49 | -------------------------------------------------------------------------------- /.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Anchorage.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "Anchorage" 3 | s.version = "4.5.0" 4 | s.summary = "A collection of operators and utilities that simplify iOS layout code." 5 | s.description = <<-DESC 6 | Create constraints using intuitive operators built directly on top of the NSLayoutAnchor API. Layout has never been simpler! 7 | DESC 8 | s.homepage = "https://github.com/Rightpoint/Anchorage" 9 | s.license = 'MIT' 10 | s.author = { "Rob Visentin" => "jvisenti@gmail.com" } 11 | s.source = { :git => "https://github.com/Rightpoint/Anchorage.git", :tag => s.version.to_s } 12 | s.swift_versions = ['4.0', '4.2', '5.0'] 13 | 14 | s.ios.deployment_target = '9.0' 15 | s.tvos.deployment_target = '9.0' 16 | s.osx.deployment_target = '10.11' 17 | s.requires_arc = true 18 | 19 | s.source_files = "Source/**/*.swift" 20 | end 21 | -------------------------------------------------------------------------------- /Anchorage.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXAggregateTarget section */ 10 | CD6A0E9B1EB7D36400FFF5DB /* RunAllTests */ = { 11 | isa = PBXAggregateTarget; 12 | buildConfigurationList = CD6A0E9C1EB7D36400FFF5DB /* Build configuration list for PBXAggregateTarget "RunAllTests" */; 13 | buildPhases = ( 14 | CD6A0EA01EB7D45D00FFF5DB /* Build and test macOS */, 15 | CD6A0E9F1EB7D36A00FFF5DB /* Build and test iOS */, 16 | CD6A0EA11EB7D57E00FFF5DB /* Build and test tvOS */, 17 | CD6A0EA21EB7DBA300FFF5DB /* Build iOS example project */, 18 | ); 19 | dependencies = ( 20 | ); 21 | name = RunAllTests; 22 | productName = RunAllTests; 23 | }; 24 | /* End PBXAggregateTarget section */ 25 | 26 | /* Begin PBXBuildFile section */ 27 | 2DBB2D451D99596100A1E94B /* RootViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DBB2D441D99596100A1E94B /* RootViewController.swift */; }; 28 | 2DBB2D4B1D99597500A1E94B /* ToggleActiveHeightCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DBB2D461D99597500A1E94B /* ToggleActiveHeightCell.swift */; }; 29 | 2DBB2D4C1D99597500A1E94B /* MinimumWidthViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DBB2D471D99597500A1E94B /* MinimumWidthViewCell.swift */; }; 30 | 2DBB2D4D1D99597500A1E94B /* EqualSpaceViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DBB2D481D99597500A1E94B /* EqualSpaceViewCell.swift */; }; 31 | 2DBB2D4E1D99597500A1E94B /* EdgeContainedLabelCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DBB2D491D99597500A1E94B /* EdgeContainedLabelCell.swift */; }; 32 | 2DBB2D4F1D99597500A1E94B /* BaseCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DBB2D4A1D99597500A1E94B /* BaseCell.swift */; }; 33 | 2DBB2D531D995FA000A1E94B /* AnimatableConstraintCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DBB2D521D995FA000A1E94B /* AnimatableConstraintCell.swift */; }; 34 | 2DD2426B1D95C2CE001D6725 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DD2426A1D95C2CE001D6725 /* AppDelegate.swift */; }; 35 | 2DD2426D1D95C2CE001D6725 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2DD2426C1D95C2CE001D6725 /* Assets.xcassets */; }; 36 | 2DD242701D95C2CE001D6725 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2DD2426E1D95C2CE001D6725 /* LaunchScreen.storyboard */; }; 37 | 3C2050B71D3B213B00995DF3 /* Anchorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C2050B61D3B213B00995DF3 /* Anchorage.swift */; }; 38 | 7A39D6311EB53E1100BDE9C0 /* AnchorageTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A39D6301EB53E1100BDE9C0 /* AnchorageTests.swift */; }; 39 | 7A39D6331EB53E1100BDE9C0 /* Anchorage.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3C2050AB1D3B20FD00995DF3 /* Anchorage.framework */; }; 40 | BBE7C0D71FAB676F00DACD2D /* NSLayoutAnchor+MultiplierConstraints.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBE7C0D51FAB65B900DACD2D /* NSLayoutAnchor+MultiplierConstraints.swift */; }; 41 | BBE7C0D81FAB677500DACD2D /* NSLayoutAnchor+MultiplierConstraints.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBE7C0D51FAB65B900DACD2D /* NSLayoutAnchor+MultiplierConstraints.swift */; }; 42 | BBE7C0D91FAB677600DACD2D /* NSLayoutAnchor+MultiplierConstraints.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBE7C0D51FAB65B900DACD2D /* NSLayoutAnchor+MultiplierConstraints.swift */; }; 43 | CD6A0E6C1EB7CDEF00FFF5DB /* Anchorage.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F15462921E56842400C3948D /* Anchorage.framework */; }; 44 | CD6A0E801EB7CE3A00FFF5DB /* Anchorage.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD6A0E771EB7CE3A00FFF5DB /* Anchorage.framework */; }; 45 | CD71F7A31EB7DD2D008C1CC4 /* AnchorageTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A39D6301EB53E1100BDE9C0 /* AnchorageTests.swift */; }; 46 | CD71F7A41EB7DD2E008C1CC4 /* AnchorageTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A39D6301EB53E1100BDE9C0 /* AnchorageTests.swift */; }; 47 | CD71F7A51EB7DD38008C1CC4 /* Anchorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C2050B61D3B213B00995DF3 /* Anchorage.swift */; }; 48 | CD71F7A61EB7DD38008C1CC4 /* AnchorGroupProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = D469DCB61EB7A975000F3DDD /* AnchorGroupProvider.swift */; }; 49 | CD71F7A71EB7DD38008C1CC4 /* Priority.swift in Sources */ = {isa = PBXBuildFile; fileRef = D469DCB41EB7A904000F3DDD /* Priority.swift */; }; 50 | CD71F7A81EB7DD38008C1CC4 /* Compatability.swift in Sources */ = {isa = PBXBuildFile; fileRef = D401673E1EB7A58D0025DCA5 /* Compatability.swift */; }; 51 | CD71F7A91EB7DD38008C1CC4 /* Internal.swift in Sources */ = {isa = PBXBuildFile; fileRef = D401673C1EB7A4A30025DCA5 /* Internal.swift */; }; 52 | D401673D1EB7A4A30025DCA5 /* Internal.swift in Sources */ = {isa = PBXBuildFile; fileRef = D401673C1EB7A4A30025DCA5 /* Internal.swift */; }; 53 | D401673F1EB7A58D0025DCA5 /* Compatability.swift in Sources */ = {isa = PBXBuildFile; fileRef = D401673E1EB7A58D0025DCA5 /* Compatability.swift */; }; 54 | D40167401EB7A6270025DCA5 /* Internal.swift in Sources */ = {isa = PBXBuildFile; fileRef = D401673C1EB7A4A30025DCA5 /* Internal.swift */; }; 55 | D40167411EB7A6270025DCA5 /* Compatability.swift in Sources */ = {isa = PBXBuildFile; fileRef = D401673E1EB7A58D0025DCA5 /* Compatability.swift */; }; 56 | D469DCB51EB7A904000F3DDD /* Priority.swift in Sources */ = {isa = PBXBuildFile; fileRef = D469DCB41EB7A904000F3DDD /* Priority.swift */; }; 57 | D469DCB71EB7A975000F3DDD /* AnchorGroupProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = D469DCB61EB7A975000F3DDD /* AnchorGroupProvider.swift */; }; 58 | D469DCB81EB7AB2F000F3DDD /* AnchorGroupProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = D469DCB61EB7A975000F3DDD /* AnchorGroupProvider.swift */; }; 59 | D469DCB91EB7AB2F000F3DDD /* Priority.swift in Sources */ = {isa = PBXBuildFile; fileRef = D469DCB41EB7A904000F3DDD /* Priority.swift */; }; 60 | F154629B1E56846200C3948D /* Anchorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C2050B61D3B213B00995DF3 /* Anchorage.swift */; }; 61 | /* End PBXBuildFile section */ 62 | 63 | /* Begin PBXContainerItemProxy section */ 64 | 7A39D6341EB53E1100BDE9C0 /* PBXContainerItemProxy */ = { 65 | isa = PBXContainerItemProxy; 66 | containerPortal = 3C2050A21D3B20FD00995DF3 /* Project object */; 67 | proxyType = 1; 68 | remoteGlobalIDString = 3C2050AA1D3B20FD00995DF3; 69 | remoteInfo = "Anchorage-iOS"; 70 | }; 71 | CD6A0E6D1EB7CDEF00FFF5DB /* PBXContainerItemProxy */ = { 72 | isa = PBXContainerItemProxy; 73 | containerPortal = 3C2050A21D3B20FD00995DF3 /* Project object */; 74 | proxyType = 1; 75 | remoteGlobalIDString = F15462911E56842400C3948D; 76 | remoteInfo = "Anchorage-macOS"; 77 | }; 78 | CD6A0E811EB7CE3A00FFF5DB /* PBXContainerItemProxy */ = { 79 | isa = PBXContainerItemProxy; 80 | containerPortal = 3C2050A21D3B20FD00995DF3 /* Project object */; 81 | proxyType = 1; 82 | remoteGlobalIDString = CD6A0E761EB7CE3A00FFF5DB; 83 | remoteInfo = "Anchorage-tvOS"; 84 | }; 85 | D497F1161EB270CC00CBCF2F /* PBXContainerItemProxy */ = { 86 | isa = PBXContainerItemProxy; 87 | containerPortal = 3C2050A21D3B20FD00995DF3 /* Project object */; 88 | proxyType = 1; 89 | remoteGlobalIDString = 3C2050AA1D3B20FD00995DF3; 90 | remoteInfo = "Anchorage-iOS"; 91 | }; 92 | /* End PBXContainerItemProxy section */ 93 | 94 | /* Begin PBXFileReference section */ 95 | 2DBB2D441D99596100A1E94B /* RootViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RootViewController.swift; sourceTree = ""; }; 96 | 2DBB2D461D99597500A1E94B /* ToggleActiveHeightCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ToggleActiveHeightCell.swift; path = Cells/ToggleActiveHeightCell.swift; sourceTree = ""; }; 97 | 2DBB2D471D99597500A1E94B /* MinimumWidthViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = MinimumWidthViewCell.swift; path = Cells/MinimumWidthViewCell.swift; sourceTree = ""; }; 98 | 2DBB2D481D99597500A1E94B /* EqualSpaceViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = EqualSpaceViewCell.swift; path = Cells/EqualSpaceViewCell.swift; sourceTree = ""; }; 99 | 2DBB2D491D99597500A1E94B /* EdgeContainedLabelCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = EdgeContainedLabelCell.swift; path = Cells/EdgeContainedLabelCell.swift; sourceTree = ""; }; 100 | 2DBB2D4A1D99597500A1E94B /* BaseCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BaseCell.swift; path = Cells/BaseCell.swift; sourceTree = ""; }; 101 | 2DBB2D521D995FA000A1E94B /* AnimatableConstraintCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AnimatableConstraintCell.swift; path = Cells/AnimatableConstraintCell.swift; sourceTree = ""; }; 102 | 2DD242681D95C2CE001D6725 /* AnchorageDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AnchorageDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 103 | 2DD2426A1D95C2CE001D6725 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 104 | 2DD2426C1D95C2CE001D6725 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 105 | 2DD2426F1D95C2CE001D6725 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 106 | 2DD242711D95C2CE001D6725 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 107 | 3C2050AB1D3B20FD00995DF3 /* Anchorage.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Anchorage.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 108 | 3C2050AF1D3B20FD00995DF3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 109 | 3C2050B61D3B213B00995DF3 /* Anchorage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Anchorage.swift; sourceTree = ""; }; 110 | 5B535F432322F06C006C85FB /* Package.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Package.swift; sourceTree = ""; }; 111 | 7A39D62E1EB53E1100BDE9C0 /* AnchorageTests-iOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "AnchorageTests-iOS.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 112 | 7A39D6301EB53E1100BDE9C0 /* AnchorageTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnchorageTests.swift; sourceTree = ""; }; 113 | 7A39D6321EB53E1100BDE9C0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 114 | BBE7C0D51FAB65B900DACD2D /* NSLayoutAnchor+MultiplierConstraints.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSLayoutAnchor+MultiplierConstraints.swift"; sourceTree = ""; }; 115 | CD6A0E671EB7CDEF00FFF5DB /* AnchorageTests-macOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "AnchorageTests-macOS.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 116 | CD6A0E771EB7CE3A00FFF5DB /* Anchorage.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Anchorage.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 117 | CD6A0E7F1EB7CE3A00FFF5DB /* Anchorage-tvOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Anchorage-tvOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 118 | D401673C1EB7A4A30025DCA5 /* Internal.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Internal.swift; sourceTree = ""; }; 119 | D401673E1EB7A58D0025DCA5 /* Compatability.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Compatability.swift; sourceTree = ""; }; 120 | D469DCB41EB7A904000F3DDD /* Priority.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Priority.swift; sourceTree = ""; }; 121 | D469DCB61EB7A975000F3DDD /* AnchorGroupProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnchorGroupProvider.swift; sourceTree = ""; }; 122 | F15462921E56842400C3948D /* Anchorage.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Anchorage.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 123 | /* End PBXFileReference section */ 124 | 125 | /* Begin PBXFrameworksBuildPhase section */ 126 | 2DD242651D95C2CE001D6725 /* Frameworks */ = { 127 | isa = PBXFrameworksBuildPhase; 128 | buildActionMask = 2147483647; 129 | files = ( 130 | ); 131 | runOnlyForDeploymentPostprocessing = 0; 132 | }; 133 | 3C2050A71D3B20FD00995DF3 /* Frameworks */ = { 134 | isa = PBXFrameworksBuildPhase; 135 | buildActionMask = 2147483647; 136 | files = ( 137 | ); 138 | runOnlyForDeploymentPostprocessing = 0; 139 | }; 140 | 7A39D62B1EB53E1100BDE9C0 /* Frameworks */ = { 141 | isa = PBXFrameworksBuildPhase; 142 | buildActionMask = 2147483647; 143 | files = ( 144 | 7A39D6331EB53E1100BDE9C0 /* Anchorage.framework in Frameworks */, 145 | ); 146 | runOnlyForDeploymentPostprocessing = 0; 147 | }; 148 | CD6A0E641EB7CDEF00FFF5DB /* Frameworks */ = { 149 | isa = PBXFrameworksBuildPhase; 150 | buildActionMask = 2147483647; 151 | files = ( 152 | CD6A0E6C1EB7CDEF00FFF5DB /* Anchorage.framework in Frameworks */, 153 | ); 154 | runOnlyForDeploymentPostprocessing = 0; 155 | }; 156 | CD6A0E731EB7CE3A00FFF5DB /* Frameworks */ = { 157 | isa = PBXFrameworksBuildPhase; 158 | buildActionMask = 2147483647; 159 | files = ( 160 | ); 161 | runOnlyForDeploymentPostprocessing = 0; 162 | }; 163 | CD6A0E7C1EB7CE3A00FFF5DB /* Frameworks */ = { 164 | isa = PBXFrameworksBuildPhase; 165 | buildActionMask = 2147483647; 166 | files = ( 167 | CD6A0E801EB7CE3A00FFF5DB /* Anchorage.framework in Frameworks */, 168 | ); 169 | runOnlyForDeploymentPostprocessing = 0; 170 | }; 171 | F154628E1E56842400C3948D /* Frameworks */ = { 172 | isa = PBXFrameworksBuildPhase; 173 | buildActionMask = 2147483647; 174 | files = ( 175 | ); 176 | runOnlyForDeploymentPostprocessing = 0; 177 | }; 178 | /* End PBXFrameworksBuildPhase section */ 179 | 180 | /* Begin PBXGroup section */ 181 | 2DBB2D431D99595500A1E94B /* Cells */ = { 182 | isa = PBXGroup; 183 | children = ( 184 | 2DBB2D4A1D99597500A1E94B /* BaseCell.swift */, 185 | 2DBB2D461D99597500A1E94B /* ToggleActiveHeightCell.swift */, 186 | 2DBB2D471D99597500A1E94B /* MinimumWidthViewCell.swift */, 187 | 2DBB2D481D99597500A1E94B /* EqualSpaceViewCell.swift */, 188 | 2DBB2D491D99597500A1E94B /* EdgeContainedLabelCell.swift */, 189 | 2DBB2D521D995FA000A1E94B /* AnimatableConstraintCell.swift */, 190 | ); 191 | name = Cells; 192 | sourceTree = ""; 193 | }; 194 | 2DD242691D95C2CE001D6725 /* AnchorageDemo */ = { 195 | isa = PBXGroup; 196 | children = ( 197 | 2DBB2D441D99596100A1E94B /* RootViewController.swift */, 198 | 2DBB2D431D99595500A1E94B /* Cells */, 199 | 2DD2426A1D95C2CE001D6725 /* AppDelegate.swift */, 200 | 2DD2426C1D95C2CE001D6725 /* Assets.xcassets */, 201 | 2DD2426E1D95C2CE001D6725 /* LaunchScreen.storyboard */, 202 | 2DD242711D95C2CE001D6725 /* Info.plist */, 203 | ); 204 | path = AnchorageDemo; 205 | sourceTree = ""; 206 | }; 207 | 3C2050A11D3B20FD00995DF3 = { 208 | isa = PBXGroup; 209 | children = ( 210 | 5B535F432322F06C006C85FB /* Package.swift */, 211 | 3C2050AD1D3B20FD00995DF3 /* Anchorage */, 212 | 2DD242691D95C2CE001D6725 /* AnchorageDemo */, 213 | 7A39D62F1EB53E1100BDE9C0 /* AnchorageTests */, 214 | 3C2050AC1D3B20FD00995DF3 /* Products */, 215 | ); 216 | sourceTree = ""; 217 | }; 218 | 3C2050AC1D3B20FD00995DF3 /* Products */ = { 219 | isa = PBXGroup; 220 | children = ( 221 | 3C2050AB1D3B20FD00995DF3 /* Anchorage.framework */, 222 | 2DD242681D95C2CE001D6725 /* AnchorageDemo.app */, 223 | F15462921E56842400C3948D /* Anchorage.framework */, 224 | 7A39D62E1EB53E1100BDE9C0 /* AnchorageTests-iOS.xctest */, 225 | CD6A0E671EB7CDEF00FFF5DB /* AnchorageTests-macOS.xctest */, 226 | CD6A0E771EB7CE3A00FFF5DB /* Anchorage.framework */, 227 | CD6A0E7F1EB7CE3A00FFF5DB /* Anchorage-tvOSTests.xctest */, 228 | ); 229 | name = Products; 230 | sourceTree = ""; 231 | }; 232 | 3C2050AD1D3B20FD00995DF3 /* Anchorage */ = { 233 | isa = PBXGroup; 234 | children = ( 235 | 3C2050B61D3B213B00995DF3 /* Anchorage.swift */, 236 | D469DCB61EB7A975000F3DDD /* AnchorGroupProvider.swift */, 237 | D469DCB41EB7A904000F3DDD /* Priority.swift */, 238 | D401673E1EB7A58D0025DCA5 /* Compatability.swift */, 239 | D401673C1EB7A4A30025DCA5 /* Internal.swift */, 240 | BBE7C0D51FAB65B900DACD2D /* NSLayoutAnchor+MultiplierConstraints.swift */, 241 | 3C2050AF1D3B20FD00995DF3 /* Info.plist */, 242 | ); 243 | name = Anchorage; 244 | path = Source; 245 | sourceTree = ""; 246 | }; 247 | 7A39D62F1EB53E1100BDE9C0 /* AnchorageTests */ = { 248 | isa = PBXGroup; 249 | children = ( 250 | 7A39D6301EB53E1100BDE9C0 /* AnchorageTests.swift */, 251 | 7A39D6321EB53E1100BDE9C0 /* Info.plist */, 252 | ); 253 | path = AnchorageTests; 254 | sourceTree = ""; 255 | }; 256 | /* End PBXGroup section */ 257 | 258 | /* Begin PBXHeadersBuildPhase section */ 259 | 3C2050A81D3B20FD00995DF3 /* Headers */ = { 260 | isa = PBXHeadersBuildPhase; 261 | buildActionMask = 2147483647; 262 | files = ( 263 | ); 264 | runOnlyForDeploymentPostprocessing = 0; 265 | }; 266 | CD6A0E741EB7CE3A00FFF5DB /* Headers */ = { 267 | isa = PBXHeadersBuildPhase; 268 | buildActionMask = 2147483647; 269 | files = ( 270 | ); 271 | runOnlyForDeploymentPostprocessing = 0; 272 | }; 273 | F154628F1E56842400C3948D /* Headers */ = { 274 | isa = PBXHeadersBuildPhase; 275 | buildActionMask = 2147483647; 276 | files = ( 277 | ); 278 | runOnlyForDeploymentPostprocessing = 0; 279 | }; 280 | /* End PBXHeadersBuildPhase section */ 281 | 282 | /* Begin PBXNativeTarget section */ 283 | 2DD242671D95C2CE001D6725 /* AnchorageDemo */ = { 284 | isa = PBXNativeTarget; 285 | buildConfigurationList = 2DD242721D95C2CE001D6725 /* Build configuration list for PBXNativeTarget "AnchorageDemo" */; 286 | buildPhases = ( 287 | 2DD242641D95C2CE001D6725 /* Sources */, 288 | 2DD242651D95C2CE001D6725 /* Frameworks */, 289 | 2DD242661D95C2CE001D6725 /* Resources */, 290 | ); 291 | buildRules = ( 292 | ); 293 | dependencies = ( 294 | D497F1171EB270CC00CBCF2F /* PBXTargetDependency */, 295 | ); 296 | name = AnchorageDemo; 297 | productName = AnchorageDemo; 298 | productReference = 2DD242681D95C2CE001D6725 /* AnchorageDemo.app */; 299 | productType = "com.apple.product-type.application"; 300 | }; 301 | 3C2050AA1D3B20FD00995DF3 /* Anchorage-iOS */ = { 302 | isa = PBXNativeTarget; 303 | buildConfigurationList = 3C2050B31D3B20FD00995DF3 /* Build configuration list for PBXNativeTarget "Anchorage-iOS" */; 304 | buildPhases = ( 305 | 3C2050A61D3B20FD00995DF3 /* Sources */, 306 | 3C2050A71D3B20FD00995DF3 /* Frameworks */, 307 | 3C2050A81D3B20FD00995DF3 /* Headers */, 308 | 3C2050A91D3B20FD00995DF3 /* Resources */, 309 | ); 310 | buildRules = ( 311 | ); 312 | dependencies = ( 313 | ); 314 | name = "Anchorage-iOS"; 315 | productName = Anchorage; 316 | productReference = 3C2050AB1D3B20FD00995DF3 /* Anchorage.framework */; 317 | productType = "com.apple.product-type.framework"; 318 | }; 319 | 7A39D62D1EB53E1100BDE9C0 /* AnchorageTests-iOS */ = { 320 | isa = PBXNativeTarget; 321 | buildConfigurationList = 7A39D6381EB53E1100BDE9C0 /* Build configuration list for PBXNativeTarget "AnchorageTests-iOS" */; 322 | buildPhases = ( 323 | 7A39D62A1EB53E1100BDE9C0 /* Sources */, 324 | 7A39D62B1EB53E1100BDE9C0 /* Frameworks */, 325 | 7A39D62C1EB53E1100BDE9C0 /* Resources */, 326 | ); 327 | buildRules = ( 328 | ); 329 | dependencies = ( 330 | 7A39D6351EB53E1100BDE9C0 /* PBXTargetDependency */, 331 | ); 332 | name = "AnchorageTests-iOS"; 333 | productName = AnchorageTests; 334 | productReference = 7A39D62E1EB53E1100BDE9C0 /* AnchorageTests-iOS.xctest */; 335 | productType = "com.apple.product-type.bundle.unit-test"; 336 | }; 337 | CD6A0E661EB7CDEF00FFF5DB /* AnchorageTests-macOS */ = { 338 | isa = PBXNativeTarget; 339 | buildConfigurationList = CD6A0E711EB7CDEF00FFF5DB /* Build configuration list for PBXNativeTarget "AnchorageTests-macOS" */; 340 | buildPhases = ( 341 | CD6A0E631EB7CDEF00FFF5DB /* Sources */, 342 | CD6A0E641EB7CDEF00FFF5DB /* Frameworks */, 343 | CD6A0E651EB7CDEF00FFF5DB /* Resources */, 344 | ); 345 | buildRules = ( 346 | ); 347 | dependencies = ( 348 | CD6A0E6E1EB7CDEF00FFF5DB /* PBXTargetDependency */, 349 | ); 350 | name = "AnchorageTests-macOS"; 351 | productName = "AnchorageTests-macOS"; 352 | productReference = CD6A0E671EB7CDEF00FFF5DB /* AnchorageTests-macOS.xctest */; 353 | productType = "com.apple.product-type.bundle.unit-test"; 354 | }; 355 | CD6A0E761EB7CE3A00FFF5DB /* Anchorage-tvOS */ = { 356 | isa = PBXNativeTarget; 357 | buildConfigurationList = CD6A0E881EB7CE3A00FFF5DB /* Build configuration list for PBXNativeTarget "Anchorage-tvOS" */; 358 | buildPhases = ( 359 | CD6A0E721EB7CE3A00FFF5DB /* Sources */, 360 | CD6A0E731EB7CE3A00FFF5DB /* Frameworks */, 361 | CD6A0E741EB7CE3A00FFF5DB /* Headers */, 362 | CD6A0E751EB7CE3A00FFF5DB /* Resources */, 363 | ); 364 | buildRules = ( 365 | ); 366 | dependencies = ( 367 | ); 368 | name = "Anchorage-tvOS"; 369 | productName = "Anchorage-tvOS"; 370 | productReference = CD6A0E771EB7CE3A00FFF5DB /* Anchorage.framework */; 371 | productType = "com.apple.product-type.framework"; 372 | }; 373 | CD6A0E7E1EB7CE3A00FFF5DB /* Anchorage-tvOSTests */ = { 374 | isa = PBXNativeTarget; 375 | buildConfigurationList = CD6A0E8B1EB7CE3A00FFF5DB /* Build configuration list for PBXNativeTarget "Anchorage-tvOSTests" */; 376 | buildPhases = ( 377 | CD6A0E7B1EB7CE3A00FFF5DB /* Sources */, 378 | CD6A0E7C1EB7CE3A00FFF5DB /* Frameworks */, 379 | CD6A0E7D1EB7CE3A00FFF5DB /* Resources */, 380 | ); 381 | buildRules = ( 382 | ); 383 | dependencies = ( 384 | CD6A0E821EB7CE3A00FFF5DB /* PBXTargetDependency */, 385 | ); 386 | name = "Anchorage-tvOSTests"; 387 | productName = "Anchorage-tvOSTests"; 388 | productReference = CD6A0E7F1EB7CE3A00FFF5DB /* Anchorage-tvOSTests.xctest */; 389 | productType = "com.apple.product-type.bundle.unit-test"; 390 | }; 391 | F15462911E56842400C3948D /* Anchorage-macOS */ = { 392 | isa = PBXNativeTarget; 393 | buildConfigurationList = F15462991E56842400C3948D /* Build configuration list for PBXNativeTarget "Anchorage-macOS" */; 394 | buildPhases = ( 395 | F154628D1E56842400C3948D /* Sources */, 396 | F154628E1E56842400C3948D /* Frameworks */, 397 | F154628F1E56842400C3948D /* Headers */, 398 | F15462901E56842400C3948D /* Resources */, 399 | ); 400 | buildRules = ( 401 | ); 402 | dependencies = ( 403 | ); 404 | name = "Anchorage-macOS"; 405 | productName = "Anchorage-macOS"; 406 | productReference = F15462921E56842400C3948D /* Anchorage.framework */; 407 | productType = "com.apple.product-type.framework"; 408 | }; 409 | /* End PBXNativeTarget section */ 410 | 411 | /* Begin PBXProject section */ 412 | 3C2050A21D3B20FD00995DF3 /* Project object */ = { 413 | isa = PBXProject; 414 | attributes = { 415 | LastSwiftUpdateCheck = 0830; 416 | LastUpgradeCheck = 1020; 417 | ORGANIZATIONNAME = Rightpoint; 418 | TargetAttributes = { 419 | 2DD242671D95C2CE001D6725 = { 420 | CreatedOnToolsVersion = 8.0; 421 | LastSwiftMigration = 0900; 422 | ProvisioningStyle = Automatic; 423 | }; 424 | 7A39D62D1EB53E1100BDE9C0 = { 425 | CreatedOnToolsVersion = 8.3.2; 426 | LastSwiftMigration = 0900; 427 | ProvisioningStyle = Automatic; 428 | }; 429 | CD6A0E661EB7CDEF00FFF5DB = { 430 | CreatedOnToolsVersion = 8.3.2; 431 | LastSwiftMigration = 1020; 432 | ProvisioningStyle = Automatic; 433 | }; 434 | CD6A0E761EB7CE3A00FFF5DB = { 435 | CreatedOnToolsVersion = 8.3.2; 436 | ProvisioningStyle = Automatic; 437 | }; 438 | CD6A0E7E1EB7CE3A00FFF5DB = { 439 | CreatedOnToolsVersion = 8.3.2; 440 | ProvisioningStyle = Automatic; 441 | }; 442 | CD6A0E9B1EB7D36400FFF5DB = { 443 | CreatedOnToolsVersion = 8.3.2; 444 | DevelopmentTeam = 336S848KQ4; 445 | ProvisioningStyle = Automatic; 446 | }; 447 | F15462911E56842400C3948D = { 448 | CreatedOnToolsVersion = 8.2.1; 449 | LastSwiftMigration = 1020; 450 | ProvisioningStyle = Automatic; 451 | }; 452 | }; 453 | }; 454 | buildConfigurationList = 3C2050A51D3B20FD00995DF3 /* Build configuration list for PBXProject "Anchorage" */; 455 | compatibilityVersion = "Xcode 3.2"; 456 | developmentRegion = en; 457 | hasScannedForEncodings = 0; 458 | knownRegions = ( 459 | en, 460 | Base, 461 | ); 462 | mainGroup = 3C2050A11D3B20FD00995DF3; 463 | productRefGroup = 3C2050AC1D3B20FD00995DF3 /* Products */; 464 | projectDirPath = ""; 465 | projectRoot = ""; 466 | targets = ( 467 | 2DD242671D95C2CE001D6725 /* AnchorageDemo */, 468 | 3C2050AA1D3B20FD00995DF3 /* Anchorage-iOS */, 469 | 7A39D62D1EB53E1100BDE9C0 /* AnchorageTests-iOS */, 470 | F15462911E56842400C3948D /* Anchorage-macOS */, 471 | CD6A0E661EB7CDEF00FFF5DB /* AnchorageTests-macOS */, 472 | CD6A0E761EB7CE3A00FFF5DB /* Anchorage-tvOS */, 473 | CD6A0E7E1EB7CE3A00FFF5DB /* Anchorage-tvOSTests */, 474 | CD6A0E9B1EB7D36400FFF5DB /* RunAllTests */, 475 | ); 476 | }; 477 | /* End PBXProject section */ 478 | 479 | /* Begin PBXResourcesBuildPhase section */ 480 | 2DD242661D95C2CE001D6725 /* Resources */ = { 481 | isa = PBXResourcesBuildPhase; 482 | buildActionMask = 2147483647; 483 | files = ( 484 | 2DD2426D1D95C2CE001D6725 /* Assets.xcassets in Resources */, 485 | 2DD242701D95C2CE001D6725 /* LaunchScreen.storyboard in Resources */, 486 | ); 487 | runOnlyForDeploymentPostprocessing = 0; 488 | }; 489 | 3C2050A91D3B20FD00995DF3 /* Resources */ = { 490 | isa = PBXResourcesBuildPhase; 491 | buildActionMask = 2147483647; 492 | files = ( 493 | ); 494 | runOnlyForDeploymentPostprocessing = 0; 495 | }; 496 | 7A39D62C1EB53E1100BDE9C0 /* Resources */ = { 497 | isa = PBXResourcesBuildPhase; 498 | buildActionMask = 2147483647; 499 | files = ( 500 | ); 501 | runOnlyForDeploymentPostprocessing = 0; 502 | }; 503 | CD6A0E651EB7CDEF00FFF5DB /* Resources */ = { 504 | isa = PBXResourcesBuildPhase; 505 | buildActionMask = 2147483647; 506 | files = ( 507 | ); 508 | runOnlyForDeploymentPostprocessing = 0; 509 | }; 510 | CD6A0E751EB7CE3A00FFF5DB /* Resources */ = { 511 | isa = PBXResourcesBuildPhase; 512 | buildActionMask = 2147483647; 513 | files = ( 514 | ); 515 | runOnlyForDeploymentPostprocessing = 0; 516 | }; 517 | CD6A0E7D1EB7CE3A00FFF5DB /* Resources */ = { 518 | isa = PBXResourcesBuildPhase; 519 | buildActionMask = 2147483647; 520 | files = ( 521 | ); 522 | runOnlyForDeploymentPostprocessing = 0; 523 | }; 524 | F15462901E56842400C3948D /* Resources */ = { 525 | isa = PBXResourcesBuildPhase; 526 | buildActionMask = 2147483647; 527 | files = ( 528 | ); 529 | runOnlyForDeploymentPostprocessing = 0; 530 | }; 531 | /* End PBXResourcesBuildPhase section */ 532 | 533 | /* Begin PBXShellScriptBuildPhase section */ 534 | CD6A0E9F1EB7D36A00FFF5DB /* Build and test iOS */ = { 535 | isa = PBXShellScriptBuildPhase; 536 | buildActionMask = 2147483647; 537 | files = ( 538 | ); 539 | inputPaths = ( 540 | ); 541 | name = "Build and test iOS"; 542 | outputPaths = ( 543 | ); 544 | runOnlyForDeploymentPostprocessing = 0; 545 | shellPath = /bin/sh; 546 | shellScript = "# Avoiding modern build system because of simultaneous access bug: https://stackoverflow.com/a/55572873/255489\nxcodebuild build-for-testing test-without-building -project Anchorage.xcodeproj -scheme Anchorage-iOS -sdk iphonesimulator -destination \"name=iPhone 6s\" SWIFT_VERSION=4.2 CODE_SIGNING_REQUIRED=NO CODE_SIGN_IDENTITY= -UseModernBuildSystem=NO\nxcodebuild build-for-testing test-without-building -project Anchorage.xcodeproj -scheme Anchorage-iOS -sdk iphonesimulator -destination \"name=iPhone 6s\" SWIFT_VERSION=5.0 CODE_SIGNING_REQUIRED=NO CODE_SIGN_IDENTITY= -UseModernBuildSystem=NO\n"; 547 | }; 548 | CD6A0EA01EB7D45D00FFF5DB /* Build and test macOS */ = { 549 | isa = PBXShellScriptBuildPhase; 550 | buildActionMask = 2147483647; 551 | files = ( 552 | ); 553 | inputPaths = ( 554 | ); 555 | name = "Build and test macOS"; 556 | outputPaths = ( 557 | ); 558 | runOnlyForDeploymentPostprocessing = 0; 559 | shellPath = /bin/sh; 560 | shellScript = "# Avoiding modern build system because of simultaneous access bug: https://stackoverflow.com/a/55572873/255489\nxcodebuild build-for-testing test-without-building -project Anchorage.xcodeproj -scheme Anchorage-macOS -sdk macosx -destination \"arch=x86_64\" SWIFT_VERSION=4.2 CODE_SIGNING_REQUIRED=NO CODE_SIGN_IDENTITY= -UseModernBuildSystem=NO\nxcodebuild build-for-testing test-without-building -project Anchorage.xcodeproj -scheme Anchorage-macOS -sdk macosx -destination \"arch=x86_64\" SWIFT_VERSION=5.0 CODE_SIGNING_REQUIRED=NO CODE_SIGN_IDENTITY= -UseModernBuildSystem=NO\n"; 561 | }; 562 | CD6A0EA11EB7D57E00FFF5DB /* Build and test tvOS */ = { 563 | isa = PBXShellScriptBuildPhase; 564 | buildActionMask = 2147483647; 565 | files = ( 566 | ); 567 | inputPaths = ( 568 | ); 569 | name = "Build and test tvOS"; 570 | outputPaths = ( 571 | ); 572 | runOnlyForDeploymentPostprocessing = 0; 573 | shellPath = /bin/sh; 574 | shellScript = "# Avoiding modern build system because of simultaneous access bug: https://stackoverflow.com/a/55572873/255489\nxcodebuild build-for-testing test-without-building -project Anchorage.xcodeproj -scheme \"Anchorage-tvOS\" -sdk \"appletvsimulator\" -destination \"name=Apple TV\" SWIFT_VERSION=4.2 CODE_SIGNING_REQUIRED=NO CODE_SIGN_IDENTITY= -UseModernBuildSystem=NO\nxcodebuild build-for-testing test-without-building -project Anchorage.xcodeproj -scheme \"Anchorage-tvOS\" -sdk \"appletvsimulator\" -destination \"name=Apple TV\" SWIFT_VERSION=5.0 CODE_SIGNING_REQUIRED=NO CODE_SIGN_IDENTITY= -UseModernBuildSystem=NO\n"; 575 | }; 576 | CD6A0EA21EB7DBA300FFF5DB /* Build iOS example project */ = { 577 | isa = PBXShellScriptBuildPhase; 578 | buildActionMask = 2147483647; 579 | files = ( 580 | ); 581 | inputPaths = ( 582 | ); 583 | name = "Build iOS example project"; 584 | outputPaths = ( 585 | ); 586 | runOnlyForDeploymentPostprocessing = 0; 587 | shellPath = /bin/sh; 588 | shellScript = "# Avoiding modern build system because of simultaneous access bug: https://stackoverflow.com/a/55572873/255489\nxcodebuild build -project Anchorage.xcodeproj -scheme AnchorageDemo -sdk iphonesimulator -destination \"name=iPhone 6s\" SWIFT_VERSION=4.2 CODE_SIGNING_REQUIRED=NO CODE_SIGN_IDENTITY= -UseModernBuildSystem=NO\nxcodebuild build -project Anchorage.xcodeproj -scheme AnchorageDemo -sdk iphonesimulator -destination \"name=iPhone 6s\" SWIFT_VERSION=5.0 CODE_SIGNING_REQUIRED=NO CODE_SIGN_IDENTITY= -UseModernBuildSystem=NO\n"; 589 | }; 590 | /* End PBXShellScriptBuildPhase section */ 591 | 592 | /* Begin PBXSourcesBuildPhase section */ 593 | 2DD242641D95C2CE001D6725 /* Sources */ = { 594 | isa = PBXSourcesBuildPhase; 595 | buildActionMask = 2147483647; 596 | files = ( 597 | 2DBB2D4C1D99597500A1E94B /* MinimumWidthViewCell.swift in Sources */, 598 | 2DBB2D4E1D99597500A1E94B /* EdgeContainedLabelCell.swift in Sources */, 599 | 2DBB2D451D99596100A1E94B /* RootViewController.swift in Sources */, 600 | 2DBB2D4B1D99597500A1E94B /* ToggleActiveHeightCell.swift in Sources */, 601 | 2DBB2D531D995FA000A1E94B /* AnimatableConstraintCell.swift in Sources */, 602 | 2DBB2D4F1D99597500A1E94B /* BaseCell.swift in Sources */, 603 | 2DD2426B1D95C2CE001D6725 /* AppDelegate.swift in Sources */, 604 | 2DBB2D4D1D99597500A1E94B /* EqualSpaceViewCell.swift in Sources */, 605 | ); 606 | runOnlyForDeploymentPostprocessing = 0; 607 | }; 608 | 3C2050A61D3B20FD00995DF3 /* Sources */ = { 609 | isa = PBXSourcesBuildPhase; 610 | buildActionMask = 2147483647; 611 | files = ( 612 | 3C2050B71D3B213B00995DF3 /* Anchorage.swift in Sources */, 613 | BBE7C0D71FAB676F00DACD2D /* NSLayoutAnchor+MultiplierConstraints.swift in Sources */, 614 | D401673D1EB7A4A30025DCA5 /* Internal.swift in Sources */, 615 | D401673F1EB7A58D0025DCA5 /* Compatability.swift in Sources */, 616 | D469DCB71EB7A975000F3DDD /* AnchorGroupProvider.swift in Sources */, 617 | D469DCB51EB7A904000F3DDD /* Priority.swift in Sources */, 618 | ); 619 | runOnlyForDeploymentPostprocessing = 0; 620 | }; 621 | 7A39D62A1EB53E1100BDE9C0 /* Sources */ = { 622 | isa = PBXSourcesBuildPhase; 623 | buildActionMask = 2147483647; 624 | files = ( 625 | 7A39D6311EB53E1100BDE9C0 /* AnchorageTests.swift in Sources */, 626 | ); 627 | runOnlyForDeploymentPostprocessing = 0; 628 | }; 629 | CD6A0E631EB7CDEF00FFF5DB /* Sources */ = { 630 | isa = PBXSourcesBuildPhase; 631 | buildActionMask = 2147483647; 632 | files = ( 633 | CD71F7A31EB7DD2D008C1CC4 /* AnchorageTests.swift in Sources */, 634 | ); 635 | runOnlyForDeploymentPostprocessing = 0; 636 | }; 637 | CD6A0E721EB7CE3A00FFF5DB /* Sources */ = { 638 | isa = PBXSourcesBuildPhase; 639 | buildActionMask = 2147483647; 640 | files = ( 641 | CD71F7A81EB7DD38008C1CC4 /* Compatability.swift in Sources */, 642 | BBE7C0D91FAB677600DACD2D /* NSLayoutAnchor+MultiplierConstraints.swift in Sources */, 643 | CD71F7A51EB7DD38008C1CC4 /* Anchorage.swift in Sources */, 644 | CD71F7A61EB7DD38008C1CC4 /* AnchorGroupProvider.swift in Sources */, 645 | CD71F7A91EB7DD38008C1CC4 /* Internal.swift in Sources */, 646 | CD71F7A71EB7DD38008C1CC4 /* Priority.swift in Sources */, 647 | ); 648 | runOnlyForDeploymentPostprocessing = 0; 649 | }; 650 | CD6A0E7B1EB7CE3A00FFF5DB /* Sources */ = { 651 | isa = PBXSourcesBuildPhase; 652 | buildActionMask = 2147483647; 653 | files = ( 654 | CD71F7A41EB7DD2E008C1CC4 /* AnchorageTests.swift in Sources */, 655 | ); 656 | runOnlyForDeploymentPostprocessing = 0; 657 | }; 658 | F154628D1E56842400C3948D /* Sources */ = { 659 | isa = PBXSourcesBuildPhase; 660 | buildActionMask = 2147483647; 661 | files = ( 662 | D40167401EB7A6270025DCA5 /* Internal.swift in Sources */, 663 | BBE7C0D81FAB677500DACD2D /* NSLayoutAnchor+MultiplierConstraints.swift in Sources */, 664 | F154629B1E56846200C3948D /* Anchorage.swift in Sources */, 665 | D40167411EB7A6270025DCA5 /* Compatability.swift in Sources */, 666 | D469DCB91EB7AB2F000F3DDD /* Priority.swift in Sources */, 667 | D469DCB81EB7AB2F000F3DDD /* AnchorGroupProvider.swift in Sources */, 668 | ); 669 | runOnlyForDeploymentPostprocessing = 0; 670 | }; 671 | /* End PBXSourcesBuildPhase section */ 672 | 673 | /* Begin PBXTargetDependency section */ 674 | 7A39D6351EB53E1100BDE9C0 /* PBXTargetDependency */ = { 675 | isa = PBXTargetDependency; 676 | target = 3C2050AA1D3B20FD00995DF3 /* Anchorage-iOS */; 677 | targetProxy = 7A39D6341EB53E1100BDE9C0 /* PBXContainerItemProxy */; 678 | }; 679 | CD6A0E6E1EB7CDEF00FFF5DB /* PBXTargetDependency */ = { 680 | isa = PBXTargetDependency; 681 | target = F15462911E56842400C3948D /* Anchorage-macOS */; 682 | targetProxy = CD6A0E6D1EB7CDEF00FFF5DB /* PBXContainerItemProxy */; 683 | }; 684 | CD6A0E821EB7CE3A00FFF5DB /* PBXTargetDependency */ = { 685 | isa = PBXTargetDependency; 686 | target = CD6A0E761EB7CE3A00FFF5DB /* Anchorage-tvOS */; 687 | targetProxy = CD6A0E811EB7CE3A00FFF5DB /* PBXContainerItemProxy */; 688 | }; 689 | D497F1171EB270CC00CBCF2F /* PBXTargetDependency */ = { 690 | isa = PBXTargetDependency; 691 | target = 3C2050AA1D3B20FD00995DF3 /* Anchorage-iOS */; 692 | targetProxy = D497F1161EB270CC00CBCF2F /* PBXContainerItemProxy */; 693 | }; 694 | /* End PBXTargetDependency section */ 695 | 696 | /* Begin PBXVariantGroup section */ 697 | 2DD2426E1D95C2CE001D6725 /* LaunchScreen.storyboard */ = { 698 | isa = PBXVariantGroup; 699 | children = ( 700 | 2DD2426F1D95C2CE001D6725 /* Base */, 701 | ); 702 | name = LaunchScreen.storyboard; 703 | sourceTree = ""; 704 | }; 705 | /* End PBXVariantGroup section */ 706 | 707 | /* Begin XCBuildConfiguration section */ 708 | 2DD242731D95C2CE001D6725 /* Debug */ = { 709 | isa = XCBuildConfiguration; 710 | buildSettings = { 711 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 712 | CLANG_WARN_INFINITE_RECURSION = YES; 713 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 714 | DEVELOPMENT_TEAM = ""; 715 | INFOPLIST_FILE = AnchorageDemo/Info.plist; 716 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 717 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 718 | PRODUCT_BUNDLE_IDENTIFIER = com.rightpoint.AnchorageDemo; 719 | PRODUCT_NAME = "$(TARGET_NAME)"; 720 | SDKROOT = iphoneos; 721 | }; 722 | name = Debug; 723 | }; 724 | 2DD242741D95C2CE001D6725 /* Release */ = { 725 | isa = XCBuildConfiguration; 726 | buildSettings = { 727 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 728 | CLANG_WARN_INFINITE_RECURSION = YES; 729 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 730 | DEVELOPMENT_TEAM = ""; 731 | INFOPLIST_FILE = AnchorageDemo/Info.plist; 732 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 733 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 734 | PRODUCT_BUNDLE_IDENTIFIER = com.rightpoint.AnchorageDemo; 735 | PRODUCT_NAME = "$(TARGET_NAME)"; 736 | SDKROOT = iphoneos; 737 | }; 738 | name = Release; 739 | }; 740 | 3C2050B11D3B20FD00995DF3 /* Debug */ = { 741 | isa = XCBuildConfiguration; 742 | buildSettings = { 743 | ALWAYS_SEARCH_USER_PATHS = NO; 744 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 745 | CLANG_ANALYZER_NONNULL = YES; 746 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 747 | CLANG_CXX_LIBRARY = "libc++"; 748 | CLANG_ENABLE_MODULES = YES; 749 | CLANG_ENABLE_OBJC_ARC = YES; 750 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 751 | CLANG_WARN_BOOL_CONVERSION = YES; 752 | CLANG_WARN_COMMA = YES; 753 | CLANG_WARN_CONSTANT_CONVERSION = YES; 754 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 755 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 756 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 757 | CLANG_WARN_EMPTY_BODY = YES; 758 | CLANG_WARN_ENUM_CONVERSION = YES; 759 | CLANG_WARN_INFINITE_RECURSION = YES; 760 | CLANG_WARN_INT_CONVERSION = YES; 761 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 762 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 763 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 764 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 765 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 766 | CLANG_WARN_STRICT_PROTOTYPES = YES; 767 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 768 | CLANG_WARN_UNREACHABLE_CODE = YES; 769 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 770 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 771 | COPY_PHASE_STRIP = NO; 772 | CURRENT_PROJECT_VERSION = 1; 773 | DEBUG_INFORMATION_FORMAT = dwarf; 774 | ENABLE_STRICT_OBJC_MSGSEND = YES; 775 | ENABLE_TESTABILITY = YES; 776 | GCC_C_LANGUAGE_STANDARD = gnu99; 777 | GCC_DYNAMIC_NO_PIC = NO; 778 | GCC_NO_COMMON_BLOCKS = YES; 779 | GCC_OPTIMIZATION_LEVEL = 0; 780 | GCC_PREPROCESSOR_DEFINITIONS = ( 781 | "DEBUG=1", 782 | "$(inherited)", 783 | ); 784 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 785 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 786 | GCC_WARN_UNDECLARED_SELECTOR = YES; 787 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 788 | GCC_WARN_UNUSED_FUNCTION = YES; 789 | GCC_WARN_UNUSED_VARIABLE = YES; 790 | MTL_ENABLE_DEBUG_INFO = YES; 791 | ONLY_ACTIVE_ARCH = YES; 792 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 793 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 794 | SWIFT_VERSION = 5.0; 795 | TARGETED_DEVICE_FAMILY = "1,2"; 796 | VERSIONING_SYSTEM = "apple-generic"; 797 | VERSION_INFO_PREFIX = ""; 798 | }; 799 | name = Debug; 800 | }; 801 | 3C2050B21D3B20FD00995DF3 /* Release */ = { 802 | isa = XCBuildConfiguration; 803 | buildSettings = { 804 | ALWAYS_SEARCH_USER_PATHS = NO; 805 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 806 | CLANG_ANALYZER_NONNULL = YES; 807 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 808 | CLANG_CXX_LIBRARY = "libc++"; 809 | CLANG_ENABLE_MODULES = YES; 810 | CLANG_ENABLE_OBJC_ARC = YES; 811 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 812 | CLANG_WARN_BOOL_CONVERSION = YES; 813 | CLANG_WARN_COMMA = YES; 814 | CLANG_WARN_CONSTANT_CONVERSION = YES; 815 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 816 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 817 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 818 | CLANG_WARN_EMPTY_BODY = YES; 819 | CLANG_WARN_ENUM_CONVERSION = YES; 820 | CLANG_WARN_INFINITE_RECURSION = YES; 821 | CLANG_WARN_INT_CONVERSION = YES; 822 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 823 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 824 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 825 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 826 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 827 | CLANG_WARN_STRICT_PROTOTYPES = YES; 828 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 829 | CLANG_WARN_UNREACHABLE_CODE = YES; 830 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 831 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 832 | COPY_PHASE_STRIP = NO; 833 | CURRENT_PROJECT_VERSION = 1; 834 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 835 | ENABLE_NS_ASSERTIONS = NO; 836 | ENABLE_STRICT_OBJC_MSGSEND = YES; 837 | GCC_C_LANGUAGE_STANDARD = gnu99; 838 | GCC_NO_COMMON_BLOCKS = YES; 839 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 840 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 841 | GCC_WARN_UNDECLARED_SELECTOR = YES; 842 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 843 | GCC_WARN_UNUSED_FUNCTION = YES; 844 | GCC_WARN_UNUSED_VARIABLE = YES; 845 | MTL_ENABLE_DEBUG_INFO = NO; 846 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 847 | SWIFT_VERSION = 5.0; 848 | TARGETED_DEVICE_FAMILY = "1,2"; 849 | VALIDATE_PRODUCT = YES; 850 | VERSIONING_SYSTEM = "apple-generic"; 851 | VERSION_INFO_PREFIX = ""; 852 | }; 853 | name = Release; 854 | }; 855 | 3C2050B41D3B20FD00995DF3 /* Debug */ = { 856 | isa = XCBuildConfiguration; 857 | buildSettings = { 858 | APPLICATION_EXTENSION_API_ONLY = YES; 859 | CLANG_ENABLE_MODULES = YES; 860 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 861 | DEFINES_MODULE = YES; 862 | DEVELOPMENT_TEAM = ""; 863 | DYLIB_COMPATIBILITY_VERSION = 1; 864 | DYLIB_CURRENT_VERSION = 1; 865 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 866 | INFOPLIST_FILE = "$(SRCROOT)/Source/Info.plist"; 867 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 868 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 869 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 870 | PRODUCT_BUNDLE_IDENTIFIER = "com.rightpoint.$(PRODUCT_NAME)"; 871 | PRODUCT_NAME = Anchorage; 872 | SDKROOT = iphoneos; 873 | SKIP_INSTALL = YES; 874 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 875 | }; 876 | name = Debug; 877 | }; 878 | 3C2050B51D3B20FD00995DF3 /* Release */ = { 879 | isa = XCBuildConfiguration; 880 | buildSettings = { 881 | APPLICATION_EXTENSION_API_ONLY = YES; 882 | CLANG_ENABLE_MODULES = YES; 883 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 884 | DEFINES_MODULE = YES; 885 | DEVELOPMENT_TEAM = ""; 886 | DYLIB_COMPATIBILITY_VERSION = 1; 887 | DYLIB_CURRENT_VERSION = 1; 888 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 889 | INFOPLIST_FILE = "$(SRCROOT)/Source/Info.plist"; 890 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 891 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 892 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 893 | PRODUCT_BUNDLE_IDENTIFIER = "com.rightpoint.$(PRODUCT_NAME)"; 894 | PRODUCT_NAME = Anchorage; 895 | SDKROOT = iphoneos; 896 | SKIP_INSTALL = YES; 897 | }; 898 | name = Release; 899 | }; 900 | 7A39D6361EB53E1100BDE9C0 /* Debug */ = { 901 | isa = XCBuildConfiguration; 902 | buildSettings = { 903 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 904 | DEVELOPMENT_TEAM = ""; 905 | INFOPLIST_FILE = AnchorageTests/Info.plist; 906 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 907 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 908 | PRODUCT_BUNDLE_IDENTIFIER = "com.rightpoint.$(PRODUCT_NAME)"; 909 | PRODUCT_NAME = "$(TARGET_NAME)"; 910 | SDKROOT = iphoneos; 911 | }; 912 | name = Debug; 913 | }; 914 | 7A39D6371EB53E1100BDE9C0 /* Release */ = { 915 | isa = XCBuildConfiguration; 916 | buildSettings = { 917 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 918 | DEVELOPMENT_TEAM = ""; 919 | INFOPLIST_FILE = AnchorageTests/Info.plist; 920 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 921 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 922 | PRODUCT_BUNDLE_IDENTIFIER = "com.rightpoint.$(PRODUCT_NAME)"; 923 | PRODUCT_NAME = "$(TARGET_NAME)"; 924 | SDKROOT = iphoneos; 925 | }; 926 | name = Release; 927 | }; 928 | CD6A0E6F1EB7CDEF00FFF5DB /* Debug */ = { 929 | isa = XCBuildConfiguration; 930 | buildSettings = { 931 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 932 | COMBINE_HIDPI_IMAGES = YES; 933 | INFOPLIST_FILE = AnchorageTests/Info.plist; 934 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; 935 | MACOSX_DEPLOYMENT_TARGET = 10.11; 936 | PRODUCT_BUNDLE_IDENTIFIER = "com.rightpoint.$(PRODUCT_NAME)"; 937 | PRODUCT_NAME = "$(TARGET_NAME)"; 938 | SDKROOT = macosx; 939 | }; 940 | name = Debug; 941 | }; 942 | CD6A0E701EB7CDEF00FFF5DB /* Release */ = { 943 | isa = XCBuildConfiguration; 944 | buildSettings = { 945 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 946 | COMBINE_HIDPI_IMAGES = YES; 947 | INFOPLIST_FILE = AnchorageTests/Info.plist; 948 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; 949 | MACOSX_DEPLOYMENT_TARGET = 10.11; 950 | PRODUCT_BUNDLE_IDENTIFIER = "com.rightpoint.$(PRODUCT_NAME)"; 951 | PRODUCT_NAME = "$(TARGET_NAME)"; 952 | SDKROOT = macosx; 953 | }; 954 | name = Release; 955 | }; 956 | CD6A0E891EB7CE3A00FFF5DB /* Debug */ = { 957 | isa = XCBuildConfiguration; 958 | buildSettings = { 959 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 960 | CODE_SIGN_IDENTITY = ""; 961 | DEFINES_MODULE = YES; 962 | DEVELOPMENT_TEAM = ""; 963 | DYLIB_COMPATIBILITY_VERSION = 1; 964 | DYLIB_CURRENT_VERSION = 1; 965 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 966 | INFOPLIST_FILE = "$(SRCROOT)/Source/Info.plist"; 967 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 968 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 969 | PRODUCT_BUNDLE_IDENTIFIER = "com.rightpoint.$(PRODUCT_NAME)"; 970 | PRODUCT_NAME = Anchorage; 971 | SDKROOT = appletvos; 972 | SKIP_INSTALL = YES; 973 | TARGETED_DEVICE_FAMILY = 3; 974 | TVOS_DEPLOYMENT_TARGET = 9.0; 975 | }; 976 | name = Debug; 977 | }; 978 | CD6A0E8A1EB7CE3A00FFF5DB /* Release */ = { 979 | isa = XCBuildConfiguration; 980 | buildSettings = { 981 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 982 | CODE_SIGN_IDENTITY = ""; 983 | DEFINES_MODULE = YES; 984 | DEVELOPMENT_TEAM = ""; 985 | DYLIB_COMPATIBILITY_VERSION = 1; 986 | DYLIB_CURRENT_VERSION = 1; 987 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 988 | INFOPLIST_FILE = "$(SRCROOT)/Source/Info.plist"; 989 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 990 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 991 | PRODUCT_BUNDLE_IDENTIFIER = "com.rightpoint.$(PRODUCT_NAME)"; 992 | PRODUCT_NAME = Anchorage; 993 | SDKROOT = appletvos; 994 | SKIP_INSTALL = YES; 995 | TARGETED_DEVICE_FAMILY = 3; 996 | TVOS_DEPLOYMENT_TARGET = 9.0; 997 | }; 998 | name = Release; 999 | }; 1000 | CD6A0E8C1EB7CE3A00FFF5DB /* Debug */ = { 1001 | isa = XCBuildConfiguration; 1002 | buildSettings = { 1003 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 1004 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 1005 | DEVELOPMENT_TEAM = ""; 1006 | INFOPLIST_FILE = AnchorageTests/Info.plist; 1007 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 1008 | PRODUCT_BUNDLE_IDENTIFIER = "com.rightpoint.$(PRODUCT_NAME)"; 1009 | PRODUCT_NAME = "$(TARGET_NAME)"; 1010 | SDKROOT = appletvos; 1011 | TARGETED_DEVICE_FAMILY = 3; 1012 | TVOS_DEPLOYMENT_TARGET = 9.0; 1013 | }; 1014 | name = Debug; 1015 | }; 1016 | CD6A0E8D1EB7CE3A00FFF5DB /* Release */ = { 1017 | isa = XCBuildConfiguration; 1018 | buildSettings = { 1019 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 1020 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 1021 | DEVELOPMENT_TEAM = ""; 1022 | INFOPLIST_FILE = AnchorageTests/Info.plist; 1023 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 1024 | PRODUCT_BUNDLE_IDENTIFIER = "com.rightpoint.$(PRODUCT_NAME)"; 1025 | PRODUCT_NAME = "$(TARGET_NAME)"; 1026 | SDKROOT = appletvos; 1027 | TARGETED_DEVICE_FAMILY = 3; 1028 | TVOS_DEPLOYMENT_TARGET = 9.0; 1029 | }; 1030 | name = Release; 1031 | }; 1032 | CD6A0E9D1EB7D36400FFF5DB /* Debug */ = { 1033 | isa = XCBuildConfiguration; 1034 | buildSettings = { 1035 | DEVELOPMENT_TEAM = 336S848KQ4; 1036 | PRODUCT_NAME = "$(TARGET_NAME)"; 1037 | }; 1038 | name = Debug; 1039 | }; 1040 | CD6A0E9E1EB7D36400FFF5DB /* Release */ = { 1041 | isa = XCBuildConfiguration; 1042 | buildSettings = { 1043 | DEVELOPMENT_TEAM = 336S848KQ4; 1044 | PRODUCT_NAME = "$(TARGET_NAME)"; 1045 | }; 1046 | name = Release; 1047 | }; 1048 | F15462971E56842400C3948D /* Debug */ = { 1049 | isa = XCBuildConfiguration; 1050 | buildSettings = { 1051 | APPLICATION_EXTENSION_API_ONLY = YES; 1052 | CLANG_WARN_INFINITE_RECURSION = YES; 1053 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 1054 | CODE_SIGN_IDENTITY = "-"; 1055 | COMBINE_HIDPI_IMAGES = YES; 1056 | DEFINES_MODULE = YES; 1057 | DYLIB_COMPATIBILITY_VERSION = 1; 1058 | DYLIB_CURRENT_VERSION = 1; 1059 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 1060 | FRAMEWORK_VERSION = A; 1061 | INFOPLIST_FILE = "$(SRCROOT)/Source/Info.plist"; 1062 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 1063 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; 1064 | MACOSX_DEPLOYMENT_TARGET = 10.11; 1065 | PRODUCT_BUNDLE_IDENTIFIER = "com.rightpoint.$(PRODUCT_NAME)"; 1066 | PRODUCT_NAME = Anchorage; 1067 | SDKROOT = macosx; 1068 | SKIP_INSTALL = YES; 1069 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 1070 | }; 1071 | name = Debug; 1072 | }; 1073 | F15462981E56842400C3948D /* Release */ = { 1074 | isa = XCBuildConfiguration; 1075 | buildSettings = { 1076 | APPLICATION_EXTENSION_API_ONLY = YES; 1077 | CLANG_WARN_INFINITE_RECURSION = YES; 1078 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 1079 | CODE_SIGN_IDENTITY = "-"; 1080 | COMBINE_HIDPI_IMAGES = YES; 1081 | DEFINES_MODULE = YES; 1082 | DYLIB_COMPATIBILITY_VERSION = 1; 1083 | DYLIB_CURRENT_VERSION = 1; 1084 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 1085 | FRAMEWORK_VERSION = A; 1086 | INFOPLIST_FILE = "$(SRCROOT)/Source/Info.plist"; 1087 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 1088 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; 1089 | MACOSX_DEPLOYMENT_TARGET = 10.11; 1090 | PRODUCT_BUNDLE_IDENTIFIER = "com.rightpoint.$(PRODUCT_NAME)"; 1091 | PRODUCT_NAME = Anchorage; 1092 | SDKROOT = macosx; 1093 | SKIP_INSTALL = YES; 1094 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 1095 | }; 1096 | name = Release; 1097 | }; 1098 | /* End XCBuildConfiguration section */ 1099 | 1100 | /* Begin XCConfigurationList section */ 1101 | 2DD242721D95C2CE001D6725 /* Build configuration list for PBXNativeTarget "AnchorageDemo" */ = { 1102 | isa = XCConfigurationList; 1103 | buildConfigurations = ( 1104 | 2DD242731D95C2CE001D6725 /* Debug */, 1105 | 2DD242741D95C2CE001D6725 /* Release */, 1106 | ); 1107 | defaultConfigurationIsVisible = 0; 1108 | defaultConfigurationName = Release; 1109 | }; 1110 | 3C2050A51D3B20FD00995DF3 /* Build configuration list for PBXProject "Anchorage" */ = { 1111 | isa = XCConfigurationList; 1112 | buildConfigurations = ( 1113 | 3C2050B11D3B20FD00995DF3 /* Debug */, 1114 | 3C2050B21D3B20FD00995DF3 /* Release */, 1115 | ); 1116 | defaultConfigurationIsVisible = 0; 1117 | defaultConfigurationName = Release; 1118 | }; 1119 | 3C2050B31D3B20FD00995DF3 /* Build configuration list for PBXNativeTarget "Anchorage-iOS" */ = { 1120 | isa = XCConfigurationList; 1121 | buildConfigurations = ( 1122 | 3C2050B41D3B20FD00995DF3 /* Debug */, 1123 | 3C2050B51D3B20FD00995DF3 /* Release */, 1124 | ); 1125 | defaultConfigurationIsVisible = 0; 1126 | defaultConfigurationName = Release; 1127 | }; 1128 | 7A39D6381EB53E1100BDE9C0 /* Build configuration list for PBXNativeTarget "AnchorageTests-iOS" */ = { 1129 | isa = XCConfigurationList; 1130 | buildConfigurations = ( 1131 | 7A39D6361EB53E1100BDE9C0 /* Debug */, 1132 | 7A39D6371EB53E1100BDE9C0 /* Release */, 1133 | ); 1134 | defaultConfigurationIsVisible = 0; 1135 | defaultConfigurationName = Release; 1136 | }; 1137 | CD6A0E711EB7CDEF00FFF5DB /* Build configuration list for PBXNativeTarget "AnchorageTests-macOS" */ = { 1138 | isa = XCConfigurationList; 1139 | buildConfigurations = ( 1140 | CD6A0E6F1EB7CDEF00FFF5DB /* Debug */, 1141 | CD6A0E701EB7CDEF00FFF5DB /* Release */, 1142 | ); 1143 | defaultConfigurationIsVisible = 0; 1144 | defaultConfigurationName = Release; 1145 | }; 1146 | CD6A0E881EB7CE3A00FFF5DB /* Build configuration list for PBXNativeTarget "Anchorage-tvOS" */ = { 1147 | isa = XCConfigurationList; 1148 | buildConfigurations = ( 1149 | CD6A0E891EB7CE3A00FFF5DB /* Debug */, 1150 | CD6A0E8A1EB7CE3A00FFF5DB /* Release */, 1151 | ); 1152 | defaultConfigurationIsVisible = 0; 1153 | defaultConfigurationName = Release; 1154 | }; 1155 | CD6A0E8B1EB7CE3A00FFF5DB /* Build configuration list for PBXNativeTarget "Anchorage-tvOSTests" */ = { 1156 | isa = XCConfigurationList; 1157 | buildConfigurations = ( 1158 | CD6A0E8C1EB7CE3A00FFF5DB /* Debug */, 1159 | CD6A0E8D1EB7CE3A00FFF5DB /* Release */, 1160 | ); 1161 | defaultConfigurationIsVisible = 0; 1162 | defaultConfigurationName = Release; 1163 | }; 1164 | CD6A0E9C1EB7D36400FFF5DB /* Build configuration list for PBXAggregateTarget "RunAllTests" */ = { 1165 | isa = XCConfigurationList; 1166 | buildConfigurations = ( 1167 | CD6A0E9D1EB7D36400FFF5DB /* Debug */, 1168 | CD6A0E9E1EB7D36400FFF5DB /* Release */, 1169 | ); 1170 | defaultConfigurationIsVisible = 0; 1171 | defaultConfigurationName = Release; 1172 | }; 1173 | F15462991E56842400C3948D /* Build configuration list for PBXNativeTarget "Anchorage-macOS" */ = { 1174 | isa = XCConfigurationList; 1175 | buildConfigurations = ( 1176 | F15462971E56842400C3948D /* Debug */, 1177 | F15462981E56842400C3948D /* Release */, 1178 | ); 1179 | defaultConfigurationIsVisible = 0; 1180 | defaultConfigurationName = Release; 1181 | }; 1182 | /* End XCConfigurationList section */ 1183 | }; 1184 | rootObject = 3C2050A21D3B20FD00995DF3 /* Project object */; 1185 | } 1186 | -------------------------------------------------------------------------------- /Anchorage.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Anchorage.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Anchorage.xcodeproj/xcshareddata/xcschemes/Anchorage-iOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 34 | 40 | 41 | 42 | 43 | 44 | 50 | 51 | 52 | 53 | 54 | 55 | 65 | 66 | 72 | 73 | 74 | 75 | 76 | 77 | 83 | 84 | 90 | 91 | 92 | 93 | 95 | 96 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /Anchorage.xcodeproj/xcshareddata/xcschemes/Anchorage-macOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 34 | 40 | 41 | 42 | 43 | 44 | 50 | 51 | 52 | 53 | 54 | 55 | 65 | 66 | 72 | 73 | 74 | 75 | 76 | 77 | 83 | 84 | 90 | 91 | 92 | 93 | 95 | 96 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /Anchorage.xcodeproj/xcshareddata/xcschemes/Anchorage-tvOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 34 | 40 | 41 | 42 | 43 | 44 | 50 | 51 | 52 | 53 | 54 | 55 | 65 | 66 | 72 | 73 | 74 | 75 | 76 | 77 | 83 | 84 | 90 | 91 | 92 | 93 | 95 | 96 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /Anchorage.xcodeproj/xcshareddata/xcschemes/AnchorageDemo.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 64 | 66 | 72 | 73 | 74 | 75 | 76 | 77 | 83 | 85 | 91 | 92 | 93 | 94 | 96 | 97 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /Anchorage.xcodeproj/xcshareddata/xcschemes/RunAllTests.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 70 | 71 | 72 | 73 | 75 | 76 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /AnchorageDemo/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // AnchorageDemo 4 | // 5 | // Created by Connor Neville on 9/23/16. 6 | // Copyright © 2016 Rightpoint. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 17 | self.window = UIWindow(frame: UIScreen.main.bounds) 18 | self.window!.rootViewController = RootViewController() 19 | self.window!.backgroundColor = UIColor.white 20 | self.window!.makeKeyAndVisible() 21 | return true 22 | } 23 | 24 | func applicationWillResignActive(_ application: UIApplication) { 25 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 26 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 27 | } 28 | 29 | func applicationDidEnterBackground(_ application: UIApplication) { 30 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 31 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 32 | } 33 | 34 | func applicationWillEnterForeground(_ application: UIApplication) { 35 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 36 | } 37 | 38 | func applicationDidBecomeActive(_ application: UIApplication) { 39 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 40 | } 41 | 42 | func applicationWillTerminate(_ application: UIApplication) { 43 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /AnchorageDemo/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ios-marketing", 45 | "size" : "1024x1024", 46 | "scale" : "1x" 47 | } 48 | ], 49 | "info" : { 50 | "version" : 1, 51 | "author" : "xcode" 52 | } 53 | } -------------------------------------------------------------------------------- /AnchorageDemo/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /AnchorageDemo/Cells/AnimatableConstraintCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AnimatableConstraintCell.swift 3 | // Anchorage 4 | // 5 | // Created by Connor Neville on 9/26/16. 6 | // Copyright © 2016 Rightpoint. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import Anchorage 11 | 12 | class AnimatableConstraintCell: BaseCell { 13 | override class func reuseId() -> String { 14 | return "AnimatableConstraintCell" 15 | } 16 | 17 | let bodyLabel: UILabel = { 18 | let l = UILabel() 19 | l.text = "Constraints generated with Anchorage, just like any other constraints, can be animated by adjusting them and calling layoutIfNeeded inside an animation block. Tap to animate the below view across the screen." 20 | l.font = UIFont.systemFont(ofSize: 12.0) 21 | l.numberOfLines = 0 22 | return l 23 | }() 24 | 25 | let animatableView: UIView = { 26 | let v = UIView() 27 | v.backgroundColor = UIColor.black 28 | return v 29 | }() 30 | var animatableConstraint: NSLayoutConstraint? 31 | 32 | override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { 33 | super.init(style: style, reuseIdentifier: reuseIdentifier) 34 | configureView() 35 | configureLayout() 36 | } 37 | 38 | override func update(forDataSource dataSource: RootViewDataSource) { 39 | let newConstant = dataSource.animatableConstraintConstant 40 | // Just because we don't want to animate anything the first 41 | // time the cell loads. 42 | guard newConstant != 0 else { 43 | return 44 | } 45 | layoutIfNeeded() 46 | animatableConstraint?.constant = newConstant 47 | UIView.animate(withDuration: 0.5, animations: { 48 | // Animate the view's position change 49 | self.layoutIfNeeded() 50 | }, completion: { _ in 51 | self.animatableConstraint?.constant = 0 52 | UIView.animate(withDuration: 0.5, animations: { 53 | // Animate the view going back to its original position 54 | self.layoutIfNeeded() 55 | }) 56 | }) 57 | } 58 | } 59 | 60 | private extension AnimatableConstraintCell { 61 | func configureView() { 62 | contentView.addSubview(bodyLabel) 63 | contentView.addSubview(animatableView) 64 | } 65 | 66 | func configureLayout() { 67 | bodyLabel.topAnchor == contentView.topAnchor 68 | bodyLabel.horizontalAnchors == contentView.horizontalAnchors + 10 69 | 70 | animatableView.topAnchor == bodyLabel.bottomAnchor + 10 71 | animatableConstraint = animatableView.leadingAnchor == contentView.leadingAnchor 72 | animatableView.widthAnchor == 20.0 73 | animatableView.heightAnchor == 20.0 74 | animatableView.bottomAnchor == contentView.bottomAnchor 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /AnchorageDemo/Cells/BaseCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BaseCell.swift 3 | // AnchorageDemo 4 | // 5 | // Created by Connor Neville on 9/21/16. 6 | // Copyright © 2016 Connor Neville. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | 12 | class BaseCell: UITableViewCell { 13 | class func reuseId() -> String { 14 | return "BaseCell" 15 | } 16 | 17 | override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { 18 | super.init(style: style, reuseIdentifier: reuseIdentifier) 19 | } 20 | 21 | @available(*, unavailable) 22 | required init?(coder aDecoder: NSCoder) { 23 | fatalError("init(coder:) has not been implemented") 24 | } 25 | 26 | func update(forDataSource dataSource: RootViewDataSource) { } 27 | } 28 | -------------------------------------------------------------------------------- /AnchorageDemo/Cells/EdgeContainedLabelCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EdgeContainedLabelCell 3 | // AnchorageDemo 4 | // 5 | // Created by Connor Neville on 9/21/16. 6 | // Copyright © 2016 Connor Neville. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import Anchorage 11 | 12 | class EdgeContainedLabelCell: BaseCell { 13 | override class func reuseId() -> String { 14 | return "EdgeContainedCell" 15 | } 16 | 17 | let bodyLabel: UILabel = { 18 | let l = UILabel() 19 | l.text = "The edges of this UILabel are constrained to the edges of this cell's contentView, with 40pt padding on all sides. Tap to adjust the font size, and see the contentView adjust to meet the constraints." 20 | l.font = UIFont.systemFont(ofSize: 12.0) 21 | l.numberOfLines = 0 22 | return l 23 | }() 24 | 25 | override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { 26 | super.init(style: style, reuseIdentifier: reuseIdentifier) 27 | configureView() 28 | configureLayout() 29 | } 30 | 31 | override func update(forDataSource dataSource: RootViewDataSource) { 32 | // UILabel has an intrinsic content size based on its font size, so all we need to do 33 | // is change the font size, and auto layout handles its width/height. 34 | bodyLabel.font = UIFont.systemFont(ofSize: dataSource.edgeContainedLabelCellFontSize) 35 | } 36 | } 37 | 38 | private extension EdgeContainedLabelCell { 39 | func configureView() { 40 | contentView.addSubview(bodyLabel) 41 | } 42 | 43 | func configureLayout() { 44 | bodyLabel.edgeAnchors == contentView.edgeAnchors + 40 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /AnchorageDemo/Cells/EqualSpaceViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EqualSpaceViewCell.swift 3 | // AnchorageDemo 4 | // 5 | // Created by Connor Neville on 9/21/16. 6 | // Copyright © 2016 Connor Neville. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import Anchorage 11 | 12 | class EqualSpaceViewCell: BaseCell { 13 | override class func reuseId() -> String { 14 | return "EqualSpaceViewCell" 15 | } 16 | 17 | let bodyLabel: UILabel = { 18 | let l = UILabel() 19 | l.text = "These views take up the width of the cell by pinning to its leading, trailing, and having a constant space in between. Tap to adjust the space in between." 20 | l.font = UIFont.systemFont(ofSize: 12.0) 21 | l.numberOfLines = 0 22 | return l 23 | }() 24 | 25 | let views: [UIView] = { 26 | var views: [UIView] = [] 27 | for i in 0...5 { 28 | let view = UIView() 29 | view.backgroundColor = (i % 2 == 0) ? UIColor.green : UIColor.cyan 30 | views.append(view) 31 | } 32 | return views 33 | }() 34 | // Here we have an array of constraints that we'll alter later. 35 | var spacingConstraints: [NSLayoutConstraint] = [] 36 | 37 | override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { 38 | super.init(style: style, reuseIdentifier: reuseIdentifier) 39 | configureView() 40 | configureLayout() 41 | } 42 | 43 | override func update(forDataSource dataSource: RootViewDataSource) { 44 | for constraint in spacingConstraints { 45 | constraint.constant = dataSource.equalSpacingConstraintConstant 46 | } 47 | layoutIfNeeded() 48 | } 49 | } 50 | 51 | private extension EqualSpaceViewCell { 52 | func configureView() { 53 | contentView.addSubview(bodyLabel) 54 | for view in views { 55 | contentView.addSubview(view) 56 | } 57 | } 58 | 59 | func configureLayout() { 60 | bodyLabel.topAnchor == contentView.topAnchor 61 | bodyLabel.horizontalAnchors == contentView.horizontalAnchors + 10 62 | 63 | guard let first = views.first, let last = views.last else { 64 | preconditionFailure("Empty views array in EqualSpaceViewCell") 65 | } 66 | 67 | first.leadingAnchor == contentView.leadingAnchor 68 | first.topAnchor == bodyLabel.bottomAnchor + 5 69 | first.heightAnchor == 30 70 | first.bottomAnchor == contentView.bottomAnchor 71 | 72 | for i in 1.. String { 14 | return "MinimumWidthViewCell" 15 | } 16 | 17 | let bodyLabel: UILabel = { 18 | let l = UILabel() 19 | l.text = "The red view will have 50% of the width of the blue view, but won't go above 100 pt, because the " + 20 | "constant requirement has a higher priority. Tap to expand the blue view." 21 | l.font = UIFont.systemFont(ofSize: 12.0) 22 | l.numberOfLines = 0 23 | return l 24 | }() 25 | 26 | let blueView: UIView = { 27 | let v = UIView() 28 | v.backgroundColor = UIColor.blue 29 | return v 30 | }() 31 | // If you want to change or replace a constraint later, it's a good idea to keep a reference to it. 32 | var blueWidthConstraint: NSLayoutConstraint? 33 | 34 | let redView: UIView = { 35 | let v = UIView() 36 | v.backgroundColor = UIColor.red 37 | return v 38 | }() 39 | 40 | override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { 41 | super.init(style: style, reuseIdentifier: reuseIdentifier) 42 | configureView() 43 | configureLayout() 44 | } 45 | 46 | override func update(forDataSource dataSource: RootViewDataSource) { 47 | blueWidthConstraint?.constant = dataSource.minimumWidthConstraintConstant 48 | layoutIfNeeded() 49 | } 50 | } 51 | 52 | private extension MinimumWidthViewCell { 53 | func configureView() { 54 | contentView.addSubview(bodyLabel) 55 | contentView.addSubview(blueView) 56 | contentView.addSubview(redView) 57 | } 58 | 59 | func configureLayout() { 60 | bodyLabel.topAnchor == contentView.topAnchor + 10 61 | bodyLabel.horizontalAnchors == contentView.horizontalAnchors + 10 62 | 63 | blueWidthConstraint = (blueView.widthAnchor == 100) 64 | blueView.centerXAnchor == centerXAnchor 65 | blueView.topAnchor == bodyLabel.bottomAnchor + 5 66 | blueView.heightAnchor == 10 67 | 68 | // We have 2 constraints that dictate the height of the red view. Auto layout tries to 69 | // satisfy both if possible, but if not, it'll satisfy the higher priority one. 70 | redView.widthAnchor == blueView.widthAnchor * 0.5 ~ .low + 1 71 | redView.widthAnchor <= 100 ~ .high 72 | 73 | redView.heightAnchor == 10 74 | redView.centerXAnchor == centerXAnchor 75 | redView.topAnchor == blueView.bottomAnchor + 5 76 | redView.bottomAnchor == contentView.bottomAnchor 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /AnchorageDemo/Cells/ToggleActiveHeightCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ToggleActiveHeightCell.swift 3 | // AnchorageDemo 4 | // 5 | // Created by Connor Neville on 9/21/16. 6 | // Copyright © 2016 Connor Neville. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import Anchorage 11 | 12 | class ToggleActiveHeightCell: BaseCell { 13 | override class func reuseId() -> String { 14 | return "ToggleActiveHeightCell" 15 | } 16 | 17 | let bodyLabel: UILabel = { 18 | let l = UILabel() 19 | l.text = "Each view below takes up 50% of the width of the cell. The left view has a constant height, and the right view, initially, has the same height. Tap to toggle the right view's height constraint's isActive property." 20 | l.font = UIFont.systemFont(ofSize: 12.0) 21 | l.numberOfLines = 0 22 | return l 23 | }() 24 | 25 | let leftView: UIView = { 26 | let v = UIView() 27 | v.backgroundColor = UIColor.purple 28 | return v 29 | }() 30 | 31 | let rightView: UIView = { 32 | let v = UIView() 33 | v.backgroundColor = UIColor.orange 34 | return v 35 | }() 36 | // If you want to change or replace a constraint later, it's a good idea to keep a reference to it. 37 | var rightHeightConstraint: NSLayoutConstraint? 38 | 39 | override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { 40 | super.init(style: style, reuseIdentifier: reuseIdentifier) 41 | configureView() 42 | configureLayout() 43 | } 44 | 45 | override func update(forDataSource dataSource: RootViewDataSource) { 46 | // You can disable a constraint by setting isActive = false. If you replace an active constraint 47 | // with an entirely new one, the old one will still be active, so do this first to avoid 48 | // unintentional layout conflicts! 49 | rightHeightConstraint?.isActive = dataSource.toggleHeightConstraintIsActive 50 | layoutIfNeeded() 51 | } 52 | } 53 | 54 | private extension ToggleActiveHeightCell { 55 | func configureView() { 56 | contentView.addSubview(bodyLabel) 57 | contentView.addSubview(leftView) 58 | contentView.addSubview(rightView) 59 | } 60 | 61 | func configureLayout() { 62 | bodyLabel.topAnchor == contentView.topAnchor 63 | bodyLabel.horizontalAnchors == contentView.horizontalAnchors + 10 64 | 65 | leftView.leftAnchor == contentView.leftAnchor 66 | leftView.rightAnchor == contentView.centerXAnchor 67 | leftView.topAnchor == bodyLabel.bottomAnchor + 5 68 | leftView.heightAnchor == 30 69 | leftView.bottomAnchor == contentView.bottomAnchor 70 | 71 | rightView.leftAnchor == contentView.centerXAnchor 72 | rightView.rightAnchor == contentView.rightAnchor 73 | rightView.topAnchor == leftView.topAnchor 74 | // When we set this to inactive, there is no specification for this view's height, so it is zero. 75 | rightHeightConstraint = (rightView.heightAnchor == leftView.heightAnchor) 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /AnchorageDemo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIRequiredDeviceCapabilities 26 | 27 | armv7 28 | 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /AnchorageDemo/RootViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RootViewController.swift 3 | // AnchorageDemo 4 | // 5 | // Created by Connor Neville on 9/21/16. 6 | // Copyright © 2016 Connor Neville. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | 12 | class RootViewController: UITableViewController { 13 | let cellTypes: [BaseCell.Type] = [ 14 | EdgeContainedLabelCell.self, 15 | MinimumWidthViewCell.self, 16 | ToggleActiveHeightCell.self, 17 | EqualSpaceViewCell.self, 18 | AnimatableConstraintCell.self 19 | ] 20 | let dataSource = RootViewDataSource() 21 | 22 | override func viewDidLoad() { 23 | super.viewDidLoad() 24 | tableView.estimatedRowHeight = 120 25 | tableView.rowHeight = UITableView.automaticDimension 26 | for cellType in cellTypes { 27 | tableView.register(cellType, forCellReuseIdentifier: cellType.reuseId()) 28 | } 29 | } 30 | 31 | override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 32 | return cellTypes.count 33 | } 34 | 35 | override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 36 | let cellType = cellTypes[indexPath.row] 37 | guard let cell = tableView.dequeueReusableCell(withIdentifier: cellType.reuseId()) as? BaseCell else { 38 | preconditionFailure("Cell missing for reuse ID \(cellType.reuseId())") 39 | } 40 | cell.update(forDataSource: dataSource) 41 | return cell 42 | } 43 | 44 | override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 45 | switch cellTypes[indexPath.row] { 46 | case is EdgeContainedLabelCell.Type: 47 | dataSource.edgeContainedLabelCellFontSize += 4.0 48 | if dataSource.edgeContainedLabelCellFontSize >= 24.0 { 49 | dataSource.edgeContainedLabelCellFontSize = 12.0 50 | } 51 | case is MinimumWidthViewCell.Type: 52 | dataSource.minimumWidthConstraintConstant += 40 53 | case is ToggleActiveHeightCell.Type: 54 | dataSource.toggleHeightConstraintIsActive = !dataSource.toggleHeightConstraintIsActive 55 | case is EqualSpaceViewCell.Type: 56 | dataSource.equalSpacingConstraintConstant = (dataSource.equalSpacingConstraintConstant == 0) ? 57 | 10.0 : 0.0 58 | case is AnimatableConstraintCell.Type: 59 | dataSource.animatableConstraintConstant = 200.0 60 | default: 61 | break 62 | } 63 | tableView.reloadRows(at: [indexPath], with: .automatic) 64 | } 65 | } 66 | 67 | class RootViewDataSource { 68 | var edgeContainedLabelCellFontSize: CGFloat = 12.0 69 | var minimumWidthConstraintConstant: CGFloat = 100.0 70 | var toggleHeightConstraintIsActive: Bool = true 71 | var equalSpacingConstraintConstant: CGFloat = 0.0 72 | var animatableConstraintConstant: CGFloat = 0.0 73 | } 74 | -------------------------------------------------------------------------------- /AnchorageTests/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 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem 'cocoapods' 4 | gem 'xcpretty' 5 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | CFPropertyList (3.0.2) 5 | activesupport (5.2.4.4) 6 | concurrent-ruby (~> 1.0, >= 1.0.2) 7 | i18n (>= 0.7, < 2) 8 | minitest (~> 5.1) 9 | tzinfo (~> 1.1) 10 | addressable (2.7.0) 11 | public_suffix (>= 2.0.2, < 5.0) 12 | algoliasearch (1.27.5) 13 | httpclient (~> 2.8, >= 2.8.3) 14 | json (>= 1.5.1) 15 | atomos (0.1.3) 16 | claide (1.0.3) 17 | cocoapods (1.10.0) 18 | addressable (~> 2.6) 19 | claide (>= 1.0.2, < 2.0) 20 | cocoapods-core (= 1.10.0) 21 | cocoapods-deintegrate (>= 1.0.3, < 2.0) 22 | cocoapods-downloader (>= 1.4.0, < 2.0) 23 | cocoapods-plugins (>= 1.0.0, < 2.0) 24 | cocoapods-search (>= 1.0.0, < 2.0) 25 | cocoapods-trunk (>= 1.4.0, < 2.0) 26 | cocoapods-try (>= 1.1.0, < 2.0) 27 | colored2 (~> 3.1) 28 | escape (~> 0.0.4) 29 | fourflusher (>= 2.3.0, < 3.0) 30 | gh_inspector (~> 1.0) 31 | molinillo (~> 0.6.6) 32 | nap (~> 1.0) 33 | ruby-macho (~> 1.4) 34 | xcodeproj (>= 1.19.0, < 2.0) 35 | cocoapods-core (1.10.0) 36 | activesupport (> 5.0, < 6) 37 | addressable (~> 2.6) 38 | algoliasearch (~> 1.0) 39 | concurrent-ruby (~> 1.1) 40 | fuzzy_match (~> 2.0.4) 41 | nap (~> 1.0) 42 | netrc (~> 0.11) 43 | public_suffix 44 | typhoeus (~> 1.0) 45 | cocoapods-deintegrate (1.0.4) 46 | cocoapods-downloader (1.4.0) 47 | cocoapods-plugins (1.0.0) 48 | nap 49 | cocoapods-search (1.0.0) 50 | cocoapods-trunk (1.5.0) 51 | nap (>= 0.8, < 2.0) 52 | netrc (~> 0.11) 53 | cocoapods-try (1.2.0) 54 | colored2 (3.1.2) 55 | concurrent-ruby (1.1.7) 56 | escape (0.0.4) 57 | ethon (0.12.0) 58 | ffi (>= 1.3.0) 59 | ffi (1.13.1) 60 | fourflusher (2.3.1) 61 | fuzzy_match (2.0.4) 62 | gh_inspector (1.1.3) 63 | httpclient (2.8.3) 64 | i18n (1.8.5) 65 | concurrent-ruby (~> 1.0) 66 | json (2.3.1) 67 | minitest (5.14.2) 68 | molinillo (0.6.6) 69 | nanaimo (0.3.0) 70 | nap (1.1.0) 71 | netrc (0.11.0) 72 | public_suffix (4.0.6) 73 | rouge (2.0.7) 74 | ruby-macho (1.4.0) 75 | thread_safe (0.3.6) 76 | typhoeus (1.4.0) 77 | ethon (>= 0.9.0) 78 | tzinfo (1.2.7) 79 | thread_safe (~> 0.1) 80 | xcodeproj (1.19.0) 81 | CFPropertyList (>= 2.3.3, < 4.0) 82 | atomos (~> 0.1.3) 83 | claide (>= 1.0.2, < 2.0) 84 | colored2 (~> 3.1) 85 | nanaimo (~> 0.3.0) 86 | xcpretty (0.3.0) 87 | rouge (~> 2.0.7) 88 | 89 | PLATFORMS 90 | ruby 91 | 92 | DEPENDENCIES 93 | cocoapods 94 | xcpretty 95 | 96 | BUNDLED WITH 97 | 2.1.4 98 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Rightpoint 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.1 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "Anchorage", 8 | platforms: [ 9 | .iOS(.v9), 10 | .macOS(.v10_11), 11 | .tvOS(.v9), 12 | ], 13 | products: [ 14 | .library( 15 | name: "Anchorage", 16 | targets: ["Anchorage"]), 17 | ], 18 | targets: [ 19 | .target( 20 | name: "Anchorage", 21 | dependencies: [], 22 | path: "Source"), 23 | .testTarget( 24 | name: "AnchorageTests", 25 | dependencies: ["Anchorage"], 26 | path: "AnchorageTests"), 27 | ] 28 | ) 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Anchorage 2 | 3 | [![Swift 4.2 + 5.0](https://img.shields.io/badge/Swift-4.2%20+%205.0-orange.svg?style=flat)](https://swift.org) 4 | [![CircleCI](https://img.shields.io/circleci/project/github/Rightpoint/Anchorage/master.svg)](https://circleci.com/gh/Rightpoint/Anchorage) 5 | [![Version](https://img.shields.io/cocoapods/v/Anchorage.svg?style=flat)](https://cocoadocs.org/docsets/Anchorage) 6 | [![Platform](https://img.shields.io/cocoapods/p/Anchorage.svg?style=flat)](http://cocoapods.org/pods/Anchorage) 7 | [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) 8 | 9 | A lightweight collection of intuitive operators and utilities that simplify Auto Layout code. Anchorage is built directly on top of the `NSLayoutAnchor` API. 10 | 11 | Each expression acts on one or more `NSLayoutAnchor`s, and returns active `NSLayoutConstraint`s. If you want inactive constraints, [here's how to do that](#batching-constraints). 12 | 13 | # Usage 14 | 15 | ## Alignment 16 | 17 | ```swift 18 | // Pin the button to 12 pt from the leading edge of its container 19 | button.leadingAnchor == container.leadingAnchor + 12 20 | 21 | // Pin the button to at least 12 pt from the trailing edge of its container 22 | button.trailingAnchor <= container.trailingAnchor - 12 23 | 24 | // Center one or both axes of a view 25 | button.centerXAnchor == container.centerXAnchor 26 | button.centerAnchors == container.centerAnchors 27 | ``` 28 | 29 | ## Relative Alignment 30 | 31 | ```swift 32 | // Position a view to be centered at 2/3 of its container's width 33 | view.centerXAnchor == 2 * container.trailingAnchor / 3 34 | 35 | // Pin the top of a view at 25% of container's height 36 | view.topAnchor == container.bottomAnchor / 4 37 | ``` 38 | 39 | ## Sizing 40 | 41 | ```swift 42 | // Constrain a view's width to be at most 100 pt 43 | view.widthAnchor <= 100 44 | 45 | // Constraint a view to a fixed size 46 | imageView.sizeAnchors == CGSize(width: 100, height: 200) 47 | 48 | // Constrain two views to be the same size 49 | imageView.sizeAnchors == view.sizeAnchors 50 | 51 | // Constrain view to 4:3 aspect ratio 52 | view.widthAnchor == 4 * view.heightAnchor / 3 53 | ``` 54 | 55 | ## Composite Anchors 56 | 57 | Constrain multiple edges at a time with this syntax: 58 | 59 | ```swift 60 | // Constrain the leading, trailing, top and bottom edges to be equal 61 | imageView.edgeAnchors == container.edgeAnchors 62 | 63 | // Inset the edges of a view from another view 64 | let insets = UIEdgeInsets(top: 5, left: 10, bottom: 15, right: 20) 65 | imageView.edgeAnchors == container.edgeAnchors + insets 66 | 67 | // Inset the leading and trailing anchors by 10 68 | imageView.horizontalAnchors >= container.horizontalAnchors + 10 69 | 70 | // Inset the top and bottom anchors by 10 71 | imageView.verticalAnchors >= container.verticalAnchors + 10 72 | ``` 73 | 74 | #### Use leading and trailing 75 | Using `leftAnchor` and `rightAnchor` is rarely the right choice. To encourage this, `horizontalAnchors` and `edgeAnchors` use the `leadingAnchor` and `trailingAnchor` layout anchors. 76 | 77 | #### Inset instead of Shift 78 | When constraining leading/trailing or top/bottom, it is far more common to work in terms of an inset from the edges instead of shifting both edges in the same direction. When building the expression, Anchorage will flip the relationship and invert the constant in the constraint on the far side of the axis. This makes the expressions much more natural to work with. 79 | 80 | 81 | ## Priority 82 | 83 | The `~` is used to specify priority of the constraint resulting from any Anchorage expression: 84 | 85 | ```swift 86 | // Align view 20 points from the center of its superview, with system-defined low priority 87 | view.centerXAnchor == view.superview.centerXAnchor + 20 ~ .low 88 | 89 | // Align view 20 points from the center of its superview, with (required - 1) priority 90 | view.centerXAnchor == view.superview.centerXAnchor + 20 ~ .required - 1 91 | 92 | // Align view 20 points from the center of its superview, with custom priority 93 | view.centerXAnchor == view.superview.centerXAnchor + 20 ~ 752 94 | ``` 95 | The layout priority is an enum with the following values: 96 | 97 | - `.required` - `UILayoutPriorityRequired` (default) 98 | - `.high` - `UILayoutPriorityDefaultHigh` 99 | - `.low` - `UILayoutPriorityDefaultLow` 100 | - `.fittingSize` - `UILayoutPriorityFittingSizeLevel` 101 | 102 | ## Storing Constraints 103 | 104 | To store constraints created by Anchorage, simply assign the expression to a variable: 105 | 106 | ```swift 107 | // A single (active) NSLayoutConstraint 108 | let topConstraint = (imageView.topAnchor == container.topAnchor) 109 | 110 | // EdgeConstraints represents a collection of constraints 111 | // You can retrieve the NSLayoutConstraints individually, 112 | // or get an [NSLayoutConstraint] via .all, .horizontal, or .vertical 113 | let edgeConstraints = (button.edgeAnchors == container.edgeAnchors).all 114 | ``` 115 | 116 | ## Batching Constraints 117 | 118 | By default, Anchorage returns active layout constraints. If you'd rather return inactive constraints for use with the [`NSLayoutConstraint.activate(_:)` method](https://developer.apple.com/reference/uikit/nslayoutconstraint/1526955-activate) for performance reasons, you can do it like this: 119 | 120 | ```swift 121 | let constraints = Anchorage.batch(active: false) { 122 | view1.widthAnchor == view2.widthAnchor 123 | view1.heightAnchor == view2.heightAnchor / 2 ~ .low 124 | // ... as many constraints as you want 125 | } 126 | 127 | // Later: 128 | NSLayoutConstraint.activate(constraints) 129 | ``` 130 | 131 | You can also pass `active: true` if you want the constraints in the array to be automatically activated in a batch. 132 | 133 | ## Autoresizing Mask 134 | 135 | Anchorage sets the `translatesAutoresizingMaskIntoConstraints` property to `false` on the *left* hand side of the expression, so you should never need to set this property manually. This is important to be aware of in case the container view relies on `translatesAutoresizingMaskIntoConstraints` being set to `true`. We tend to keep child views on the left hand side of the expression to avoid this problem, especially when constraining to a system-supplied view. 136 | 137 | ## A Note on Compile Times 138 | 139 | Anchorage overloads a few Swift operators, which can lead to increased compile times. You can reduce this overhead by surrounding these operators with `/`, like so: 140 | 141 | | Operator | Faster Alternative | 142 | |------|----------| 143 | | `==` | `/==/` | 144 | | `<=` | `/<=/` | 145 | | `>=` | `/>=/` | 146 | 147 | For example, `view1.edgeAnchors == view2.edgeAnchors` would become `view1.edgeAnchors /==/ view2.edgeAnchors`. 148 | 149 | # Installation 150 | 151 | ## CocoaPods 152 | 153 | To integrate Anchorage into your Xcode project using CocoaPods, specify it in 154 | your Podfile: 155 | 156 | ```ruby 157 | pod 'Anchorage' 158 | ``` 159 | 160 | ## Carthage 161 | 162 | To integrate Anchorage into your Xcode project using Carthage, specify it in 163 | your Cartfile: 164 | 165 | ```ogdl 166 | github "Rightpoint/Anchorage" 167 | ``` 168 | 169 | Run `carthage update` to build the framework and drag the built 170 | `Anchorage.framework` into your Xcode project. 171 | 172 | # License 173 | 174 | This code and tool is under the MIT License. See `LICENSE` file in this repository. 175 | 176 | Any ideas and contributions welcome! 177 | -------------------------------------------------------------------------------- /Source/AnchorGroupProvider.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AnchorGroupProvider.swift 3 | // Anchorage 4 | // 5 | // Created by Rob Visentin on 5/1/17. 6 | // 7 | // Copyright 2016 Rightpoint and other contributors 8 | // http://rightpoint.com/ 9 | // 10 | // Permission is hereby granted, free of charge, to any person obtaining 11 | // a copy of this software and associated documentation files (the 12 | // Software"), to deal in the Software without restriction, including 13 | // without limitation the rights to use, copy, modify, merge, publish, 14 | // distribute, sublicense, and/or sell copies of the Software, and to 15 | // permit persons to whom the Software is furnished to do so, subject to 16 | // the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be 19 | // included in all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 22 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 23 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 24 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 25 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 26 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 27 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28 | 29 | #if os(macOS) 30 | import Cocoa 31 | #else 32 | import UIKit 33 | #endif 34 | 35 | public protocol AnchorGroupProvider { 36 | 37 | var horizontalAnchors: AnchorPair { get } 38 | var verticalAnchors: AnchorPair { get } 39 | var centerAnchors: AnchorPair { get } 40 | var sizeAnchors: AnchorPair { get } 41 | 42 | } 43 | 44 | extension AnchorGroupProvider { 45 | 46 | public var edgeAnchors: EdgeAnchors { 47 | return EdgeAnchors(horizontal: horizontalAnchors, vertical: verticalAnchors) 48 | } 49 | 50 | } 51 | 52 | extension View: AnchorGroupProvider { 53 | 54 | public var horizontalAnchors: AnchorPair { 55 | return AnchorPair(first: leadingAnchor, second: trailingAnchor) 56 | } 57 | 58 | public var verticalAnchors: AnchorPair { 59 | return AnchorPair(first: topAnchor, second: bottomAnchor) 60 | } 61 | 62 | public var centerAnchors: AnchorPair { 63 | return AnchorPair(first: centerXAnchor, second: centerYAnchor) 64 | } 65 | 66 | public var sizeAnchors: AnchorPair { 67 | return AnchorPair(first: widthAnchor, second: heightAnchor) 68 | } 69 | 70 | } 71 | 72 | extension ViewController: AnchorGroupProvider { 73 | 74 | @available(*, deprecated, message: "Do not set constraints directly on a UIViewController; set them on its root UIView.") 75 | public var horizontalAnchors: AnchorPair { 76 | return view.horizontalAnchors 77 | } 78 | 79 | @available(*, deprecated, message: "Do not set constraints directly on a UIViewController; set them on its root UIView.") 80 | public var verticalAnchors: AnchorPair { 81 | #if os(macOS) 82 | return view.verticalAnchors 83 | #else 84 | return AnchorPair(first: topLayoutGuide.bottomAnchor, second: bottomLayoutGuide.topAnchor) 85 | #endif 86 | } 87 | 88 | @available(*, deprecated, message: "Do not set constraints directly on a UIViewController; set them on its root UIView.") 89 | public var centerAnchors: AnchorPair { 90 | return view.centerAnchors 91 | } 92 | 93 | @available(*, deprecated, message: "Do not set constraints directly on a UIViewController; set them on its root UIView.") 94 | public var sizeAnchors: AnchorPair { 95 | return view.sizeAnchors 96 | } 97 | 98 | } 99 | 100 | extension LayoutGuide: AnchorGroupProvider { 101 | 102 | public var horizontalAnchors: AnchorPair { 103 | return AnchorPair(first: leadingAnchor, second: trailingAnchor) 104 | } 105 | 106 | public var verticalAnchors: AnchorPair { 107 | return AnchorPair(first: topAnchor, second: bottomAnchor) 108 | } 109 | 110 | public var centerAnchors: AnchorPair { 111 | return AnchorPair(first: centerXAnchor, second: centerYAnchor) 112 | } 113 | 114 | public var sizeAnchors: AnchorPair { 115 | return AnchorPair(first: widthAnchor, second: heightAnchor) 116 | } 117 | 118 | } 119 | 120 | // MARK: - EdgeAnchors 121 | 122 | public struct EdgeAnchors: LayoutAnchorType { 123 | 124 | public var horizontalAnchors: AnchorPair 125 | public var verticalAnchors: AnchorPair 126 | 127 | } 128 | 129 | // MARK: - Axis Group 130 | 131 | public struct ConstraintPair { 132 | 133 | public var first: NSLayoutConstraint 134 | public var second: NSLayoutConstraint 135 | 136 | } 137 | 138 | // MARK: - ConstraintGroup 139 | 140 | public struct ConstraintGroup { 141 | 142 | public var top: NSLayoutConstraint 143 | public var leading: NSLayoutConstraint 144 | public var bottom: NSLayoutConstraint 145 | public var trailing: NSLayoutConstraint 146 | 147 | public var horizontal: [NSLayoutConstraint] { 148 | return [leading, trailing] 149 | } 150 | 151 | public var vertical: [NSLayoutConstraint] { 152 | return [top, bottom] 153 | } 154 | 155 | public var all: [NSLayoutConstraint] { 156 | return [top, leading, bottom, trailing] 157 | } 158 | 159 | } 160 | -------------------------------------------------------------------------------- /Source/Anchorage.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Anchorage.swift 3 | // Anchorage 4 | // 5 | // Created by Rob Visentin on 2/6/16. 6 | // 7 | // Copyright 2016 Rightpoint and other contributors 8 | // http://rightpoint.com/ 9 | // 10 | // Permission is hereby granted, free of charge, to any person obtaining 11 | // a copy of this software and associated documentation files (the 12 | // Software"), to deal in the Software without restriction, including 13 | // without limitation the rights to use, copy, modify, merge, publish, 14 | // distribute, sublicense, and/or sell copies of the Software, and to 15 | // permit persons to whom the Software is furnished to do so, subject to 16 | // the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be 19 | // included in all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 22 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 23 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 24 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 25 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 26 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 27 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28 | 29 | #if os(macOS) 30 | import Cocoa 31 | #else 32 | import UIKit 33 | #endif 34 | 35 | public protocol LayoutConstantType {} 36 | extension CGFloat: LayoutConstantType {} 37 | extension CGSize: LayoutConstantType {} 38 | extension EdgeInsets: LayoutConstantType {} 39 | 40 | public protocol LayoutAnchorType {} 41 | extension NSLayoutAnchor: LayoutAnchorType {} 42 | 43 | // MARK: - Equality Constraints 44 | 45 | infix operator /==/: ComparisonPrecedence 46 | 47 | @discardableResult public func == (lhs: NSLayoutDimension, rhs: T) -> NSLayoutConstraint { 48 | return lhs /==/ rhs 49 | } 50 | 51 | @discardableResult public func /==/ (lhs: NSLayoutDimension, rhs: T) -> NSLayoutConstraint { 52 | return finalize(constraint: lhs.constraint(equalToConstant: CGFloat(rhs))) 53 | } 54 | 55 | @discardableResult public func == (lhs: NSLayoutXAxisAnchor, rhs: NSLayoutXAxisAnchor) -> NSLayoutConstraint { 56 | return lhs /==/ rhs 57 | } 58 | 59 | @discardableResult public func /==/ (lhs: NSLayoutXAxisAnchor, rhs: NSLayoutXAxisAnchor) -> NSLayoutConstraint { 60 | return finalize(constraint: lhs.constraint(equalTo: rhs)) 61 | } 62 | 63 | @discardableResult public func == (lhs: NSLayoutYAxisAnchor, rhs: NSLayoutYAxisAnchor) -> NSLayoutConstraint { 64 | return lhs /==/ rhs 65 | } 66 | 67 | @discardableResult public func /==/ (lhs: NSLayoutYAxisAnchor, rhs: NSLayoutYAxisAnchor) -> NSLayoutConstraint { 68 | return finalize(constraint: lhs.constraint(equalTo: rhs)) 69 | } 70 | 71 | @discardableResult public func == (lhs: NSLayoutDimension, rhs: NSLayoutDimension) -> NSLayoutConstraint { 72 | return lhs /==/ rhs 73 | } 74 | 75 | @discardableResult public func /==/ (lhs: NSLayoutDimension, rhs: NSLayoutDimension) -> NSLayoutConstraint { 76 | return finalize(constraint: lhs.constraint(equalTo: rhs)) 77 | } 78 | 79 | @discardableResult public func == (lhs: NSLayoutXAxisAnchor, rhs: LayoutExpression) -> NSLayoutConstraint { 80 | return lhs /==/ rhs 81 | } 82 | 83 | @discardableResult public func /==/ (lhs: NSLayoutXAxisAnchor, rhs: LayoutExpression) -> NSLayoutConstraint { 84 | return finalize(constraint: lhs.constraint(equalTo: rhs.anchor!, multiplier: rhs.multiplier, constant: rhs.constant), withPriority: rhs.priority) 85 | } 86 | 87 | @discardableResult public func == (lhs: NSLayoutYAxisAnchor, rhs: LayoutExpression) -> NSLayoutConstraint { 88 | return lhs /==/ rhs 89 | } 90 | 91 | @discardableResult public func /==/ (lhs: NSLayoutYAxisAnchor, rhs: LayoutExpression) -> NSLayoutConstraint { 92 | return finalize(constraint: lhs.constraint(equalTo: rhs.anchor!, multiplier: rhs.multiplier, constant: rhs.constant), withPriority: rhs.priority) 93 | } 94 | 95 | @discardableResult public func == (lhs: NSLayoutDimension, rhs: LayoutExpression) -> NSLayoutConstraint { 96 | return lhs /==/ rhs 97 | } 98 | 99 | @discardableResult public func /==/ (lhs: NSLayoutDimension, rhs: LayoutExpression) -> NSLayoutConstraint { 100 | if let anchor = rhs.anchor { 101 | return finalize(constraint: lhs.constraint(equalTo: anchor, multiplier: rhs.multiplier, constant: rhs.constant), withPriority: rhs.priority) 102 | } 103 | else { 104 | return finalize(constraint: lhs.constraint(equalToConstant: rhs.constant), withPriority: rhs.priority) 105 | } 106 | } 107 | 108 | @discardableResult public func == (lhs: EdgeAnchors, rhs: EdgeAnchors) -> ConstraintGroup { 109 | return lhs /==/ rhs 110 | } 111 | 112 | @discardableResult public func /==/ (lhs: EdgeAnchors, rhs: EdgeAnchors) -> ConstraintGroup { 113 | return lhs.finalize(constraintsEqualToEdges: rhs) 114 | } 115 | 116 | @discardableResult public func == (lhs: EdgeAnchors, rhs: LayoutExpression) -> ConstraintGroup { 117 | return lhs /==/ rhs 118 | } 119 | 120 | @discardableResult public func /==/ (lhs: EdgeAnchors, rhs: LayoutExpression) -> ConstraintGroup { 121 | return lhs.finalize(constraintsEqualToEdges: rhs.anchor, constant: rhs.constant, priority: rhs.priority) 122 | } 123 | 124 | @discardableResult public func == (lhs: EdgeAnchors, rhs: LayoutExpression) -> ConstraintGroup { 125 | return lhs /==/ rhs 126 | } 127 | 128 | @discardableResult public func /==/ (lhs: EdgeAnchors, rhs: LayoutExpression) -> ConstraintGroup { 129 | return lhs.finalize(constraintsEqualToEdges: rhs.anchor, insets: rhs.constant, priority: rhs.priority) 130 | } 131 | 132 | @discardableResult public func == (lhs: AnchorPair, rhs: AnchorPair) -> ConstraintPair { 133 | return lhs /==/ rhs 134 | } 135 | 136 | @discardableResult public func /==/ (lhs: AnchorPair, rhs: AnchorPair) -> ConstraintPair { 137 | return lhs.finalize(constraintsEqualToEdges: rhs) 138 | } 139 | 140 | @discardableResult public func == (lhs: AnchorPair, rhs: LayoutExpression, CGFloat>) -> ConstraintPair { 141 | return lhs /==/ rhs 142 | } 143 | 144 | @discardableResult public func /==/ (lhs: AnchorPair, rhs: LayoutExpression, CGFloat>) -> ConstraintPair { 145 | return lhs.finalize(constraintsEqualToEdges: rhs.anchor, constant: rhs.constant, priority: rhs.priority) 146 | } 147 | 148 | @discardableResult public func == (lhs: AnchorPair, rhs: CGSize) -> ConstraintPair { 149 | return lhs /==/ rhs 150 | } 151 | 152 | @discardableResult public func /==/ (lhs: AnchorPair, rhs: CGSize) -> ConstraintPair { 153 | return lhs.finalize(constraintsEqualToConstant: rhs) 154 | } 155 | 156 | @discardableResult public func == (lhs: AnchorPair, rhs: LayoutExpression, CGSize>) -> ConstraintPair { 157 | return lhs /==/ rhs 158 | } 159 | 160 | @discardableResult public func /==/ (lhs: AnchorPair, rhs: LayoutExpression, CGSize>) -> ConstraintPair { 161 | return lhs.finalize(constraintsEqualToConstant: rhs.constant, priority: rhs.priority) 162 | } 163 | 164 | // MARK: - Inequality Constraints 165 | 166 | // MARK: Less Than or Equal To 167 | 168 | infix operator /<=/: ComparisonPrecedence 169 | 170 | @discardableResult public func <= (lhs: NSLayoutDimension, rhs: T) -> NSLayoutConstraint { 171 | return lhs /<=/ rhs 172 | } 173 | 174 | @discardableResult public func /<=/ (lhs: NSLayoutDimension, rhs: T) -> NSLayoutConstraint { 175 | return finalize(constraint: lhs.constraint(lessThanOrEqualToConstant: CGFloat(rhs))) 176 | } 177 | 178 | @discardableResult public func <= (lhs: NSLayoutXAxisAnchor, rhs: NSLayoutXAxisAnchor) -> NSLayoutConstraint { 179 | return lhs /<=/ rhs 180 | } 181 | 182 | @discardableResult public func /<=/ (lhs: NSLayoutXAxisAnchor, rhs: NSLayoutXAxisAnchor) -> NSLayoutConstraint { 183 | return finalize(constraint: lhs.constraint(lessThanOrEqualTo: rhs)) 184 | } 185 | 186 | @discardableResult public func <= (lhs: NSLayoutYAxisAnchor, rhs: NSLayoutYAxisAnchor) -> NSLayoutConstraint { 187 | return lhs /<=/ rhs 188 | } 189 | 190 | @discardableResult public func /<=/ (lhs: NSLayoutYAxisAnchor, rhs: NSLayoutYAxisAnchor) -> NSLayoutConstraint { 191 | return finalize(constraint: lhs.constraint(lessThanOrEqualTo: rhs)) 192 | } 193 | 194 | @discardableResult public func <= (lhs: NSLayoutDimension, rhs: NSLayoutDimension) -> NSLayoutConstraint { 195 | return lhs /<=/ rhs 196 | } 197 | 198 | @discardableResult public func /<=/ (lhs: NSLayoutDimension, rhs: NSLayoutDimension) -> NSLayoutConstraint { 199 | return finalize(constraint: lhs.constraint(lessThanOrEqualTo: rhs)) 200 | } 201 | 202 | @discardableResult public func <= (lhs: NSLayoutXAxisAnchor, rhs: LayoutExpression) -> NSLayoutConstraint { 203 | return lhs /<=/ rhs 204 | } 205 | 206 | @discardableResult public func /<=/ (lhs: NSLayoutXAxisAnchor, rhs: LayoutExpression) -> NSLayoutConstraint { 207 | return finalize(constraint: lhs.constraint(lessThanOrEqualTo: rhs.anchor!, multiplier: rhs.multiplier, constant: rhs.constant), withPriority: rhs.priority) 208 | } 209 | 210 | @discardableResult public func <= (lhs: NSLayoutYAxisAnchor, rhs: LayoutExpression) -> NSLayoutConstraint { 211 | return lhs /<=/ rhs 212 | } 213 | 214 | @discardableResult public func /<=/ (lhs: NSLayoutYAxisAnchor, rhs: LayoutExpression) -> NSLayoutConstraint { 215 | return finalize(constraint: lhs.constraint(lessThanOrEqualTo: rhs.anchor!, multiplier: rhs.multiplier, constant: rhs.constant), withPriority: rhs.priority) 216 | } 217 | 218 | @discardableResult public func <= (lhs: NSLayoutDimension, rhs: LayoutExpression) -> NSLayoutConstraint { 219 | return lhs /<=/ rhs 220 | } 221 | 222 | @discardableResult public func /<=/ (lhs: NSLayoutDimension, rhs: LayoutExpression) -> NSLayoutConstraint { 223 | if let anchor = rhs.anchor { 224 | return finalize(constraint: lhs.constraint(lessThanOrEqualTo: anchor, multiplier: rhs.multiplier, constant: rhs.constant), withPriority: rhs.priority) 225 | } 226 | else { 227 | return finalize(constraint: lhs.constraint(lessThanOrEqualToConstant: rhs.constant), withPriority: rhs.priority) 228 | } 229 | } 230 | 231 | @discardableResult public func <= (lhs: EdgeAnchors, rhs: EdgeAnchors) -> ConstraintGroup { 232 | return lhs /<=/ rhs 233 | } 234 | 235 | @discardableResult public func /<=/ (lhs: EdgeAnchors, rhs: EdgeAnchors) -> ConstraintGroup { 236 | return lhs.finalize(constraintsLessThanOrEqualToEdges: rhs) 237 | } 238 | 239 | @discardableResult public func <= (lhs: EdgeAnchors, rhs: LayoutExpression) -> ConstraintGroup { 240 | return lhs /<=/ rhs 241 | } 242 | 243 | @discardableResult public func /<=/ (lhs: EdgeAnchors, rhs: LayoutExpression) -> ConstraintGroup { 244 | return lhs.finalize(constraintsLessThanOrEqualToEdges: rhs.anchor, constant: rhs.constant, priority: rhs.priority) 245 | } 246 | 247 | @discardableResult public func <= (lhs: EdgeAnchors, rhs: LayoutExpression) -> ConstraintGroup { 248 | return lhs /<=/ rhs 249 | } 250 | 251 | @discardableResult public func /<=/ (lhs: EdgeAnchors, rhs: LayoutExpression) -> ConstraintGroup { 252 | return lhs.finalize(constraintsLessThanOrEqualToEdges: rhs.anchor, insets: rhs.constant, priority: rhs.priority) 253 | } 254 | 255 | @discardableResult public func <= (lhs: AnchorPair, rhs: AnchorPair) -> ConstraintPair { 256 | return lhs /<=/ rhs 257 | } 258 | 259 | @discardableResult public func /<=/ (lhs: AnchorPair, rhs: AnchorPair) -> ConstraintPair { 260 | return lhs.finalize(constraintsLessThanOrEqualToEdges: rhs) 261 | } 262 | 263 | @discardableResult public func <= (lhs: AnchorPair, rhs: LayoutExpression, CGFloat>) -> ConstraintPair { 264 | return lhs /<=/ rhs 265 | } 266 | 267 | @discardableResult public func /<=/ (lhs: AnchorPair, rhs: LayoutExpression, CGFloat>) -> ConstraintPair { 268 | return lhs.finalize(constraintsLessThanOrEqualToEdges: rhs.anchor, constant: rhs.constant, priority: rhs.priority) 269 | } 270 | 271 | @discardableResult public func <= (lhs: AnchorPair, rhs: CGSize) -> ConstraintPair { 272 | return lhs /<=/ rhs 273 | } 274 | 275 | @discardableResult public func /<=/ (lhs: AnchorPair, rhs: CGSize) -> ConstraintPair { 276 | return lhs.finalize(constraintsLessThanOrEqualToConstant: rhs) 277 | } 278 | 279 | @discardableResult public func <= (lhs: AnchorPair, rhs: LayoutExpression, CGSize>) -> ConstraintPair { 280 | return lhs /<=/ rhs 281 | } 282 | 283 | @discardableResult public func /<=/ (lhs: AnchorPair, rhs: LayoutExpression, CGSize>) -> ConstraintPair { 284 | return lhs.finalize(constraintsLessThanOrEqualToConstant: rhs.constant, priority: rhs.priority) 285 | } 286 | 287 | // MARK: Greater Than or Equal To 288 | 289 | infix operator />=/: ComparisonPrecedence 290 | 291 | @discardableResult public func >= (lhs: NSLayoutDimension, rhs: T) -> NSLayoutConstraint { 292 | return lhs />=/ rhs 293 | } 294 | 295 | @discardableResult public func />=/ (lhs: NSLayoutDimension, rhs: T) -> NSLayoutConstraint { 296 | return finalize(constraint: lhs.constraint(greaterThanOrEqualToConstant: CGFloat(rhs))) 297 | } 298 | 299 | @discardableResult public func >= (lhs: NSLayoutXAxisAnchor, rhs: NSLayoutXAxisAnchor) -> NSLayoutConstraint { 300 | return lhs />=/ rhs 301 | } 302 | 303 | @discardableResult public func />=/ (lhs: NSLayoutXAxisAnchor, rhs: NSLayoutXAxisAnchor) -> NSLayoutConstraint { 304 | return finalize(constraint: lhs.constraint(greaterThanOrEqualTo: rhs)) 305 | } 306 | 307 | @discardableResult public func >= (lhs: NSLayoutYAxisAnchor, rhs: NSLayoutYAxisAnchor) -> NSLayoutConstraint { 308 | return lhs />=/ rhs 309 | } 310 | 311 | @discardableResult public func />=/ (lhs: NSLayoutYAxisAnchor, rhs: NSLayoutYAxisAnchor) -> NSLayoutConstraint { 312 | return finalize(constraint: lhs.constraint(greaterThanOrEqualTo: rhs)) 313 | } 314 | 315 | @discardableResult public func >= (lhs: NSLayoutDimension, rhs: NSLayoutDimension) -> NSLayoutConstraint { 316 | return lhs />=/ rhs 317 | } 318 | 319 | @discardableResult public func />=/ (lhs: NSLayoutDimension, rhs: NSLayoutDimension) -> NSLayoutConstraint { 320 | return finalize(constraint: lhs.constraint(greaterThanOrEqualTo: rhs)) 321 | } 322 | 323 | @discardableResult public func >= (lhs: NSLayoutXAxisAnchor, rhs: LayoutExpression) -> NSLayoutConstraint { 324 | return lhs />=/ rhs 325 | } 326 | 327 | @discardableResult public func />=/ (lhs: NSLayoutXAxisAnchor, rhs: LayoutExpression) -> NSLayoutConstraint { 328 | return finalize(constraint: lhs.constraint(greaterThanOrEqualTo: rhs.anchor!, multiplier: rhs.multiplier, constant: rhs.constant), withPriority: rhs.priority) 329 | } 330 | 331 | @discardableResult public func >= (lhs: NSLayoutYAxisAnchor, rhs: LayoutExpression) -> NSLayoutConstraint { 332 | return lhs />=/ rhs 333 | } 334 | 335 | @discardableResult public func />=/ (lhs: NSLayoutYAxisAnchor, rhs: LayoutExpression) -> NSLayoutConstraint { 336 | return finalize(constraint: lhs.constraint(greaterThanOrEqualTo: rhs.anchor!, multiplier: rhs.multiplier, constant: rhs.constant), withPriority: rhs.priority) 337 | } 338 | 339 | @discardableResult public func >= (lhs: NSLayoutDimension, rhs: LayoutExpression) -> NSLayoutConstraint { 340 | return lhs />=/ rhs 341 | } 342 | 343 | @discardableResult public func />=/ (lhs: NSLayoutDimension, rhs: LayoutExpression) -> NSLayoutConstraint { 344 | if let anchor = rhs.anchor { 345 | return finalize(constraint: lhs.constraint(greaterThanOrEqualTo: anchor, multiplier: rhs.multiplier, constant: rhs.constant), withPriority: rhs.priority) 346 | } 347 | else { 348 | return finalize(constraint: lhs.constraint(greaterThanOrEqualToConstant: rhs.constant), withPriority: rhs.priority) 349 | } 350 | } 351 | 352 | @discardableResult public func >= (lhs: EdgeAnchors, rhs: EdgeAnchors) -> ConstraintGroup { 353 | return lhs />=/ rhs 354 | } 355 | 356 | @discardableResult public func />=/ (lhs: EdgeAnchors, rhs: EdgeAnchors) -> ConstraintGroup { 357 | return lhs.finalize(constraintsGreaterThanOrEqualToEdges: rhs) 358 | } 359 | 360 | @discardableResult public func >= (lhs: EdgeAnchors, rhs: LayoutExpression) -> ConstraintGroup { 361 | return lhs />=/ rhs 362 | } 363 | 364 | @discardableResult public func />=/ (lhs: EdgeAnchors, rhs: LayoutExpression) -> ConstraintGroup { 365 | return lhs.finalize(constraintsGreaterThanOrEqualToEdges: rhs.anchor, constant: rhs.constant, priority: rhs.priority) 366 | } 367 | 368 | @discardableResult public func >= (lhs: EdgeAnchors, rhs: LayoutExpression) -> ConstraintGroup { 369 | return lhs />=/ rhs 370 | } 371 | 372 | @discardableResult public func />=/ (lhs: EdgeAnchors, rhs: LayoutExpression) -> ConstraintGroup { 373 | return lhs.finalize(constraintsGreaterThanOrEqualToEdges: rhs.anchor, insets: rhs.constant, priority: rhs.priority) 374 | } 375 | 376 | @discardableResult public func >= (lhs: AnchorPair, rhs: AnchorPair) -> ConstraintPair { 377 | return lhs />=/ rhs 378 | } 379 | 380 | @discardableResult public func />=/ (lhs: AnchorPair, rhs: AnchorPair) -> ConstraintPair { 381 | return lhs.finalize(constraintsGreaterThanOrEqualToEdges: rhs) 382 | } 383 | 384 | @discardableResult public func >= (lhs: AnchorPair, rhs: LayoutExpression, CGFloat>) -> ConstraintPair { 385 | return lhs />=/ rhs 386 | } 387 | 388 | @discardableResult public func />=/ (lhs: AnchorPair, rhs: LayoutExpression, CGFloat>) -> ConstraintPair { 389 | return lhs.finalize(constraintsGreaterThanOrEqualToEdges: rhs.anchor, constant: rhs.constant, priority: rhs.priority) 390 | } 391 | 392 | @discardableResult public func >= (lhs: AnchorPair, rhs: CGSize) -> ConstraintPair { 393 | return lhs />=/ rhs 394 | } 395 | 396 | @discardableResult public func />=/ (lhs: AnchorPair, rhs: CGSize) -> ConstraintPair { 397 | return lhs.finalize(constraintsGreaterThanOrEqualToConstant: rhs) 398 | } 399 | 400 | @discardableResult public func >= (lhs: AnchorPair, rhs: LayoutExpression, CGSize>) -> ConstraintPair { 401 | return lhs />=/ rhs 402 | } 403 | 404 | @discardableResult public func />=/ (lhs: AnchorPair, rhs: LayoutExpression, CGSize>) -> ConstraintPair { 405 | return lhs.finalize(constraintsGreaterThanOrEqualToConstant: rhs.constant, priority: rhs.priority) 406 | } 407 | 408 | // MARK: - Priority 409 | 410 | precedencegroup PriorityPrecedence { 411 | associativity: none 412 | higherThan: ComparisonPrecedence 413 | lowerThan: AdditionPrecedence 414 | } 415 | 416 | infix operator ~: PriorityPrecedence 417 | 418 | @discardableResult public func ~ (lhs: T, rhs: Priority) -> LayoutExpression { 419 | return LayoutExpression(constant: CGFloat(lhs), priority: rhs) 420 | } 421 | 422 | @discardableResult public func ~ (lhs: CGSize, rhs: Priority) -> LayoutExpression, CGSize> { 423 | return LayoutExpression(constant: lhs, priority: rhs) 424 | } 425 | 426 | @discardableResult public func ~ (lhs: T, rhs: Priority) -> LayoutExpression { 427 | return LayoutExpression(anchor: lhs, constant: 0.0, priority: rhs) 428 | } 429 | 430 | @discardableResult public func ~ (lhs: LayoutExpression, rhs: Priority) -> LayoutExpression { 431 | var expr = lhs 432 | expr.priority = rhs 433 | return expr 434 | } 435 | 436 | @discardableResult public func * (lhs: NSLayoutDimension, rhs: T) -> LayoutExpression { 437 | return LayoutExpression(anchor: lhs, constant: 0.0, multiplier: CGFloat(rhs)) 438 | } 439 | 440 | @discardableResult public func * (lhs: T, rhs: NSLayoutDimension) -> LayoutExpression { 441 | return LayoutExpression(anchor: rhs, constant: 0.0, multiplier: CGFloat(lhs)) 442 | } 443 | 444 | @discardableResult public func * (lhs: LayoutExpression, rhs: T) -> LayoutExpression { 445 | var expr = lhs 446 | expr.multiplier *= CGFloat(rhs) 447 | return expr 448 | } 449 | 450 | @discardableResult public func * (lhs: T, rhs: LayoutExpression) -> LayoutExpression { 451 | var expr = rhs 452 | expr.multiplier *= CGFloat(lhs) 453 | return expr 454 | } 455 | 456 | @discardableResult public func * (lhs: NSLayoutXAxisAnchor, rhs: T) -> LayoutExpression { 457 | return LayoutExpression(anchor: Optional.some(lhs), constant: 0.0, multiplier: CGFloat(rhs)) 458 | } 459 | 460 | @discardableResult public func * (lhs: T, rhs: NSLayoutXAxisAnchor) -> LayoutExpression { 461 | return LayoutExpression(anchor: rhs, constant: 0.0, multiplier: CGFloat(lhs)) 462 | } 463 | 464 | @discardableResult public func * (lhs: LayoutExpression, rhs: T) -> LayoutExpression { 465 | var expr = lhs 466 | expr.multiplier *= CGFloat(rhs) 467 | return expr 468 | } 469 | 470 | @discardableResult public func * (lhs: T, rhs: LayoutExpression) -> LayoutExpression { 471 | var expr = rhs 472 | expr.multiplier *= CGFloat(lhs) 473 | return expr 474 | } 475 | 476 | @discardableResult public func * (lhs: NSLayoutYAxisAnchor, rhs: T) -> LayoutExpression { 477 | return LayoutExpression(anchor: lhs, constant: 0.0, multiplier: CGFloat(rhs)) 478 | } 479 | 480 | @discardableResult public func * (lhs: T, rhs: NSLayoutYAxisAnchor) -> LayoutExpression { 481 | return LayoutExpression(anchor: rhs, constant: 0.0, multiplier: CGFloat(lhs)) 482 | } 483 | 484 | @discardableResult public func * (lhs: LayoutExpression, rhs: T) -> LayoutExpression { 485 | var expr = lhs 486 | expr.multiplier *= CGFloat(rhs) 487 | return expr 488 | } 489 | 490 | @discardableResult public func * (lhs: T, rhs: LayoutExpression) -> LayoutExpression { 491 | var expr = rhs 492 | expr.multiplier *= CGFloat(lhs) 493 | return expr 494 | } 495 | 496 | @discardableResult public func / (lhs: NSLayoutDimension, rhs: T) -> LayoutExpression { 497 | return LayoutExpression(anchor: lhs, constant: 0.0, multiplier: 1.0 / CGFloat(rhs)) 498 | } 499 | 500 | @discardableResult public func / (lhs: LayoutExpression, rhs: T) -> LayoutExpression { 501 | var expr = lhs 502 | expr.multiplier /= CGFloat(rhs) 503 | return expr 504 | } 505 | 506 | @discardableResult public func / (lhs: NSLayoutXAxisAnchor, rhs: T) -> LayoutExpression { 507 | return LayoutExpression(anchor: lhs, constant: 0.0, multiplier: 1.0 / CGFloat(rhs)) 508 | } 509 | 510 | @discardableResult public func / (lhs: LayoutExpression, rhs: T) -> LayoutExpression { 511 | var expr = lhs 512 | expr.multiplier /= CGFloat(rhs) 513 | return expr 514 | } 515 | 516 | @discardableResult public func / (lhs: NSLayoutYAxisAnchor, rhs: T) -> LayoutExpression { 517 | return LayoutExpression(anchor: lhs, constant: 0.0, multiplier: 1.0 / CGFloat(rhs)) 518 | } 519 | 520 | @discardableResult public func / (lhs: LayoutExpression, rhs: T) -> LayoutExpression { 521 | var expr = lhs 522 | expr.multiplier /= CGFloat(rhs) 523 | return expr 524 | } 525 | 526 | @discardableResult public func + (lhs: T, rhs: U) -> LayoutExpression { 527 | return LayoutExpression(anchor: lhs, constant: CGFloat(rhs)) 528 | } 529 | 530 | @discardableResult public func + (lhs: T, rhs: U) -> LayoutExpression { 531 | return LayoutExpression(anchor: rhs, constant: CGFloat(lhs)) 532 | } 533 | 534 | @discardableResult public func + (lhs: LayoutExpression, rhs: U) -> LayoutExpression { 535 | var expr = lhs 536 | expr.constant += CGFloat(rhs) 537 | return expr 538 | } 539 | 540 | @discardableResult public func + (lhs: T, rhs: LayoutExpression) -> LayoutExpression { 541 | var expr = rhs 542 | expr.constant += CGFloat(lhs) 543 | return expr 544 | } 545 | 546 | @discardableResult public func + (lhs: EdgeAnchors, rhs: EdgeInsets) -> LayoutExpression { 547 | return LayoutExpression(anchor: lhs, constant: rhs) 548 | } 549 | 550 | @discardableResult public func - (lhs: T, rhs: U) -> LayoutExpression { 551 | return LayoutExpression(anchor: lhs, constant: -CGFloat(rhs)) 552 | } 553 | 554 | @discardableResult public func - (lhs: T, rhs: U) -> LayoutExpression { 555 | return LayoutExpression(anchor: rhs, constant: -CGFloat(lhs)) 556 | } 557 | 558 | @discardableResult public func - (lhs: LayoutExpression, rhs: U) -> LayoutExpression { 559 | var expr = lhs 560 | expr.constant -= CGFloat(rhs) 561 | return expr 562 | } 563 | 564 | @discardableResult public func - (lhs: T, rhs: LayoutExpression) -> LayoutExpression { 565 | var expr = rhs 566 | expr.constant -= CGFloat(lhs) 567 | return expr 568 | } 569 | 570 | @discardableResult public func - (lhs: EdgeAnchors, rhs: EdgeInsets) -> LayoutExpression { 571 | return LayoutExpression(anchor: lhs, constant: -rhs) 572 | } 573 | 574 | // MARK: - Batching 575 | 576 | /// Any Anchorage constraints created inside the passed closure are returned in the array. 577 | /// 578 | /// - Parameter closure: A closure that runs some Anchorage expressions. 579 | /// - Returns: An array of new, active `NSLayoutConstraint`s. 580 | @discardableResult public func batch(_ closure: () -> Void) -> [NSLayoutConstraint] { 581 | return batch(active: true, closure: closure) 582 | } 583 | 584 | /// Any Anchorage constraints created inside the passed closure are returned in the array. 585 | /// 586 | /// - Parameter active: Whether the created constraints should be active when they are returned. 587 | /// - Parameter closure: A closure that runs some Anchorage expressions. 588 | /// - Returns: An array of new `NSLayoutConstraint`s. 589 | public func batch(active: Bool, closure: () -> Void) -> [NSLayoutConstraint] { 590 | let batch = ConstraintBatch() 591 | batches.append(batch) 592 | defer { 593 | batches.removeLast() 594 | } 595 | 596 | closure() 597 | 598 | if active { 599 | batch.activate() 600 | } 601 | 602 | return batch.constraints 603 | } 604 | -------------------------------------------------------------------------------- /Source/Compatability.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Compatability.swift 3 | // Anchorage 4 | // 5 | // Created by Rob Visentin on 5/1/17. 6 | // 7 | // Copyright 2016 Rightpoint and other contributors 8 | // http://rightpoint.com/ 9 | // 10 | // Permission is hereby granted, free of charge, to any person obtaining 11 | // a copy of this software and associated documentation files (the 12 | // Software"), to deal in the Software without restriction, including 13 | // without limitation the rights to use, copy, modify, merge, publish, 14 | // distribute, sublicense, and/or sell copies of the Software, and to 15 | // permit persons to whom the Software is furnished to do so, subject to 16 | // the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be 19 | // included in all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 22 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 23 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 24 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 25 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 26 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 27 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28 | 29 | #if os(macOS) 30 | import Cocoa 31 | 32 | #if swift(>=4.0) 33 | public typealias LayoutPriority = NSLayoutConstraint.Priority 34 | public typealias EdgeInsets = NSEdgeInsets 35 | #else 36 | public typealias LayoutPriority = NSLayoutPriority 37 | #endif 38 | #else 39 | import UIKit 40 | 41 | public typealias LayoutPriority = UILayoutPriority 42 | public typealias EdgeInsets = UIEdgeInsets 43 | #endif 44 | 45 | #if swift(>=4.2) || (os(macOS) && swift(>=4.0)) 46 | public typealias ConstraintAttribute = NSLayoutConstraint.Attribute 47 | #else 48 | public typealias ConstraintAttribute = NSLayoutAttribute 49 | #endif 50 | 51 | #if swift(>=4.0) 52 | #else 53 | extension LayoutPriority { 54 | 55 | var rawValue: Float { 56 | return self 57 | } 58 | 59 | init(rawValue: Float) { 60 | self.init(rawValue) 61 | } 62 | } 63 | #endif 64 | 65 | #if swift(>=4.2) 66 | #elseif !os(macOS) 67 | extension UITableView { 68 | public static let automaticDimension = UITableViewAutomaticDimension 69 | } 70 | 71 | extension UITableViewCell { 72 | public typealias CellStyle = UITableViewCellStyle 73 | } 74 | 75 | extension UIApplication { 76 | public typealias LaunchOptionsKey = UIApplicationLaunchOptionsKey 77 | } 78 | #endif 79 | 80 | extension CGFloat { 81 | 82 | init(_ value: T) { 83 | switch value { 84 | case is Double: 85 | self.init(value as! Double) 86 | case is Float: 87 | self.init(value as! Float) 88 | case is CGFloat: 89 | self.init(value as! CGFloat) 90 | default: 91 | fatalError("Unable to initialize CGFloat with value \(value) of type \(type(of: value))") 92 | } 93 | } 94 | 95 | } 96 | 97 | extension Float { 98 | 99 | init(_ value: T) { 100 | switch value { 101 | case is Double: 102 | self.init(value as! Double) 103 | case is Float: 104 | self.init(value as! Float) 105 | case is CGFloat: 106 | self.init(value as! CGFloat) 107 | default: 108 | fatalError("Unable to initialize CGFloat with value \(value) of type \(type(of: value))") 109 | } 110 | } 111 | 112 | } 113 | -------------------------------------------------------------------------------- /Source/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 2.0.1 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSPrincipalClass 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Source/Internal.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Internal.swift 3 | // Anchorage 4 | // 5 | // Created by Rob Visentin on 5/1/17. 6 | // 7 | // Copyright 2016 Rightpoint and other contributors 8 | // http://rightpoint.com/ 9 | // 10 | // Permission is hereby granted, free of charge, to any person obtaining 11 | // a copy of this software and associated documentation files (the 12 | // Software"), to deal in the Software without restriction, including 13 | // without limitation the rights to use, copy, modify, merge, publish, 14 | // distribute, sublicense, and/or sell copies of the Software, and to 15 | // permit persons to whom the Software is furnished to do so, subject to 16 | // the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be 19 | // included in all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 22 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 23 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 24 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 25 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 26 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 27 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28 | 29 | #if os(macOS) 30 | import Cocoa 31 | 32 | internal typealias View = NSView 33 | internal typealias ViewController = NSViewController 34 | internal typealias LayoutGuide = NSLayoutGuide 35 | 36 | #if swift(>=4.0) 37 | internal let LayoutPriorityRequired = NSLayoutConstraint.Priority.required 38 | internal let LayoutPriorityHigh = NSLayoutConstraint.Priority.defaultHigh 39 | internal let LayoutPriorityLow = NSLayoutConstraint.Priority.defaultLow 40 | internal let LayoutPriorityFittingSize = NSLayoutConstraint.Priority.fittingSizeCompression 41 | #else 42 | internal let LayoutPriorityRequired = NSLayoutPriorityRequired 43 | internal let LayoutPriorityHigh = NSLayoutPriorityDefaultHigh 44 | internal let LayoutPriorityLow = NSLayoutPriorityDefaultLow 45 | internal let LayoutPriorityFittingSize = NSLayoutPriorityFittingSizeCompression 46 | #endif 47 | #else 48 | import UIKit 49 | 50 | internal typealias View = UIView 51 | internal typealias ViewController = UIViewController 52 | internal typealias LayoutGuide = UILayoutGuide 53 | 54 | #if swift(>=4.0) 55 | internal let LayoutPriorityRequired = UILayoutPriority.required 56 | internal let LayoutPriorityHigh = UILayoutPriority.defaultHigh 57 | internal let LayoutPriorityLow = UILayoutPriority.defaultLow 58 | internal let LayoutPriorityFittingSize = UILayoutPriority.fittingSizeLevel 59 | #else 60 | internal let LayoutPriorityRequired = UILayoutPriorityRequired 61 | internal let LayoutPriorityHigh = UILayoutPriorityDefaultHigh 62 | internal let LayoutPriorityLow = UILayoutPriorityDefaultLow 63 | internal let LayoutPriorityFittingSize = UILayoutPriorityFittingSizeLevel 64 | #endif 65 | #endif 66 | 67 | // MARK: - LayoutExpression 68 | 69 | public struct LayoutExpression { 70 | 71 | public var anchor: T? 72 | public var constant: U 73 | public var multiplier: CGFloat 74 | public var priority: Priority 75 | 76 | internal init(anchor: T? = nil, constant: U, multiplier: CGFloat = 1.0, priority: Priority = .required) { 77 | self.anchor = anchor 78 | self.constant = constant 79 | self.multiplier = multiplier 80 | self.priority = priority 81 | } 82 | 83 | } 84 | 85 | // MARK: - AnchorPair 86 | 87 | public struct AnchorPair: LayoutAnchorType { 88 | 89 | public var first: T 90 | public var second: U 91 | 92 | public init(first: T, second: U) { 93 | self.first = first 94 | self.second = second 95 | } 96 | 97 | } 98 | 99 | internal extension AnchorPair { 100 | 101 | func finalize(constraintsEqualToConstant size: CGSize, priority: Priority = .required) -> ConstraintPair { 102 | return constraints(forConstant: size, priority: priority, builder: ConstraintBuilder.equality); 103 | } 104 | 105 | func finalize(constraintsLessThanOrEqualToConstant size: CGSize, priority: Priority = .required) -> ConstraintPair { 106 | return constraints(forConstant: size, priority: priority, builder: ConstraintBuilder.lessThanOrEqual); 107 | } 108 | 109 | func finalize(constraintsGreaterThanOrEqualToConstant size: CGSize, priority: Priority = .required) -> ConstraintPair { 110 | return constraints(forConstant: size, priority: priority, builder: ConstraintBuilder.greaterThanOrEqual); 111 | } 112 | 113 | func finalize(constraintsEqualToEdges anchor: AnchorPair?, constant c: CGFloat = 0.0, priority: Priority = .required) -> ConstraintPair { 114 | return constraints(forAnchors: anchor, constant: c, priority: priority, builder: ConstraintBuilder.equality) 115 | } 116 | 117 | func finalize(constraintsLessThanOrEqualToEdges anchor: AnchorPair?, constant c: CGFloat = 0.0, priority: Priority = .required) -> ConstraintPair { 118 | return constraints(forAnchors: anchor, constant: c, priority: priority, builder: ConstraintBuilder.lessThanOrEqual) 119 | } 120 | 121 | func finalize(constraintsGreaterThanOrEqualToEdges anchor: AnchorPair?, constant c: CGFloat = 0.0, priority: Priority = .required) -> ConstraintPair { 122 | return constraints(forAnchors: anchor, constant: c, priority: priority, builder: ConstraintBuilder.greaterThanOrEqual) 123 | } 124 | 125 | func constraints(forConstant size: CGSize, priority: Priority, builder: ConstraintBuilder) -> ConstraintPair { 126 | var constraints: ConstraintPair! 127 | 128 | performInBatch { 129 | switch (first, second) { 130 | case let (first as NSLayoutDimension, second as NSLayoutDimension): 131 | constraints = ConstraintPair( 132 | first: builder.dimensionBuilder(first, size.width ~ priority), 133 | second: builder.dimensionBuilder(second, size.height ~ priority) 134 | ) 135 | default: 136 | preconditionFailure("Only AnchorPair can be constrained to a constant size.") 137 | } 138 | } 139 | 140 | return constraints; 141 | } 142 | 143 | func constraints(forAnchors anchors: AnchorPair?, constant c: CGFloat, priority: Priority, builder: ConstraintBuilder) -> ConstraintPair { 144 | return constraints(forAnchors: anchors, firstConstant: c, secondConstant: c, priority: priority, builder: builder) 145 | } 146 | 147 | func constraints(forAnchors anchors: AnchorPair?, firstConstant c1: CGFloat, secondConstant c2: CGFloat, priority: Priority, builder: ConstraintBuilder) -> ConstraintPair { 148 | guard let anchors = anchors else { 149 | preconditionFailure("Encountered nil edge anchors, indicating internal inconsistency of this API.") 150 | } 151 | 152 | var constraints: ConstraintPair! 153 | 154 | performInBatch { 155 | switch (first, anchors.first, second, anchors.second) { 156 | // Leading, Trailing 157 | case let (firstX as NSLayoutXAxisAnchor, otherFirstX as NSLayoutXAxisAnchor, 158 | secondX as NSLayoutXAxisAnchor, otherSecondX as NSLayoutXAxisAnchor): 159 | constraints = ConstraintPair( 160 | first: builder.leadingBuilder(firstX, otherFirstX + c1 ~ priority), 161 | second: builder.trailingBuilder(secondX, otherSecondX - c2 ~ priority) 162 | ) 163 | // Top, Bottom 164 | case let (firstY as NSLayoutYAxisAnchor, otherFirstY as NSLayoutYAxisAnchor, 165 | secondY as NSLayoutYAxisAnchor, otherSecondY as NSLayoutYAxisAnchor): 166 | constraints = ConstraintPair( 167 | first: builder.topBuilder(firstY, otherFirstY + c1 ~ priority), 168 | second: builder.bottomBuilder(secondY, otherSecondY - c2 ~ priority) 169 | ) 170 | // CenterX, CenterY 171 | case let (firstX as NSLayoutXAxisAnchor, otherFirstX as NSLayoutXAxisAnchor, 172 | firstY as NSLayoutYAxisAnchor, otherFirstY as NSLayoutYAxisAnchor): 173 | constraints = ConstraintPair( 174 | first: builder.centerXBuilder(firstX, otherFirstX + c1 ~ priority), 175 | second: builder.centerYBuilder(firstY, otherFirstY + c2 ~ priority) 176 | ) 177 | // Width, Height 178 | case let (first as NSLayoutDimension, otherFirst as NSLayoutDimension, 179 | second as NSLayoutDimension, otherSecond as NSLayoutDimension): 180 | constraints = ConstraintPair( 181 | first: builder.dimensionBuilder(first, otherFirst + c1 ~ priority), 182 | second: builder.dimensionBuilder(second, otherSecond + c2 ~ priority) 183 | ) 184 | default: 185 | preconditionFailure("Constrained anchors must match in either axis or type.") 186 | } 187 | } 188 | 189 | return constraints 190 | } 191 | 192 | } 193 | 194 | // MARK: - EdgeAnchors 195 | 196 | internal extension EdgeInsets { 197 | 198 | init(constant: CGFloat) { 199 | self.init( 200 | top: constant, 201 | left: constant, 202 | bottom: constant, 203 | right: constant 204 | ) 205 | } 206 | 207 | } 208 | 209 | internal prefix func - (rhs: EdgeInsets) -> EdgeInsets { 210 | return EdgeInsets( 211 | top: -rhs.top, 212 | left: -rhs.left, 213 | bottom: -rhs.bottom, 214 | right: -rhs.right 215 | ) 216 | } 217 | 218 | internal extension EdgeAnchors { 219 | 220 | init(horizontal: AnchorPair, vertical: AnchorPair) { 221 | self.horizontalAnchors = horizontal 222 | self.verticalAnchors = vertical 223 | } 224 | 225 | func finalize(constraintsEqualToEdges anchor: EdgeAnchors?, insets: EdgeInsets, priority: Priority = .required) -> ConstraintGroup { 226 | return constraints(forAnchors: anchor, insets: insets, priority: priority, builder: ConstraintBuilder.equality) 227 | } 228 | 229 | func finalize(constraintsLessThanOrEqualToEdges anchor: EdgeAnchors?, insets: EdgeInsets, priority: Priority = .required) -> ConstraintGroup { 230 | return constraints(forAnchors: anchor, insets: insets, priority: priority, builder: ConstraintBuilder.lessThanOrEqual) 231 | } 232 | 233 | func finalize(constraintsGreaterThanOrEqualToEdges anchor: EdgeAnchors?, insets: EdgeInsets, priority: Priority = .required) -> ConstraintGroup { 234 | return constraints(forAnchors: anchor, insets: insets, priority: priority, builder: ConstraintBuilder.greaterThanOrEqual) 235 | } 236 | 237 | func finalize(constraintsEqualToEdges anchor: EdgeAnchors?, constant c: CGFloat = 0.0, priority: Priority = .required) -> ConstraintGroup { 238 | return constraints(forAnchors: anchor, insets: EdgeInsets(constant: c), priority: priority, builder: ConstraintBuilder.equality) 239 | } 240 | 241 | func finalize(constraintsLessThanOrEqualToEdges anchor: EdgeAnchors?, constant c: CGFloat = 0.0, priority: Priority = .required) -> ConstraintGroup { 242 | return constraints(forAnchors: anchor, insets: EdgeInsets(constant: c), priority: priority, builder: ConstraintBuilder.lessThanOrEqual) 243 | } 244 | 245 | func finalize(constraintsGreaterThanOrEqualToEdges anchor: EdgeAnchors?, constant c: CGFloat = 0.0, priority: Priority = .required) -> ConstraintGroup { 246 | return constraints(forAnchors: anchor, insets: EdgeInsets(constant: c), priority: priority, builder: ConstraintBuilder.greaterThanOrEqual) 247 | } 248 | 249 | func constraints(forAnchors anchors: EdgeAnchors?, insets: EdgeInsets, priority: Priority, builder: ConstraintBuilder) -> ConstraintGroup { 250 | guard let anchors = anchors else { 251 | preconditionFailure("Encountered nil edge anchors, indicating internal inconsistency of this API.") 252 | } 253 | 254 | var constraints: ConstraintGroup! 255 | 256 | performInBatch { 257 | let horizontalConstraints = horizontalAnchors.constraints(forAnchors: anchors.horizontalAnchors, firstConstant: insets.left, secondConstant: insets.right, priority: priority, builder: builder) 258 | let verticalConstraints = verticalAnchors.constraints(forAnchors: anchors.verticalAnchors, firstConstant: insets.top, secondConstant: insets.bottom, priority: priority, builder: builder) 259 | constraints = ConstraintGroup( 260 | top: verticalConstraints.first, 261 | leading: horizontalConstraints.first, 262 | bottom: verticalConstraints.second, 263 | trailing: horizontalConstraints.second 264 | ) 265 | } 266 | 267 | return constraints 268 | } 269 | 270 | } 271 | 272 | // MARK: - ConstraintBuilder 273 | 274 | internal struct ConstraintBuilder { 275 | 276 | typealias Horizontal = (NSLayoutXAxisAnchor, LayoutExpression) -> NSLayoutConstraint 277 | typealias Vertical = (NSLayoutYAxisAnchor, LayoutExpression) -> NSLayoutConstraint 278 | typealias Dimension = (NSLayoutDimension, LayoutExpression) -> NSLayoutConstraint 279 | 280 | static let equality = ConstraintBuilder(horizontal: ==, vertical: ==, dimension: ==) 281 | static let lessThanOrEqual = ConstraintBuilder(leading: <=, top: <=, trailing: >=, bottom: >=, centerX: <=, centerY: <=, dimension: <=) 282 | static let greaterThanOrEqual = ConstraintBuilder(leading: >=, top: >=, trailing: <=, bottom: <=, centerX: >=, centerY: >=, dimension: >=) 283 | 284 | var topBuilder: Vertical 285 | var leadingBuilder: Horizontal 286 | var bottomBuilder: Vertical 287 | var trailingBuilder: Horizontal 288 | var centerYBuilder: Vertical 289 | var centerXBuilder: Horizontal 290 | var dimensionBuilder: Dimension 291 | 292 | init(horizontal: @escaping Horizontal, vertical: @escaping Vertical, dimension: @escaping Dimension) { 293 | topBuilder = vertical 294 | leadingBuilder = horizontal 295 | bottomBuilder = vertical 296 | trailingBuilder = horizontal 297 | centerYBuilder = vertical 298 | centerXBuilder = horizontal 299 | dimensionBuilder = dimension 300 | } 301 | 302 | init(leading: @escaping Horizontal, top: @escaping Vertical, trailing: @escaping Horizontal, 303 | bottom: @escaping Vertical, centerX: @escaping Horizontal, centerY: @escaping Vertical, dimension: @escaping Dimension) { 304 | leadingBuilder = leading 305 | topBuilder = top 306 | trailingBuilder = trailing 307 | bottomBuilder = bottom 308 | centerYBuilder = centerY 309 | centerXBuilder = centerX 310 | dimensionBuilder = dimension 311 | } 312 | 313 | } 314 | 315 | // MARK: - Batching 316 | 317 | internal var batches: [ConstraintBatch] = [] 318 | 319 | internal class ConstraintBatch { 320 | 321 | var constraints = [NSLayoutConstraint]() 322 | 323 | func add(constraint: NSLayoutConstraint) { 324 | constraints.append(constraint) 325 | } 326 | 327 | func activate() { 328 | NSLayoutConstraint.activate(constraints) 329 | } 330 | 331 | } 332 | 333 | /// Perform a closure immediately if a batch is already active, 334 | /// otherwise executes the closure in a new batch. 335 | /// 336 | /// - Parameter closure: The work to perform inside of a batch 337 | internal func performInBatch(closure: () -> Void) { 338 | if batches.isEmpty { 339 | batch(closure) 340 | } 341 | else { 342 | closure() 343 | } 344 | } 345 | 346 | // MARK: - Constraint Activation 347 | 348 | internal func finalize(constraint: NSLayoutConstraint, withPriority priority: Priority = .required) -> NSLayoutConstraint { 349 | // Only disable autoresizing constraints on the LHS item, which is the one definitely intended to be governed by Auto Layout 350 | if let first = constraint.firstItem as? View { 351 | first.translatesAutoresizingMaskIntoConstraints = false 352 | } 353 | 354 | constraint.priority = priority.value 355 | 356 | if let lastBatch = batches.last { 357 | lastBatch.add(constraint: constraint) 358 | } 359 | else { 360 | constraint.isActive = true 361 | } 362 | 363 | return constraint 364 | } 365 | -------------------------------------------------------------------------------- /Source/NSLayoutAnchor+MultiplierConstraints.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NSLayoutAnchor+MultiplierConstraints.swift 3 | // Anchorage 4 | // 5 | // Created by Aleksandr Gusev on 7/21/17. 6 | // 7 | // Copyright 2016 Rightpoint and other contributors 8 | // http://rightpoint.com/ 9 | // 10 | // Permission is hereby granted, free of charge, to any person obtaining 11 | // a copy of this software and associated documentation files (the 12 | // Software"), to deal in the Software without restriction, including 13 | // without limitation the rights to use, copy, modify, merge, publish, 14 | // distribute, sublicense, and/or sell copies of the Software, and to 15 | // permit persons to whom the Software is furnished to do so, subject to 16 | // the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be 19 | // included in all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 22 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 23 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 24 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 25 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 26 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 27 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28 | 29 | #if os(macOS) 30 | import Cocoa 31 | #else 32 | import UIKit 33 | #endif 34 | 35 | extension NSLayoutXAxisAnchor { 36 | func constraint(equalTo anchor: NSLayoutXAxisAnchor, 37 | multiplier m: CGFloat, 38 | constant c: CGFloat = 0.0) -> NSLayoutConstraint { 39 | let constraint = self.constraint(equalTo: anchor, constant: c) 40 | return constraint.with(multiplier: m) 41 | } 42 | 43 | func constraint(greaterThanOrEqualTo anchor: NSLayoutXAxisAnchor, 44 | multiplier m: CGFloat, 45 | constant c: CGFloat = 0.0) -> NSLayoutConstraint { 46 | let constraint = self.constraint(greaterThanOrEqualTo: anchor, constant: c) 47 | return constraint.with(multiplier: m) 48 | } 49 | 50 | func constraint(lessThanOrEqualTo anchor: NSLayoutXAxisAnchor, 51 | multiplier m: CGFloat, 52 | constant c: CGFloat = 0.0) -> NSLayoutConstraint { 53 | let constraint = self.constraint(lessThanOrEqualTo: anchor, constant: c) 54 | return constraint.with(multiplier: m) 55 | } 56 | } 57 | 58 | extension NSLayoutYAxisAnchor { 59 | func constraint(equalTo anchor: NSLayoutYAxisAnchor, 60 | multiplier m: CGFloat, 61 | constant c: CGFloat = 0.0) -> NSLayoutConstraint { 62 | let constraint = self.constraint(equalTo: anchor, constant: c) 63 | return constraint.with(multiplier: m) 64 | } 65 | 66 | func constraint(greaterThanOrEqualTo anchor: NSLayoutYAxisAnchor, 67 | multiplier m: CGFloat, 68 | constant c: CGFloat = 0.0) -> NSLayoutConstraint { 69 | let constraint = self.constraint(greaterThanOrEqualTo: anchor, constant: c) 70 | return constraint.with(multiplier: m) 71 | } 72 | 73 | func constraint(lessThanOrEqualTo anchor: NSLayoutYAxisAnchor, 74 | multiplier m: CGFloat, 75 | constant c: CGFloat = 0.0) -> NSLayoutConstraint { 76 | let constraint = self.constraint(lessThanOrEqualTo: anchor, constant: c) 77 | return constraint.with(multiplier: m) 78 | } 79 | } 80 | 81 | private extension NSLayoutConstraint { 82 | func with(multiplier: CGFloat) -> NSLayoutConstraint { 83 | return NSLayoutConstraint(item: firstItem!, 84 | attribute: firstAttribute, 85 | relatedBy: relation, 86 | toItem: secondItem, 87 | attribute: secondAttribute, 88 | multiplier: multiplier, 89 | constant: constant) 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /Source/Priority.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Priority.swift 3 | // Anchorage 4 | // 5 | // Created by Rob Visentin on 5/1/17. 6 | // 7 | // Copyright 2016 Rightpoint and other contributors 8 | // http://rightpoint.com/ 9 | // 10 | // Permission is hereby granted, free of charge, to any person obtaining 11 | // a copy of this software and associated documentation files (the 12 | // Software"), to deal in the Software without restriction, including 13 | // without limitation the rights to use, copy, modify, merge, publish, 14 | // distribute, sublicense, and/or sell copies of the Software, and to 15 | // permit persons to whom the Software is furnished to do so, subject to 16 | // the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be 19 | // included in all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 22 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 23 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 24 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 25 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 26 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 27 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28 | 29 | #if os(macOS) 30 | import Cocoa 31 | #else 32 | import UIKit 33 | #endif 34 | 35 | public enum Priority: ExpressibleByFloatLiteral, ExpressibleByIntegerLiteral, Equatable { 36 | 37 | case required 38 | case high 39 | case low 40 | case fittingSize 41 | case custom(LayoutPriority) 42 | 43 | public var value: LayoutPriority { 44 | switch self { 45 | case .required: return LayoutPriorityRequired 46 | case .high: return LayoutPriorityHigh 47 | case .low: return LayoutPriorityLow 48 | case .fittingSize: return LayoutPriorityFittingSize 49 | case .custom(let priority): return priority 50 | } 51 | } 52 | 53 | public init(floatLiteral value: Float) { 54 | self = .custom(LayoutPriority(value)) 55 | } 56 | 57 | public init(integerLiteral value: Int) { 58 | self.init(value) 59 | } 60 | 61 | public init(_ value: Int) { 62 | self = .custom(LayoutPriority(Float(value))) 63 | } 64 | 65 | public init(_ value: T) { 66 | self = .custom(LayoutPriority(Float(value))) 67 | } 68 | 69 | } 70 | 71 | public func == (lhs: Priority, rhs: Priority) -> Bool { 72 | return lhs.value == rhs.value 73 | } 74 | 75 | public func + (lhs: Priority, rhs: T) -> Priority { 76 | return .custom(LayoutPriority(rawValue: lhs.value.rawValue + Float(rhs))) 77 | } 78 | 79 | public func + (lhs: T, rhs: Priority) -> Priority { 80 | return .custom(LayoutPriority(rawValue: Float(lhs) + rhs.value.rawValue)) 81 | } 82 | 83 | public func - (lhs: Priority, rhs: T) -> Priority { 84 | return .custom(LayoutPriority(rawValue: lhs.value.rawValue - Float(rhs))) 85 | } 86 | 87 | public func - (lhs: T, rhs: Priority) -> Priority { 88 | return .custom(LayoutPriority(rawValue: Float(lhs) - rhs.value.rawValue)) 89 | } 90 | -------------------------------------------------------------------------------- /scripts/iOS_Swift.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # required: pass iOS version as first parameter 3 | # required: pass Swift version as second parameter 4 | 5 | set -o pipefail && \ 6 | xcodebuild clean build test \ 7 | -project Anchorage.xcodeproj \ 8 | -scheme Anchorage-iOS \ 9 | -sdk iphonesimulator \ 10 | -destination "platform=iOS Simulator,name=iPhone 8,OS=$1" \ 11 | SWIFT_VERSION=$2 \ 12 | CODE_SIGNING_REQUIRED=NO \ 13 | CODE_SIGN_IDENTITY= \ 14 | | bundle exec xcpretty 15 | -------------------------------------------------------------------------------- /scripts/iOS_demo_Swift.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # required: pass iOS version as first parameter 3 | # required: pass Swift version as second parameter 4 | 5 | set -o pipefail && \ 6 | xcodebuild clean build \ 7 | -project Anchorage.xcodeproj \ 8 | -scheme AnchorageDemo \ 9 | -sdk iphonesimulator \ 10 | -destination "platform=iOS Simulator,name=iPhone 8,OS=$1" \ 11 | SWIFT_VERSION=$2 \ 12 | CODE_SIGNING_REQUIRED=NO \ 13 | CODE_SIGN_IDENTITY= \ 14 | | bundle exec xcpretty 15 | -------------------------------------------------------------------------------- /scripts/macOS_Swift.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # required: pass Swift version as first and only parameter 3 | 4 | set -o pipefail && \ 5 | xcodebuild clean build test \ 6 | -project Anchorage.xcodeproj \ 7 | -scheme Anchorage-macOS \ 8 | -sdk macosx \ 9 | -destination "arch=x86_64" \ 10 | SWIFT_VERSION=$1 \ 11 | CODE_SIGNING_REQUIRED=NO \ 12 | CODE_SIGN_IDENTITY= \ 13 | | bundle exec xcpretty 14 | -------------------------------------------------------------------------------- /scripts/tvOS_Swift.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # required: pass iOS version as first parameter 3 | # required: pass Swift version as second parameter 4 | 5 | set -o pipefail && \ 6 | xcodebuild clean build test \ 7 | -project Anchorage.xcodeproj \ 8 | -scheme Anchorage-tvOS \ 9 | -sdk appletvsimulator \ 10 | -destination "platform=tvOS Simulator,name=Apple TV,OS=$1" \ 11 | SWIFT_VERSION=$2 \ 12 | CODE_SIGNING_REQUIRED=NO \ 13 | CODE_SIGN_IDENTITY= \ 14 | | bundle exec xcpretty 15 | --------------------------------------------------------------------------------