├── .cocoadocs.yml ├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── Cartfile ├── Cartfile.resolved ├── Example ├── DEPLOY PROCESS.md ├── Podfile ├── Podfile.lock ├── Scripts │ └── Cocoapods │ │ ├── podInstall.command │ │ ├── podSetup.command │ │ ├── podUpdate.command │ │ └── utils.sh ├── StretchScrollView.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── xcshareddata │ │ └── xcschemes │ │ └── StretchScrollView-Example.xcscheme ├── StretchScrollView.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── WorkspaceSettings.xcsettings ├── StretchScrollView │ ├── AppDelegate.swift │ ├── Base.lproj │ │ ├── LaunchScreen.xib │ │ └── Main.storyboard │ ├── FromCodeVC.swift │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ ├── Contents.json │ │ └── sarah.imageset │ │ │ ├── 2670048-starcraft_sarah_kerrigan.jpg │ │ │ └── Contents.json │ ├── Info.plist │ ├── StretchScrollView.gif │ ├── ViewController.swift │ ├── constraints.png │ ├── constraints2.png │ ├── contentMode.png │ ├── customClass.png │ ├── options.png │ └── outlets.png └── Tests │ ├── Info.plist │ └── Tests.swift ├── LICENSE ├── Package.resolved ├── Package.swift ├── README.md ├── Scripts └── Carthage │ ├── carthageAdd.command │ ├── carthageAdd.rb │ ├── carthageInstall.command │ ├── carthageInstallTests.command │ ├── carthageRemove.command │ ├── carthageRemove.rb │ ├── carthageSetup.command │ ├── carthageSetup.rb │ ├── carthageUpdate.command │ ├── utils.rb │ └── utils.sh ├── StretchScrollView tvOS ├── Info.plist └── StretchScrollView_tvOS.h ├── StretchScrollView.podspec ├── StretchScrollView.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── xcshareddata │ └── xcschemes │ └── StretchScrollView.xcscheme ├── StretchScrollView ├── Assets │ └── .gitkeep ├── Classes │ ├── CGRect+Utils.swift │ ├── StretchScrollView.swift │ ├── UIScrollView+Utils.swift │ ├── UIView+Utils.swift │ └── UIViewController+Utils.swift ├── Info.plist └── StretchScrollView.h ├── checkBuild.command ├── podCheck.command └── podPush.command /.cocoadocs.yml: -------------------------------------------------------------------------------- 1 | highlight-font: '"GT Walsheim", "gt_walsheim_regular", "Avant Garde Gothic ITCW01Dm", "Avant Garde", "Helvetica Neue", "Arial"' 2 | 3 | body: '"Helvetica Neue", "Arial", san-serif' 4 | code: '"Monaco", "Menlo", "Consolas", "Courier New", monospace' 5 | 6 | highlight-color: '#ED0015' 7 | highlight-dark-color: '#A90010' 8 | 9 | darker-color: '#C6B7B2' 10 | darker-dark-color: '#A8A8A8' 11 | 12 | background-color: '#F2F2F2' 13 | alt-link-color: '#B7233F' 14 | warning-color: '#B80E3D' 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## 6 | .DS_Store 7 | 8 | ## Build generated 9 | build/ 10 | DerivedData 11 | *.d 12 | *.dia 13 | 14 | ## Various settings 15 | *.pbxuser 16 | !default.pbxuser 17 | *.mode1v3 18 | !default.mode1v3 19 | *.mode2v3 20 | !default.mode2v3 21 | *.perspectivev3 22 | !default.perspectivev3 23 | xcuserdata 24 | 25 | ## Other 26 | *.xccheckout 27 | *.moved-aside 28 | *.xcuserstate 29 | *.xcscmblueprint 30 | 31 | ## Obj-C/Swift specific 32 | *.hmap 33 | *.ipa 34 | 35 | # CocoaPods 36 | # 37 | # We recommend against adding the Pods directory to your .gitignore. However 38 | # you should judge for yourself, the pros and cons are mentioned at: 39 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 40 | # 41 | #*.lock 42 | Example/Pods/ 43 | 44 | # Carthage 45 | # 46 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 47 | /Carthage/ 48 | 49 | *.orig 50 | 51 | # Swift Package Manager 52 | # 53 | # Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata 54 | # hence it is not needed unless you have added a package configuration file to your project 55 | # .swiftpm 56 | 57 | .build/ 58 | .swiftpm/ 59 | /Packages 60 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # references: 2 | # * http://www.objc.io/issue-6/travis-ci.html 3 | # * https://github.com/supermarin/xcpretty#usage 4 | 5 | osx_image: xcode12.4 6 | 7 | language: swift 8 | 9 | cache: 10 | directories: 11 | - Carthage 12 | - Example/Pods 13 | 14 | before_install: 15 | - Example/Scripts/Cocoapods/podInstall.command 16 | - brew install carthage 17 | - Scripts/Carthage/carthageInstallTests.command 18 | 19 | script: 20 | - bash checkBuild.command 21 | - pod lib lint 22 | - pod spec lint 23 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | All notable changes to this project will be documented in this file. 3 | `StretchScrollView` adheres to [Semantic Versioning](http://semver.org/). 4 | 5 | 6 | ## [6.0.0](https://github.com/APUtils/StretchScrollView/releases/tag/6.0.0) 7 | Released on 04/13/2021. 8 | 9 | #### Added 10 | - SPM support 11 | - tvOS support 12 | 13 | #### Changed 14 | - iOS 9.0 min 15 | 16 | 17 | ## [5.0.0](https://github.com/APUtils/StretchScrollView/releases/tag/5.0.0) 18 | Released on 01/03/2020. 19 | 20 | #### Added 21 | - Support for nesting in UIStackView 22 | 23 | 24 | ## [4.3.0](https://github.com/APUtils/StretchScrollView/releases/tag/4.3.0) 25 | Released on 01/14/2019. 26 | 27 | #### Added 28 | - Detection and management of enlarged scrollView 29 | 30 | 31 | ## [4.2.1](https://github.com/APUtils/StretchScrollView/releases/tag/4.2.1) 32 | Released on 01/14/2019. 33 | 34 | #### Fixed 35 | - Ability to set stretched view from code 36 | 37 | 38 | ## [4.2.0](https://github.com/APUtils/StretchScrollView/releases/tag/4.2.0) 39 | Released on 01/14/2019. 40 | 41 | #### Added 42 | - Ability to set stretched view from code 43 | 44 | 45 | ## [4.1.3](https://github.com/APUtils/StretchScrollView/releases/tag/4.1.3) 46 | Released on 01/14/2019. 47 | 48 | #### Fixed 49 | - Carthage support 50 | 51 | 52 | ## [4.1.2](https://github.com/APUtils/StretchScrollView/releases/tag/4.1.2) 53 | Released on 01/14/2019. 54 | 55 | #### Fixed 56 | - Carthage support 57 | 58 | 59 | ## [4.1.1](https://github.com/APUtils/StretchScrollView/releases/tag/4.1.1) 60 | Released on 01/14/2019. 61 | 62 | #### Fixed 63 | - Carthage support 64 | 65 | 66 | ## [4.1.0](https://github.com/APUtils/StretchScrollView/releases/tag/4.1.0) 67 | Released on 01/11/2019. 68 | 69 | #### Fixed 70 | - Carthage support 71 | 72 | 73 | ## [4.0.0](https://github.com/APUtils/StretchScrollView/releases/tag/4.0.0) 74 | Released on 12/30/2018. 75 | 76 | #### Added 77 | - Swift 4.2 78 | 79 | #### Fixed 80 | - Always bounce to enlarge even if there isn't enough content 81 | 82 | 83 | ## [3.0.4](https://github.com/APUtils/StretchScrollView/releases/tag/3.0.4) 84 | Released on 09/27/2017. 85 | 86 | #### Fixed 87 | - iPhone X fix 88 | 89 | 90 | ## [3.0.3](https://github.com/APUtils/StretchScrollView/releases/tag/3.0.3) 91 | Released on 09/27/2017. 92 | 93 | #### Fixed 94 | - Force disable large titles for controller 95 | 96 | 97 | ## [3.0.2](https://github.com/APUtils/StretchScrollView/releases/tag/3.0.2) 98 | Released on 09/25/2017. 99 | 100 | #### Fixed 101 | - Top inset calculation fix 102 | 103 | 104 | ## [3.0.1](https://github.com/APUtils/StretchScrollView/releases/tag/3.0.1) 105 | Released on 09/25/2017. 106 | 107 | #### Fixed 108 | - Taking into account safe area adjusted offsets 109 | - Navigation bar background view fix 110 | 111 | 112 | ## [3.0.0](https://github.com/APUtils/StretchScrollView/releases/tag/3.0.0) 113 | Released on 09/21/2017. 114 | 115 | Swift 4 migration 116 | 117 | 118 | ## [2.2.1](https://github.com/APUtils/StretchScrollView/releases/tag/2.2.1) 119 | Released on 08/28/2017. 120 | 121 | #### Fixed 122 | - Possible conflicts with APExtensions extensions 123 | - Wrong state restoration when pop to root was performed 124 | 125 | 126 | ## [2.2.0](https://github.com/APUtils/StretchScrollView/releases/tag/2.2.0) 127 | Released on 08/14/2017. 128 | 129 | #### Fixed 130 | - Pop animation fix 131 | 132 | 133 | ## [2.1.0](https://github.com/APUtils/StretchScrollView/releases/tag/2.1.0) 134 | Released on 08/08/2017. 135 | 136 | #### Added 137 | - Top and sides constraints setup 138 | - Carthage support 139 | 140 | 141 | ## [2.0.1](https://github.com/APUtils/StretchScrollView/releases/tag/2.0.1) 142 | Released on 08/07/2017. 143 | 144 | #### Fixed 145 | - Fixed bug with transparent state save and restore 146 | - Example project crash fix 147 | 148 | 149 | ## [2.0.0](https://github.com/APUtils/StretchScrollView/releases/tag/2.0.0) 150 | Released on 08/07/2017. 151 | 152 | #### Added 153 | - Manage navigation bar transparency automatically 154 | 155 | 156 | ## [1.2.0](https://github.com/APUtils/StretchScrollView/releases/tag/1.2.0) 157 | Released on 08/04/2017. 158 | 159 | #### Changed 160 | - Migrated to APExtensions 3.3.0 161 | - Updated GIF 162 | 163 | 164 | ## [1.1.0](https://github.com/APUtils/StretchScrollView/releases/tag/1.1.0) 165 | Released on 07/20/2017. 166 | 167 | #### Added 168 | - Now scrollView pays attention to top contentInset so translucent navigation bar won't overlap image. 169 | 170 | 171 | ## [1.0.1](https://github.com/APUtils/StretchScrollView/releases/tag/1.0.1) 172 | Released on 07/20/2017. 173 | 174 | #### Removed 175 | - Removing unnecessary extension. 176 | 177 | 178 | ## [1.0.0](https://github.com/APUtils/StretchScrollView/releases/tag/1.0.0) 179 | Released on 07/20/2017. 180 | 181 | #### Added 182 | - Initial release of StretchScrollView. 183 | - Added by [Anton Plebanovich](https://github.com/anton-plebanovich). 184 | -------------------------------------------------------------------------------- /Cartfile: -------------------------------------------------------------------------------- 1 | github "APUtils/ViewState" >= 1.2.2 -------------------------------------------------------------------------------- /Cartfile.resolved: -------------------------------------------------------------------------------- 1 | github "APUtils/LogsManager" "9.1.20" 2 | github "APUtils/ViewState" "1.2.5" 3 | github "CocoaLumberjack/CocoaLumberjack" "3.7.2" 4 | -------------------------------------------------------------------------------- /Example/DEPLOY PROCESS.md: -------------------------------------------------------------------------------- 1 | - Assure `CarthageSupport/StretchScrollView.xcodeproj` have all dependencies added. 2 | - Change version in podspec 3 | - Run `podUpdate.command` 4 | - Run `carthageUpdate.command` 5 | - Run `swift package update` 6 | - Run `checkBuild.command` 7 | - Update CHANGELOG.md 8 | - Update README.md with new version if needed 9 | - Push changes in git 10 | - Add git tag 11 | - Run `podPush.command` 12 | -------------------------------------------------------------------------------- /Example/Podfile: -------------------------------------------------------------------------------- 1 | # Deployment Target 2 | platform :ios, '11.0' 3 | install! 'cocoapods', :warn_for_unused_master_specs_repo => false 4 | 5 | # Add pods as frameworks so we could add obj-c and swift 3.0 pods 6 | use_frameworks! 7 | 8 | 9 | target 'StretchScrollView_Example' do 10 | pod 'APExtensions', :git => 'https://github.com/APUtils/APExtensions' 11 | pod 'BaseClasses', :git => 'https://github.com/APUtils/BaseClasses' 12 | pod 'StretchScrollView', :path => '../' 13 | 14 | target 'StretchScrollView_Tests' do 15 | inherit! :search_paths 16 | 17 | pod 'Quick' 18 | pod 'Nimble' 19 | pod 'Nimble-Snapshots' 20 | end 21 | end 22 | 23 | 24 | post_install do |installer| 25 | # Add podInstall.command and podUpdate.command shell scripts to Pods project 26 | pods_project = installer.pods_project 27 | pods_project.new_file "../Scripts/Cocoapods/podInstall.command" 28 | pods_project.new_file "../Scripts/Cocoapods/podUpdate.command" 29 | 30 | # Silence Pods project warning 31 | installer.pods_project.build_configurations.each do |config| 32 | config.build_settings['CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED'] = 'YES' 33 | end 34 | 35 | installer.pods_project.targets.each do |target| 36 | target.build_configurations.each do |config| 37 | config.build_settings.delete 'IPHONEOS_DEPLOYMENT_TARGET' 38 | end 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /Example/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - APExtensions (10.1.6): 3 | - APExtensions/Core (= 10.1.6) 4 | - APExtensions/Storyboard (= 10.1.6) 5 | - APExtensions/ViewConfiguration (= 10.1.6) 6 | - APExtensions/Core (10.1.6): 7 | - RoutableLogger 8 | - APExtensions/Storyboard (10.1.6) 9 | - APExtensions/ViewConfiguration (10.1.6) 10 | - BaseClasses (6.0.0): 11 | - RoutableLogger (>= 9.1.6) 12 | - iOSSnapshotTestCase (8.0.0): 13 | - iOSSnapshotTestCase/SwiftSupport (= 8.0.0) 14 | - iOSSnapshotTestCase/Core (8.0.0) 15 | - iOSSnapshotTestCase/SwiftSupport (8.0.0): 16 | - iOSSnapshotTestCase/Core 17 | - Nimble (9.2.1) 18 | - Nimble-Snapshots (9.3.0): 19 | - Nimble-Snapshots/Core (= 9.3.0) 20 | - Nimble-Snapshots/Core (9.3.0): 21 | - iOSSnapshotTestCase (~> 8.0) 22 | - Nimble 23 | - Quick (4.0.0) 24 | - RoutableLogger (9.1.12) 25 | - StretchScrollView (6.0.0): 26 | - ViewState (>= 1.0.0) 27 | - ViewState (1.2.3): 28 | - RoutableLogger (>= 9.1.11) 29 | 30 | DEPENDENCIES: 31 | - APExtensions (from `https://github.com/APUtils/APExtensions`) 32 | - BaseClasses (from `https://github.com/APUtils/BaseClasses`) 33 | - Nimble 34 | - Nimble-Snapshots 35 | - Quick 36 | - StretchScrollView (from `../`) 37 | 38 | SPEC REPOS: 39 | trunk: 40 | - iOSSnapshotTestCase 41 | - Nimble 42 | - Nimble-Snapshots 43 | - Quick 44 | - RoutableLogger 45 | - ViewState 46 | 47 | EXTERNAL SOURCES: 48 | APExtensions: 49 | :git: https://github.com/APUtils/APExtensions 50 | BaseClasses: 51 | :git: https://github.com/APUtils/BaseClasses 52 | StretchScrollView: 53 | :path: "../" 54 | 55 | CHECKOUT OPTIONS: 56 | APExtensions: 57 | :commit: 085a41c04626378c75bc5d4887784121465adc9c 58 | :git: https://github.com/APUtils/APExtensions 59 | BaseClasses: 60 | :commit: 265de446def32f3f84424d81d05ff1a2aa01bb4e 61 | :git: https://github.com/APUtils/BaseClasses 62 | 63 | SPEC CHECKSUMS: 64 | APExtensions: 63f9f31f09a8b43a52c2207774568756e3bd489f 65 | BaseClasses: c9c3c7532dedbc7bf839917fbbff8234ede087b2 66 | iOSSnapshotTestCase: a670511f9ee3829c2b9c23e6e68f315fd7b6790f 67 | Nimble: e7e615c0335ee4bf5b0d786685451e62746117d5 68 | Nimble-Snapshots: 97270cd48f0e6eebd6c80ccf7dd35d4e57fb9997 69 | Quick: 6473349e43b9271a8d43839d9ba1c442ed1b7ac4 70 | RoutableLogger: 9ad367e9a79df59c3cf5a1707ba9598ffbae8784 71 | StretchScrollView: 715aacf8437aa3598cafbee671116663bcee27d8 72 | ViewState: d6492d0434d2ee6013c270c1431dbe73cc895b75 73 | 74 | PODFILE CHECKSUM: 08abfb075b194aebd6d045f21839a742e4a002dd 75 | 76 | COCOAPODS: 1.11.2 77 | -------------------------------------------------------------------------------- /Example/Scripts/Cocoapods/podInstall.command: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | performPodInstallAndCaptureOutput() { 4 | # Capture variable but preserve console output - https://stackoverflow.com/a/12451419/4124265 5 | # Preserve colors - https://stackoverflow.com/a/3515296/4124265 6 | exec 5>&1 7 | set -o pipefail 8 | pod_install_output=`script -q /dev/null pod install | tee /dev/fd/5` 9 | } 10 | 11 | # Assume scripts are placed in /Scripts/Cocoapods dir 12 | _script_call_path="${BASH_SOURCE%/*}" 13 | if [[ ! -d "${_script_call_path}" ]]; then _script_call_path=$(dirname "$0"); fi 14 | cd "${_script_call_path}" 15 | 16 | . utils.sh 17 | 18 | cd .. 19 | cd .. 20 | 21 | simulators=$(xcrun simctl list devices available | sed -n 's/.*(\([A-Z0-9\-]*\)).*/\1/p' | tr "\n" ' ') 22 | if [ -z "${simulators}" ]; then 23 | new_simulator_name=$(uuidgen) 24 | echo "There are no simulators for 'pod install'. Creating one with name '${new_simulator_name}'." 25 | new_simulator_id=$(xcrun simctl create ${new_simulator_name} com.apple.CoreSimulator.SimDeviceType.iPhone-SE) 26 | echo "Created simulator for 'pod install' with ID '${new_simulator_id}' and name '${new_simulator_name}'" 27 | fi 28 | 29 | set +e 30 | performPodInstallAndCaptureOutput 31 | exit_code=$? 32 | set -e 33 | 34 | # Check if repo needs update 35 | # * `31` Spec not found (i.e out-of-date source repos, mistyped Pod name etc...) 36 | echo "Exit code: ${exit_code}" 37 | if [ ${exit_code} -eq 31 ] || [ ${exit_code} -eq 1 ]; then 38 | echo "Fixing outdated repo" 39 | pod repo update 40 | pod_install_output=`script -q /dev/null pod install | tee /dev/fd/5` 41 | 42 | elif [ ${exit_code} -eq 0 ]; then 43 | # Break 44 | : 45 | 46 | else 47 | exit ${exit_code} 48 | fi 49 | 50 | # Check if there is a license warning caused by a broken pods cache. 51 | # [!] Unable to read the license file `LICENSE` for the spec `FirebaseCoreDiagnostics (1.3.0)` 52 | # Filter out `LogsManager` missing LICENSE because of the bug - https://github.com/leavez/cocoapods-binary/pull/122 53 | filtered_pod_install_output=$(echo "${pod_install_output}" | grep -v 'LICENSE.*LogsManager') 54 | if [[ "${filtered_pod_install_output}" == *LICENSE* ]]; then 55 | echo "Fixing broken Pods cache" 56 | rm -rf "Pods" 57 | pod cache clean --all 58 | pod install 59 | fi 60 | 61 | echo "Fixing warnings" 62 | fixWarnings 63 | -------------------------------------------------------------------------------- /Example/Scripts/Cocoapods/podSetup.command: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ### Script to setup Cocoapods for a project target ### 4 | 5 | # Any subsequent(*) commands which fail will cause the shell script to exit immediately 6 | set -e 7 | 8 | _post_instal_phase="\npost_install do |installer|\n # Add podInstall.command and podUpdate.command shell scripts to Pods project\n pods_project = installer.pods_project\n pods_project.new_file \"../Scripts/Cocoapods/podInstall.command\"\n pods_project.new_file \"../Scripts/Cocoapods/podUpdate.command\"\n\n # Silence Pods project warning\n installer.pods_project.build_configurations.each do |config|\n config.build_settings['CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED'] = 'YES'\n end\nend\n" 9 | addPostIstallPhase() { 10 | printf "${_post_instal_phase}" >> "Podfile" 11 | } 12 | 13 | # Assume scripts are placed in /Scripts/Cocoapods dir 14 | _script_call_path="${BASH_SOURCE%/*}" 15 | if [[ ! -d "${_script_call_path}" ]]; then _script_call_path=$(dirname "$0"); fi 16 | cd "${_script_call_path}" 17 | 18 | . ./utils.sh 19 | 20 | cd .. 21 | cd .. 22 | 23 | # Podfile Update 24 | printf >&2 "\n${blue_color}Updating Podfile...${no_color}\n" 25 | touch "Podfile" 26 | if ! $(grep -q -F 'pods_project.new_file "../Scripts/Cocoapods/podInstall.command"' "Podfile"); then 27 | # Need to update Podfile 28 | if ! $(grep -q -F 'post_install' "Podfile"); then 29 | # Need to create post_install phase 30 | addPostIstallPhase 31 | 32 | else 33 | askForContinue "${yellow_color}Your Podfile already have \'post_install\' phase. Do you want to override it? (Y/n) ${no_color}" 34 | if [ "${continue}" = "true" ]; then 35 | # Remove post_install phase first 36 | sed -i '' '/^post_install/,/^end/d' 'Podfile' 37 | addPostIstallPhase 38 | 39 | else 40 | # Need to update post_install phase 41 | printf >&2 "${yellow_color}You have to manually add those lines:${no_color}\n" 42 | printf "${_post_instal_phase}\n" 43 | fi 44 | fi 45 | fi 46 | 47 | # .gitignore Update 48 | printf >&2 "\n${blue_color}Updating .gitignore...${no_color}\n" 49 | if ! grep -q -F "Pods/" ".gitignore"; then 50 | printf "\n/Pods/\n" >> ".gitignore" 51 | elif ! grep -q -F "/Pods/" ".gitignore"; then 52 | sed -i '' 's/Pods\//\/Pods\//g' ".gitignore" 53 | fi 54 | 55 | printf >&2 "\n${blue_color}Executing 'pod install'...${no_color}\n" 56 | bash "Scripts/Cocoapods/podInstall.command" 57 | 58 | # Success 59 | printf >&2 "\n${bold_text}PROJECT SETUP SUCCESS${normal_text}\n\n" 60 | -------------------------------------------------------------------------------- /Example/Scripts/Cocoapods/podUpdate.command: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Assume scripts are placed in /Scripts/Cocoapods dir 4 | _script_call_path="${BASH_SOURCE%/*}" 5 | if [[ ! -d "${_script_call_path}" ]]; then _script_call_path=$(dirname "$0"); fi 6 | cd "${_script_call_path}" 7 | 8 | . ./utils.sh 9 | 10 | cd .. 11 | cd .. 12 | 13 | # Listing available pods 14 | echo "" 15 | echo "Pods list:" 16 | 17 | # Blue color 18 | printf '\033[0;34m' 19 | 20 | # Pods list 21 | grep -o "pod \'[a-zA-Z0-9\.\/-]*\'" Podfile | sed -e "s/^pod \'//" -e "s/\'$//" | sort -fu 22 | 23 | # No color 24 | printf '\033[0m' 25 | echo "" 26 | 27 | # Asking which one to update 28 | read -p "Which pod to update? Press enter to update all: " pod_name 29 | 30 | # Check if pod has git repository attached 31 | if [ -n "${pod_name}" ] && grep -cq "\- ${pod_name}.*(from " Podfile.lock; then 32 | # Pod has git repository attached. No need to fetch pods repo. 33 | pod update ${pod_name} --no-repo-update 34 | else 35 | # Trigger specific or all pod update 36 | pod update ${pod_name} 37 | fi 38 | 39 | echo "Fixing warnings" 40 | fixWarnings 41 | -------------------------------------------------------------------------------- /Example/Scripts/Cocoapods/utils.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Colors Constants 4 | red_color='\033[0;31m' 5 | green_color='\033[0;32m' 6 | yellow_color='\033[0;33m' 7 | blue_color='\033[0;34m' 8 | no_color='\033[0m' 9 | 10 | # Font Constants 11 | bold_text=$(tput bold) 12 | normal_text=$(tput sgr0) 13 | 14 | # First parameter - message 15 | # Second parameter - retype message. Optional. 16 | askForContinue() { 17 | local message="${1}" 18 | local retype_message="${2}" 19 | while true; do 20 | printf "${message}" 21 | read yn 22 | case $yn in 23 | [Yy]* ) continue=true; break;; 24 | [Nn]* ) continue=fase; break;; 25 | * ) [ -n "${retype_message}" ] && echo "${retype_message}";; 26 | esac 27 | done 28 | } 29 | 30 | fixWarnings() { 31 | # Project last update check fix 32 | sed -i '' -e $'s/LastUpgradeCheck = [0-9]*;/LastUpgradeCheck = 9999;\\\n\t\t\t\tLastSwiftMigration = 9999;/g' 'Pods/Pods.xcodeproj/project.pbxproj' 33 | 34 | # Schemes last update verions fix 35 | find Pods/Pods.xcodeproj/xcuserdata -type f -name '*.xcscheme' -exec sed -i '' -e 's/LastUpgradeVersion = \"[0-9]*\"/LastUpgradeVersion = \"9999\"/g' {} + 36 | } 37 | -------------------------------------------------------------------------------- /Example/StretchScrollView.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1981E400178D763E92618D81 /* Pods_StretchScrollView_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3FEFEFAD8AAFFAE83C40D7C3 /* Pods_StretchScrollView_Example.framework */; }; 11 | 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD51AFB9204008FA782 /* AppDelegate.swift */; }; 12 | 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD71AFB9204008FA782 /* ViewController.swift */; }; 13 | 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 607FACD91AFB9204008FA782 /* Main.storyboard */; }; 14 | 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDC1AFB9204008FA782 /* Images.xcassets */; }; 15 | 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */; }; 16 | 607FACEC1AFB9204008FA782 /* Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACEB1AFB9204008FA782 /* Tests.swift */; }; 17 | AE66E9E765FE48F8F42F99C7 /* Pods_StretchScrollView_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 60918A1E510DF6447EEA1A17 /* Pods_StretchScrollView_Tests.framework */; }; 18 | B078A08221ECC8E90005EC15 /* FromCodeVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B078A08121ECC8E90005EC15 /* FromCodeVC.swift */; }; 19 | B0A072CE1F39DF4A001B8CC6 /* contentMode.png in Resources */ = {isa = PBXBuildFile; fileRef = B0A072CD1F39DF4A001B8CC6 /* contentMode.png */; }; 20 | B0A072D21F39E929001B8CC6 /* constraints2.png in Resources */ = {isa = PBXBuildFile; fileRef = B0A072D11F39E929001B8CC6 /* constraints2.png */; }; 21 | B0A072D41F39EBAE001B8CC6 /* constraints.png in Resources */ = {isa = PBXBuildFile; fileRef = B0A072D31F39EBAE001B8CC6 /* constraints.png */; }; 22 | B0C2F5FA1F20FEB700805B26 /* StretchScrollView.gif in Resources */ = {isa = PBXBuildFile; fileRef = B0C2F5F91F20FEB700805B26 /* StretchScrollView.gif */; }; 23 | B0C2F5FC1F20FEE400805B26 /* customClass.png in Resources */ = {isa = PBXBuildFile; fileRef = B0C2F5FB1F20FEE400805B26 /* customClass.png */; }; 24 | B0C2F5FF1F20FF7400805B26 /* options.png in Resources */ = {isa = PBXBuildFile; fileRef = B0C2F5FD1F20FF7400805B26 /* options.png */; }; 25 | B0C2F6001F20FF7400805B26 /* outlets.png in Resources */ = {isa = PBXBuildFile; fileRef = B0C2F5FE1F20FF7400805B26 /* outlets.png */; }; 26 | /* End PBXBuildFile section */ 27 | 28 | /* Begin PBXContainerItemProxy section */ 29 | 607FACE61AFB9204008FA782 /* PBXContainerItemProxy */ = { 30 | isa = PBXContainerItemProxy; 31 | containerPortal = 607FACC81AFB9204008FA782 /* Project object */; 32 | proxyType = 1; 33 | remoteGlobalIDString = 607FACCF1AFB9204008FA782; 34 | remoteInfo = StretchScrollView; 35 | }; 36 | /* End PBXContainerItemProxy section */ 37 | 38 | /* Begin PBXFileReference section */ 39 | 0C106D0564E957A4B82F4834 /* Pods-StretchScrollView_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-StretchScrollView_Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-StretchScrollView_Tests/Pods-StretchScrollView_Tests.release.xcconfig"; sourceTree = ""; }; 40 | 0D19EB4A2625931C004850BC /* Package.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = Package.swift; path = ../Package.swift; sourceTree = ""; }; 41 | 0D19EB4B26259695004850BC /* carthageUpdate.command */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; name = carthageUpdate.command; path = ../Scripts/Carthage/carthageUpdate.command; sourceTree = ""; }; 42 | 123B7B7555C577DB358D326C /* .cocoadocs.yml */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = .cocoadocs.yml; path = ../.cocoadocs.yml; sourceTree = ""; }; 43 | 3FEFEFAD8AAFFAE83C40D7C3 /* Pods_StretchScrollView_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_StretchScrollView_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 44 | 46C606709FE24B20C39B672D /* .gitignore */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = .gitignore; path = ../.gitignore; sourceTree = ""; }; 45 | 607FACD01AFB9204008FA782 /* StretchScrollView_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = StretchScrollView_Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 46 | 607FACD41AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 47 | 607FACD51AFB9204008FA782 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 48 | 607FACD71AFB9204008FA782 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 49 | 607FACDA1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 50 | 607FACDC1AFB9204008FA782 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 51 | 607FACDF1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 52 | 607FACE51AFB9204008FA782 /* StretchScrollView_Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = StretchScrollView_Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 53 | 607FACEA1AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 54 | 607FACEB1AFB9204008FA782 /* Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tests.swift; sourceTree = ""; }; 55 | 60918A1E510DF6447EEA1A17 /* Pods_StretchScrollView_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_StretchScrollView_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 56 | 7A087634CE84488B9510DF84 /* Pods-StretchScrollView_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-StretchScrollView_Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-StretchScrollView_Tests/Pods-StretchScrollView_Tests.debug.xcconfig"; sourceTree = ""; }; 57 | 8068D7C1D602F758D1E2EA08 /* StretchScrollView.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = StretchScrollView.podspec; path = ../StretchScrollView.podspec; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 58 | 81FF47BB9B0F09FA4D544006 /* podCheck.command */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; name = podCheck.command; path = ../podCheck.command; sourceTree = ""; }; 59 | 88EFA83E35A41E80A610B851 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = ""; }; 60 | A01BC4B8417019BB3834CAF7 /* CHANGELOG.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = CHANGELOG.md; path = ../CHANGELOG.md; sourceTree = ""; }; 61 | A4D03A549CB8FAECFFEAD8CF /* Pods-StretchScrollView_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-StretchScrollView_Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-StretchScrollView_Example/Pods-StretchScrollView_Example.debug.xcconfig"; sourceTree = ""; }; 62 | B02C3D6921EC8B4C008DE799 /* DEPLOY PROCESS.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = "DEPLOY PROCESS.md"; sourceTree = ""; }; 63 | B02C3D6D21EC8C1B008DE799 /* checkBuild.command */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; name = checkBuild.command; path = ../checkBuild.command; sourceTree = ""; }; 64 | B078A08121ECC8E90005EC15 /* FromCodeVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FromCodeVC.swift; sourceTree = ""; }; 65 | B0A072CD1F39DF4A001B8CC6 /* contentMode.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = contentMode.png; sourceTree = ""; }; 66 | B0A072D11F39E929001B8CC6 /* constraints2.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = constraints2.png; sourceTree = ""; }; 67 | B0A072D31F39EBAE001B8CC6 /* constraints.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = constraints.png; sourceTree = ""; }; 68 | B0C2F5F91F20FEB700805B26 /* StretchScrollView.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = StretchScrollView.gif; sourceTree = ""; }; 69 | B0C2F5FB1F20FEE400805B26 /* customClass.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = customClass.png; sourceTree = ""; }; 70 | B0C2F5FD1F20FF7400805B26 /* options.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = options.png; sourceTree = ""; }; 71 | B0C2F5FE1F20FF7400805B26 /* outlets.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = outlets.png; sourceTree = ""; }; 72 | B4EEBC2CD7F5CD10A5AD6DA1 /* .travis.yml */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = .travis.yml; path = ../.travis.yml; sourceTree = ""; }; 73 | BD431106B83DB8A746A6DA4D /* Pods-StretchScrollView_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-StretchScrollView_Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-StretchScrollView_Example/Pods-StretchScrollView_Example.release.xcconfig"; sourceTree = ""; }; 74 | CF654993D734B5AB8BCEB020 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; 75 | F0E910E8E6A00D7C17F0567A /* podPush.command */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; name = podPush.command; path = ../podPush.command; sourceTree = ""; }; 76 | /* End PBXFileReference section */ 77 | 78 | /* Begin PBXFrameworksBuildPhase section */ 79 | 607FACCD1AFB9204008FA782 /* Frameworks */ = { 80 | isa = PBXFrameworksBuildPhase; 81 | buildActionMask = 2147483647; 82 | files = ( 83 | 1981E400178D763E92618D81 /* Pods_StretchScrollView_Example.framework in Frameworks */, 84 | ); 85 | runOnlyForDeploymentPostprocessing = 0; 86 | }; 87 | 607FACE21AFB9204008FA782 /* Frameworks */ = { 88 | isa = PBXFrameworksBuildPhase; 89 | buildActionMask = 2147483647; 90 | files = ( 91 | AE66E9E765FE48F8F42F99C7 /* Pods_StretchScrollView_Tests.framework in Frameworks */, 92 | ); 93 | runOnlyForDeploymentPostprocessing = 0; 94 | }; 95 | /* End PBXFrameworksBuildPhase section */ 96 | 97 | /* Begin PBXGroup section */ 98 | 26570C2E27F793C978C922A4 /* Frameworks */ = { 99 | isa = PBXGroup; 100 | children = ( 101 | 3FEFEFAD8AAFFAE83C40D7C3 /* Pods_StretchScrollView_Example.framework */, 102 | 60918A1E510DF6447EEA1A17 /* Pods_StretchScrollView_Tests.framework */, 103 | ); 104 | name = Frameworks; 105 | sourceTree = ""; 106 | }; 107 | 607FACC71AFB9204008FA782 = { 108 | isa = PBXGroup; 109 | children = ( 110 | 607FACF51AFB993E008FA782 /* Podspec Metadata */, 111 | 607FACD21AFB9204008FA782 /* Example for StretchScrollView */, 112 | 607FACE81AFB9204008FA782 /* Tests */, 113 | 607FACD11AFB9204008FA782 /* Products */, 114 | 7B741E49B086F6DCD1637C22 /* Pods */, 115 | 26570C2E27F793C978C922A4 /* Frameworks */, 116 | ); 117 | sourceTree = ""; 118 | }; 119 | 607FACD11AFB9204008FA782 /* Products */ = { 120 | isa = PBXGroup; 121 | children = ( 122 | 607FACD01AFB9204008FA782 /* StretchScrollView_Example.app */, 123 | 607FACE51AFB9204008FA782 /* StretchScrollView_Tests.xctest */, 124 | ); 125 | name = Products; 126 | sourceTree = ""; 127 | }; 128 | 607FACD21AFB9204008FA782 /* Example for StretchScrollView */ = { 129 | isa = PBXGroup; 130 | children = ( 131 | B06688E51F13EAB800A02878 /* _Gifs */, 132 | B06688E41F13EAB300A02878 /* _Images */, 133 | 607FACD31AFB9204008FA782 /* _Supporting Files */, 134 | 607FACD51AFB9204008FA782 /* AppDelegate.swift */, 135 | 607FACDC1AFB9204008FA782 /* Images.xcassets */, 136 | 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */, 137 | 607FACD91AFB9204008FA782 /* Main.storyboard */, 138 | 607FACD71AFB9204008FA782 /* ViewController.swift */, 139 | B078A08121ECC8E90005EC15 /* FromCodeVC.swift */, 140 | ); 141 | name = "Example for StretchScrollView"; 142 | path = StretchScrollView; 143 | sourceTree = ""; 144 | }; 145 | 607FACD31AFB9204008FA782 /* _Supporting Files */ = { 146 | isa = PBXGroup; 147 | children = ( 148 | 607FACD41AFB9204008FA782 /* Info.plist */, 149 | ); 150 | name = "_Supporting Files"; 151 | sourceTree = ""; 152 | }; 153 | 607FACE81AFB9204008FA782 /* Tests */ = { 154 | isa = PBXGroup; 155 | children = ( 156 | 607FACE91AFB9204008FA782 /* _Supporting Files */, 157 | 607FACEB1AFB9204008FA782 /* Tests.swift */, 158 | ); 159 | path = Tests; 160 | sourceTree = ""; 161 | }; 162 | 607FACE91AFB9204008FA782 /* _Supporting Files */ = { 163 | isa = PBXGroup; 164 | children = ( 165 | 607FACEA1AFB9204008FA782 /* Info.plist */, 166 | ); 167 | name = "_Supporting Files"; 168 | sourceTree = ""; 169 | }; 170 | 607FACF51AFB993E008FA782 /* Podspec Metadata */ = { 171 | isa = PBXGroup; 172 | children = ( 173 | 123B7B7555C577DB358D326C /* .cocoadocs.yml */, 174 | 46C606709FE24B20C39B672D /* .gitignore */, 175 | B4EEBC2CD7F5CD10A5AD6DA1 /* .travis.yml */, 176 | A01BC4B8417019BB3834CAF7 /* CHANGELOG.md */, 177 | B02C3D6D21EC8C1B008DE799 /* checkBuild.command */, 178 | 0D19EB4B26259695004850BC /* carthageUpdate.command */, 179 | B02C3D6921EC8B4C008DE799 /* DEPLOY PROCESS.md */, 180 | 88EFA83E35A41E80A610B851 /* LICENSE */, 181 | 81FF47BB9B0F09FA4D544006 /* podCheck.command */, 182 | F0E910E8E6A00D7C17F0567A /* podPush.command */, 183 | CF654993D734B5AB8BCEB020 /* README.md */, 184 | 8068D7C1D602F758D1E2EA08 /* StretchScrollView.podspec */, 185 | 0D19EB4A2625931C004850BC /* Package.swift */, 186 | ); 187 | name = "Podspec Metadata"; 188 | sourceTree = ""; 189 | }; 190 | 7B741E49B086F6DCD1637C22 /* Pods */ = { 191 | isa = PBXGroup; 192 | children = ( 193 | A4D03A549CB8FAECFFEAD8CF /* Pods-StretchScrollView_Example.debug.xcconfig */, 194 | BD431106B83DB8A746A6DA4D /* Pods-StretchScrollView_Example.release.xcconfig */, 195 | 7A087634CE84488B9510DF84 /* Pods-StretchScrollView_Tests.debug.xcconfig */, 196 | 0C106D0564E957A4B82F4834 /* Pods-StretchScrollView_Tests.release.xcconfig */, 197 | ); 198 | name = Pods; 199 | sourceTree = ""; 200 | }; 201 | B06688E41F13EAB300A02878 /* _Images */ = { 202 | isa = PBXGroup; 203 | children = ( 204 | B0A072D31F39EBAE001B8CC6 /* constraints.png */, 205 | B0A072D11F39E929001B8CC6 /* constraints2.png */, 206 | B0A072CD1F39DF4A001B8CC6 /* contentMode.png */, 207 | B0C2F5FB1F20FEE400805B26 /* customClass.png */, 208 | B0C2F5FD1F20FF7400805B26 /* options.png */, 209 | B0C2F5FE1F20FF7400805B26 /* outlets.png */, 210 | ); 211 | name = _Images; 212 | sourceTree = ""; 213 | }; 214 | B06688E51F13EAB800A02878 /* _Gifs */ = { 215 | isa = PBXGroup; 216 | children = ( 217 | B0C2F5F91F20FEB700805B26 /* StretchScrollView.gif */, 218 | ); 219 | name = _Gifs; 220 | sourceTree = ""; 221 | }; 222 | /* End PBXGroup section */ 223 | 224 | /* Begin PBXNativeTarget section */ 225 | 607FACCF1AFB9204008FA782 /* StretchScrollView_Example */ = { 226 | isa = PBXNativeTarget; 227 | buildConfigurationList = 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "StretchScrollView_Example" */; 228 | buildPhases = ( 229 | 64AF88E02EC04FD174EF39BB /* [CP] Check Pods Manifest.lock */, 230 | 607FACCC1AFB9204008FA782 /* Sources */, 231 | 607FACCD1AFB9204008FA782 /* Frameworks */, 232 | 607FACCE1AFB9204008FA782 /* Resources */, 233 | BCDDD009CD4E51DB49BF367A /* [CP] Embed Pods Frameworks */, 234 | ); 235 | buildRules = ( 236 | ); 237 | dependencies = ( 238 | ); 239 | name = StretchScrollView_Example; 240 | productName = StretchScrollView; 241 | productReference = 607FACD01AFB9204008FA782 /* StretchScrollView_Example.app */; 242 | productType = "com.apple.product-type.application"; 243 | }; 244 | 607FACE41AFB9204008FA782 /* StretchScrollView_Tests */ = { 245 | isa = PBXNativeTarget; 246 | buildConfigurationList = 607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "StretchScrollView_Tests" */; 247 | buildPhases = ( 248 | B3F627D9963445FFD47CEE9C /* [CP] Check Pods Manifest.lock */, 249 | 607FACE11AFB9204008FA782 /* Sources */, 250 | 607FACE21AFB9204008FA782 /* Frameworks */, 251 | 607FACE31AFB9204008FA782 /* Resources */, 252 | 47F0CAA34C0210D5A496DE33 /* [CP] Embed Pods Frameworks */, 253 | ); 254 | buildRules = ( 255 | ); 256 | dependencies = ( 257 | 607FACE71AFB9204008FA782 /* PBXTargetDependency */, 258 | ); 259 | name = StretchScrollView_Tests; 260 | productName = Tests; 261 | productReference = 607FACE51AFB9204008FA782 /* StretchScrollView_Tests.xctest */; 262 | productType = "com.apple.product-type.bundle.unit-test"; 263 | }; 264 | /* End PBXNativeTarget section */ 265 | 266 | /* Begin PBXProject section */ 267 | 607FACC81AFB9204008FA782 /* Project object */ = { 268 | isa = PBXProject; 269 | attributes = { 270 | LastSwiftUpdateCheck = 0720; 271 | LastUpgradeCheck = 1310; 272 | ORGANIZATIONNAME = CocoaPods; 273 | TargetAttributes = { 274 | 607FACCF1AFB9204008FA782 = { 275 | CreatedOnToolsVersion = 6.3.1; 276 | LastSwiftMigration = 1010; 277 | }; 278 | 607FACE41AFB9204008FA782 = { 279 | CreatedOnToolsVersion = 6.3.1; 280 | LastSwiftMigration = 1010; 281 | TestTargetID = 607FACCF1AFB9204008FA782; 282 | }; 283 | }; 284 | }; 285 | buildConfigurationList = 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "StretchScrollView" */; 286 | compatibilityVersion = "Xcode 3.2"; 287 | developmentRegion = en; 288 | hasScannedForEncodings = 0; 289 | knownRegions = ( 290 | en, 291 | Base, 292 | ); 293 | mainGroup = 607FACC71AFB9204008FA782; 294 | productRefGroup = 607FACD11AFB9204008FA782 /* Products */; 295 | projectDirPath = ""; 296 | projectRoot = ""; 297 | targets = ( 298 | 607FACCF1AFB9204008FA782 /* StretchScrollView_Example */, 299 | 607FACE41AFB9204008FA782 /* StretchScrollView_Tests */, 300 | ); 301 | }; 302 | /* End PBXProject section */ 303 | 304 | /* Begin PBXResourcesBuildPhase section */ 305 | 607FACCE1AFB9204008FA782 /* Resources */ = { 306 | isa = PBXResourcesBuildPhase; 307 | buildActionMask = 2147483647; 308 | files = ( 309 | B0C2F5FC1F20FEE400805B26 /* customClass.png in Resources */, 310 | B0A072D41F39EBAE001B8CC6 /* constraints.png in Resources */, 311 | B0A072D21F39E929001B8CC6 /* constraints2.png in Resources */, 312 | B0C2F5FA1F20FEB700805B26 /* StretchScrollView.gif in Resources */, 313 | B0C2F5FF1F20FF7400805B26 /* options.png in Resources */, 314 | B0A072CE1F39DF4A001B8CC6 /* contentMode.png in Resources */, 315 | 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */, 316 | 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */, 317 | B0C2F6001F20FF7400805B26 /* outlets.png in Resources */, 318 | 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */, 319 | ); 320 | runOnlyForDeploymentPostprocessing = 0; 321 | }; 322 | 607FACE31AFB9204008FA782 /* Resources */ = { 323 | isa = PBXResourcesBuildPhase; 324 | buildActionMask = 2147483647; 325 | files = ( 326 | ); 327 | runOnlyForDeploymentPostprocessing = 0; 328 | }; 329 | /* End PBXResourcesBuildPhase section */ 330 | 331 | /* Begin PBXShellScriptBuildPhase section */ 332 | 47F0CAA34C0210D5A496DE33 /* [CP] Embed Pods Frameworks */ = { 333 | isa = PBXShellScriptBuildPhase; 334 | buildActionMask = 2147483647; 335 | files = ( 336 | ); 337 | inputPaths = ( 338 | "${PODS_ROOT}/Target Support Files/Pods-StretchScrollView_Tests/Pods-StretchScrollView_Tests-frameworks.sh", 339 | "${BUILT_PRODUCTS_DIR}/Nimble/Nimble.framework", 340 | "${BUILT_PRODUCTS_DIR}/Nimble-Snapshots/Nimble_Snapshots.framework", 341 | "${BUILT_PRODUCTS_DIR}/Quick/Quick.framework", 342 | "${BUILT_PRODUCTS_DIR}/iOSSnapshotTestCase/FBSnapshotTestCase.framework", 343 | ); 344 | name = "[CP] Embed Pods Frameworks"; 345 | outputPaths = ( 346 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Nimble.framework", 347 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Nimble_Snapshots.framework", 348 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Quick.framework", 349 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FBSnapshotTestCase.framework", 350 | ); 351 | runOnlyForDeploymentPostprocessing = 0; 352 | shellPath = /bin/sh; 353 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-StretchScrollView_Tests/Pods-StretchScrollView_Tests-frameworks.sh\"\n"; 354 | showEnvVarsInLog = 0; 355 | }; 356 | 64AF88E02EC04FD174EF39BB /* [CP] Check Pods Manifest.lock */ = { 357 | isa = PBXShellScriptBuildPhase; 358 | buildActionMask = 2147483647; 359 | files = ( 360 | ); 361 | inputPaths = ( 362 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 363 | "${PODS_ROOT}/Manifest.lock", 364 | ); 365 | name = "[CP] Check Pods Manifest.lock"; 366 | outputPaths = ( 367 | "$(DERIVED_FILE_DIR)/Pods-StretchScrollView_Example-checkManifestLockResult.txt", 368 | ); 369 | runOnlyForDeploymentPostprocessing = 0; 370 | shellPath = /bin/sh; 371 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 372 | showEnvVarsInLog = 0; 373 | }; 374 | B3F627D9963445FFD47CEE9C /* [CP] Check Pods Manifest.lock */ = { 375 | isa = PBXShellScriptBuildPhase; 376 | buildActionMask = 2147483647; 377 | files = ( 378 | ); 379 | inputPaths = ( 380 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 381 | "${PODS_ROOT}/Manifest.lock", 382 | ); 383 | name = "[CP] Check Pods Manifest.lock"; 384 | outputPaths = ( 385 | "$(DERIVED_FILE_DIR)/Pods-StretchScrollView_Tests-checkManifestLockResult.txt", 386 | ); 387 | runOnlyForDeploymentPostprocessing = 0; 388 | shellPath = /bin/sh; 389 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 390 | showEnvVarsInLog = 0; 391 | }; 392 | BCDDD009CD4E51DB49BF367A /* [CP] Embed Pods Frameworks */ = { 393 | isa = PBXShellScriptBuildPhase; 394 | buildActionMask = 2147483647; 395 | files = ( 396 | ); 397 | inputPaths = ( 398 | "${PODS_ROOT}/Target Support Files/Pods-StretchScrollView_Example/Pods-StretchScrollView_Example-frameworks.sh", 399 | "${BUILT_PRODUCTS_DIR}/APExtensions/APExtensions.framework", 400 | "${BUILT_PRODUCTS_DIR}/BaseClasses/BaseClasses.framework", 401 | "${BUILT_PRODUCTS_DIR}/RoutableLogger/RoutableLogger.framework", 402 | "${BUILT_PRODUCTS_DIR}/StretchScrollView/StretchScrollView.framework", 403 | "${BUILT_PRODUCTS_DIR}/ViewState/ViewState.framework", 404 | ); 405 | name = "[CP] Embed Pods Frameworks"; 406 | outputPaths = ( 407 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/APExtensions.framework", 408 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/BaseClasses.framework", 409 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RoutableLogger.framework", 410 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/StretchScrollView.framework", 411 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ViewState.framework", 412 | ); 413 | runOnlyForDeploymentPostprocessing = 0; 414 | shellPath = /bin/sh; 415 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-StretchScrollView_Example/Pods-StretchScrollView_Example-frameworks.sh\"\n"; 416 | showEnvVarsInLog = 0; 417 | }; 418 | /* End PBXShellScriptBuildPhase section */ 419 | 420 | /* Begin PBXSourcesBuildPhase section */ 421 | 607FACCC1AFB9204008FA782 /* Sources */ = { 422 | isa = PBXSourcesBuildPhase; 423 | buildActionMask = 2147483647; 424 | files = ( 425 | 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */, 426 | B078A08221ECC8E90005EC15 /* FromCodeVC.swift in Sources */, 427 | 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */, 428 | ); 429 | runOnlyForDeploymentPostprocessing = 0; 430 | }; 431 | 607FACE11AFB9204008FA782 /* Sources */ = { 432 | isa = PBXSourcesBuildPhase; 433 | buildActionMask = 2147483647; 434 | files = ( 435 | 607FACEC1AFB9204008FA782 /* Tests.swift in Sources */, 436 | ); 437 | runOnlyForDeploymentPostprocessing = 0; 438 | }; 439 | /* End PBXSourcesBuildPhase section */ 440 | 441 | /* Begin PBXTargetDependency section */ 442 | 607FACE71AFB9204008FA782 /* PBXTargetDependency */ = { 443 | isa = PBXTargetDependency; 444 | target = 607FACCF1AFB9204008FA782 /* StretchScrollView_Example */; 445 | targetProxy = 607FACE61AFB9204008FA782 /* PBXContainerItemProxy */; 446 | }; 447 | /* End PBXTargetDependency section */ 448 | 449 | /* Begin PBXVariantGroup section */ 450 | 607FACD91AFB9204008FA782 /* Main.storyboard */ = { 451 | isa = PBXVariantGroup; 452 | children = ( 453 | 607FACDA1AFB9204008FA782 /* Base */, 454 | ); 455 | name = Main.storyboard; 456 | sourceTree = ""; 457 | }; 458 | 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */ = { 459 | isa = PBXVariantGroup; 460 | children = ( 461 | 607FACDF1AFB9204008FA782 /* Base */, 462 | ); 463 | name = LaunchScreen.xib; 464 | sourceTree = ""; 465 | }; 466 | /* End PBXVariantGroup section */ 467 | 468 | /* Begin XCBuildConfiguration section */ 469 | 607FACED1AFB9204008FA782 /* Debug */ = { 470 | isa = XCBuildConfiguration; 471 | buildSettings = { 472 | ALWAYS_SEARCH_USER_PATHS = NO; 473 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 474 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 475 | CLANG_CXX_LIBRARY = "libc++"; 476 | CLANG_ENABLE_MODULES = YES; 477 | CLANG_ENABLE_OBJC_ARC = YES; 478 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 479 | CLANG_WARN_BOOL_CONVERSION = YES; 480 | CLANG_WARN_COMMA = YES; 481 | CLANG_WARN_CONSTANT_CONVERSION = YES; 482 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 483 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 484 | CLANG_WARN_EMPTY_BODY = YES; 485 | CLANG_WARN_ENUM_CONVERSION = YES; 486 | CLANG_WARN_INFINITE_RECURSION = YES; 487 | CLANG_WARN_INT_CONVERSION = YES; 488 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 489 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 490 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 491 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 492 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 493 | CLANG_WARN_STRICT_PROTOTYPES = YES; 494 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 495 | CLANG_WARN_UNREACHABLE_CODE = YES; 496 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 497 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 498 | COPY_PHASE_STRIP = NO; 499 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 500 | ENABLE_STRICT_OBJC_MSGSEND = YES; 501 | ENABLE_TESTABILITY = YES; 502 | GCC_C_LANGUAGE_STANDARD = gnu99; 503 | GCC_DYNAMIC_NO_PIC = NO; 504 | GCC_NO_COMMON_BLOCKS = YES; 505 | GCC_OPTIMIZATION_LEVEL = 0; 506 | GCC_PREPROCESSOR_DEFINITIONS = ( 507 | "DEBUG=1", 508 | "$(inherited)", 509 | ); 510 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 511 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 512 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 513 | GCC_WARN_UNDECLARED_SELECTOR = YES; 514 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 515 | GCC_WARN_UNUSED_FUNCTION = YES; 516 | GCC_WARN_UNUSED_VARIABLE = YES; 517 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 518 | MTL_ENABLE_DEBUG_INFO = YES; 519 | ONLY_ACTIVE_ARCH = YES; 520 | SDKROOT = iphoneos; 521 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 522 | SWIFT_VERSION = 5.0; 523 | }; 524 | name = Debug; 525 | }; 526 | 607FACEE1AFB9204008FA782 /* Release */ = { 527 | isa = XCBuildConfiguration; 528 | buildSettings = { 529 | ALWAYS_SEARCH_USER_PATHS = NO; 530 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 531 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 532 | CLANG_CXX_LIBRARY = "libc++"; 533 | CLANG_ENABLE_MODULES = YES; 534 | CLANG_ENABLE_OBJC_ARC = YES; 535 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 536 | CLANG_WARN_BOOL_CONVERSION = YES; 537 | CLANG_WARN_COMMA = YES; 538 | CLANG_WARN_CONSTANT_CONVERSION = YES; 539 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 540 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 541 | CLANG_WARN_EMPTY_BODY = YES; 542 | CLANG_WARN_ENUM_CONVERSION = YES; 543 | CLANG_WARN_INFINITE_RECURSION = YES; 544 | CLANG_WARN_INT_CONVERSION = YES; 545 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 546 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 547 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 548 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 549 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 550 | CLANG_WARN_STRICT_PROTOTYPES = YES; 551 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 552 | CLANG_WARN_UNREACHABLE_CODE = YES; 553 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 554 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 555 | COPY_PHASE_STRIP = NO; 556 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 557 | ENABLE_NS_ASSERTIONS = NO; 558 | ENABLE_STRICT_OBJC_MSGSEND = YES; 559 | GCC_C_LANGUAGE_STANDARD = gnu99; 560 | GCC_NO_COMMON_BLOCKS = YES; 561 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 562 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 563 | GCC_WARN_UNDECLARED_SELECTOR = YES; 564 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 565 | GCC_WARN_UNUSED_FUNCTION = YES; 566 | GCC_WARN_UNUSED_VARIABLE = YES; 567 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 568 | MTL_ENABLE_DEBUG_INFO = NO; 569 | SDKROOT = iphoneos; 570 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 571 | SWIFT_VERSION = 5.0; 572 | VALIDATE_PRODUCT = YES; 573 | }; 574 | name = Release; 575 | }; 576 | 607FACF01AFB9204008FA782 /* Debug */ = { 577 | isa = XCBuildConfiguration; 578 | baseConfigurationReference = A4D03A549CB8FAECFFEAD8CF /* Pods-StretchScrollView_Example.debug.xcconfig */; 579 | buildSettings = { 580 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 581 | INFOPLIST_FILE = StretchScrollView/Info.plist; 582 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 583 | MODULE_NAME = ExampleApp; 584 | PRODUCT_BUNDLE_IDENTIFIER = "com.anton-plebanovich.StretchScrollView-Example${DEVELOPMENT_TEAM}"; 585 | PRODUCT_NAME = "$(TARGET_NAME)"; 586 | }; 587 | name = Debug; 588 | }; 589 | 607FACF11AFB9204008FA782 /* Release */ = { 590 | isa = XCBuildConfiguration; 591 | baseConfigurationReference = BD431106B83DB8A746A6DA4D /* Pods-StretchScrollView_Example.release.xcconfig */; 592 | buildSettings = { 593 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 594 | INFOPLIST_FILE = StretchScrollView/Info.plist; 595 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 596 | MODULE_NAME = ExampleApp; 597 | PRODUCT_BUNDLE_IDENTIFIER = "com.anton-plebanovich.StretchScrollView-Example${DEVELOPMENT_TEAM}"; 598 | PRODUCT_NAME = "$(TARGET_NAME)"; 599 | }; 600 | name = Release; 601 | }; 602 | 607FACF31AFB9204008FA782 /* Debug */ = { 603 | isa = XCBuildConfiguration; 604 | baseConfigurationReference = 7A087634CE84488B9510DF84 /* Pods-StretchScrollView_Tests.debug.xcconfig */; 605 | buildSettings = { 606 | FRAMEWORK_SEARCH_PATHS = "$(inherited)"; 607 | GCC_PREPROCESSOR_DEFINITIONS = ( 608 | "DEBUG=1", 609 | "$(inherited)", 610 | ); 611 | INFOPLIST_FILE = Tests/Info.plist; 612 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 613 | PRODUCT_BUNDLE_IDENTIFIER = "com.anton-plebanovich.$(PRODUCT_NAME:rfc1034identifier)${DEVELOPMENT_TEAM}"; 614 | PRODUCT_NAME = "$(TARGET_NAME)"; 615 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/StretchScrollView_Example.app/StretchScrollView_Example"; 616 | }; 617 | name = Debug; 618 | }; 619 | 607FACF41AFB9204008FA782 /* Release */ = { 620 | isa = XCBuildConfiguration; 621 | baseConfigurationReference = 0C106D0564E957A4B82F4834 /* Pods-StretchScrollView_Tests.release.xcconfig */; 622 | buildSettings = { 623 | FRAMEWORK_SEARCH_PATHS = "$(inherited)"; 624 | INFOPLIST_FILE = Tests/Info.plist; 625 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 626 | PRODUCT_BUNDLE_IDENTIFIER = "com.anton-plebanovich.$(PRODUCT_NAME:rfc1034identifier)${DEVELOPMENT_TEAM}"; 627 | PRODUCT_NAME = "$(TARGET_NAME)"; 628 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/StretchScrollView_Example.app/StretchScrollView_Example"; 629 | }; 630 | name = Release; 631 | }; 632 | /* End XCBuildConfiguration section */ 633 | 634 | /* Begin XCConfigurationList section */ 635 | 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "StretchScrollView" */ = { 636 | isa = XCConfigurationList; 637 | buildConfigurations = ( 638 | 607FACED1AFB9204008FA782 /* Debug */, 639 | 607FACEE1AFB9204008FA782 /* Release */, 640 | ); 641 | defaultConfigurationIsVisible = 0; 642 | defaultConfigurationName = Release; 643 | }; 644 | 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "StretchScrollView_Example" */ = { 645 | isa = XCConfigurationList; 646 | buildConfigurations = ( 647 | 607FACF01AFB9204008FA782 /* Debug */, 648 | 607FACF11AFB9204008FA782 /* Release */, 649 | ); 650 | defaultConfigurationIsVisible = 0; 651 | defaultConfigurationName = Release; 652 | }; 653 | 607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "StretchScrollView_Tests" */ = { 654 | isa = XCConfigurationList; 655 | buildConfigurations = ( 656 | 607FACF31AFB9204008FA782 /* Debug */, 657 | 607FACF41AFB9204008FA782 /* Release */, 658 | ); 659 | defaultConfigurationIsVisible = 0; 660 | defaultConfigurationName = Release; 661 | }; 662 | /* End XCConfigurationList section */ 663 | }; 664 | rootObject = 607FACC81AFB9204008FA782 /* Project object */; 665 | } 666 | -------------------------------------------------------------------------------- /Example/StretchScrollView.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/StretchScrollView.xcodeproj/xcshareddata/xcschemes/StretchScrollView-Example.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 51 | 52 | 53 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 76 | 78 | 84 | 85 | 86 | 87 | 93 | 95 | 101 | 102 | 103 | 104 | 106 | 107 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /Example/StretchScrollView.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Example/StretchScrollView.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/StretchScrollView.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildSystemType 6 | Original 7 | DisableBuildSystemDeprecationDiagnostic 8 | 9 | DisableBuildSystemDeprecationWarning 10 | 11 | IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded 12 | 13 | PreviewsEnabled 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /Example/StretchScrollView/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // StretchScrollView 4 | // 5 | // Created by Anton Plebanovich on 07/20/2017. 6 | // Copyright (c) 2017 Anton Plebanovich. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | var window: UIWindow? 14 | } 15 | -------------------------------------------------------------------------------- /Example/StretchScrollView/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 25 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /Example/StretchScrollView/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 66 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 176 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 392 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | -------------------------------------------------------------------------------- /Example/StretchScrollView/FromCodeVC.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FromCodeVC.swift 3 | // StretchScrollView 4 | // 5 | // Created by Anton Plebanovich on 1/14/19. 6 | // Copyright © 2019 CocoaPods. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | import APExtensions 12 | import StretchScrollView 13 | 14 | 15 | final class FromCodeVC: UIViewController { 16 | 17 | override func viewDidLoad() { 18 | super.viewDidLoad() 19 | 20 | let scrollView = StretchScrollView(frame: .zero) 21 | scrollView.translatesAutoresizingMaskIntoConstraints = false 22 | 23 | view.addSubview(scrollView) 24 | 25 | scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true 26 | scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true 27 | scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true 28 | scrollView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true 29 | 30 | let imageView = UIImageView(image: #imageLiteral(resourceName: "sarah")) 31 | imageView.translatesAutoresizingMaskIntoConstraints = false 32 | imageView.contentMode = .scaleAspectFill 33 | 34 | scrollView.addSubview(imageView) 35 | 36 | imageView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true 37 | imageView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).isActive = true 38 | imageView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor).isActive = true 39 | imageView.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true 40 | imageView.widthAnchor.constraint(equalTo: scrollView.widthAnchor).isActive = true 41 | imageView.heightAnchor.constraint(equalTo: imageView.widthAnchor).isActive = true 42 | 43 | // Should be called last 44 | scrollView.setStretchedView(imageView) 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Example/StretchScrollView/Images.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 | } -------------------------------------------------------------------------------- /Example/StretchScrollView/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Example/StretchScrollView/Images.xcassets/sarah.imageset/2670048-starcraft_sarah_kerrigan.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/APUtils/StretchScrollView/c66c6d66b6a3d0d08d9da823b103a3484556a592/Example/StretchScrollView/Images.xcassets/sarah.imageset/2670048-starcraft_sarah_kerrigan.jpg -------------------------------------------------------------------------------- /Example/StretchScrollView/Images.xcassets/sarah.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "2670048-starcraft_sarah_kerrigan.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "2670048-starcraft_sarah_kerrigan.jpg", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "2670048-starcraft_sarah_kerrigan.jpg", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/StretchScrollView/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Example/StretchScrollView/StretchScrollView.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/APUtils/StretchScrollView/c66c6d66b6a3d0d08d9da823b103a3484556a592/Example/StretchScrollView/StretchScrollView.gif -------------------------------------------------------------------------------- /Example/StretchScrollView/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // StretchScrollView 4 | // 5 | // Created by Anton Plebanovich on 07/20/2017. 6 | // Copyright (c) 2017 Anton Plebanovich. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | 12 | class ViewController: UIViewController { 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | 16 | if #available(iOS 11.0, *) { 17 | navigationController?.navigationBar.prefersLargeTitles = true 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Example/StretchScrollView/constraints.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/APUtils/StretchScrollView/c66c6d66b6a3d0d08d9da823b103a3484556a592/Example/StretchScrollView/constraints.png -------------------------------------------------------------------------------- /Example/StretchScrollView/constraints2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/APUtils/StretchScrollView/c66c6d66b6a3d0d08d9da823b103a3484556a592/Example/StretchScrollView/constraints2.png -------------------------------------------------------------------------------- /Example/StretchScrollView/contentMode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/APUtils/StretchScrollView/c66c6d66b6a3d0d08d9da823b103a3484556a592/Example/StretchScrollView/contentMode.png -------------------------------------------------------------------------------- /Example/StretchScrollView/customClass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/APUtils/StretchScrollView/c66c6d66b6a3d0d08d9da823b103a3484556a592/Example/StretchScrollView/customClass.png -------------------------------------------------------------------------------- /Example/StretchScrollView/options.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/APUtils/StretchScrollView/c66c6d66b6a3d0d08d9da823b103a3484556a592/Example/StretchScrollView/options.png -------------------------------------------------------------------------------- /Example/StretchScrollView/outlets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/APUtils/StretchScrollView/c66c6d66b6a3d0d08d9da823b103a3484556a592/Example/StretchScrollView/outlets.png -------------------------------------------------------------------------------- /Example/Tests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /Example/Tests/Tests.swift: -------------------------------------------------------------------------------- 1 | // https://github.com/Quick/Quick 2 | 3 | import Quick 4 | import Nimble 5 | import StretchScrollView 6 | 7 | class MainSpec: QuickSpec { 8 | override func spec() {} 9 | } 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017 Anton Plebanovich 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "object": { 3 | "pins": [ 4 | { 5 | "package": "RoutableLogger", 6 | "repositoryURL": "https://github.com/APUtils/LogsManager.git", 7 | "state": { 8 | "branch": null, 9 | "revision": "3a3b22fbfb5a2af934113c21001746c229bf28f2", 10 | "version": "9.1.20" 11 | } 12 | }, 13 | { 14 | "package": "ViewState", 15 | "repositoryURL": "https://github.com/APUtils/ViewState.git", 16 | "state": { 17 | "branch": null, 18 | "revision": "b85537ef5bbae93a4bf5c423b84064c2d8aaf8c9", 19 | "version": "1.2.5" 20 | } 21 | } 22 | ] 23 | }, 24 | "version": 1 25 | } 26 | -------------------------------------------------------------------------------- /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: "StretchScrollView", 8 | platforms: [ 9 | .iOS(.v9), 10 | .tvOS(.v9), 11 | ], 12 | products: [ 13 | .library( 14 | name: "StretchScrollView", 15 | targets: ["StretchScrollView"]), 16 | ], 17 | dependencies: [ 18 | .package(url: "https://github.com/APUtils/ViewState.git", .upToNextMajor(from: "1.2.3")), 19 | ], 20 | targets: [ 21 | .target( 22 | name: "StretchScrollView", 23 | dependencies: ["ViewState"], 24 | path: "StretchScrollView/Classes", 25 | exclude: []), 26 | ] 27 | ) 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # StretchScrollView 2 | 3 | [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) 4 | [![Swift Package Manager compatible](https://img.shields.io/badge/Swift%20Package%20Manager-compatible-brightgreen.svg)](https://github.com/apple/swift-package-manager) 5 | [![Version](https://img.shields.io/cocoapods/v/StretchScrollView.svg?style=flat)](http://cocoapods.org/pods/StretchScrollView) 6 | [![License](https://img.shields.io/cocoapods/l/StretchScrollView.svg?style=flat)](http://cocoapods.org/pods/StretchScrollView) 7 | [![Platform](https://img.shields.io/cocoapods/p/StretchScrollView.svg?style=flat)](http://cocoapods.org/pods/StretchScrollView) 8 | [![CI Status](http://img.shields.io/travis/APUtils/StretchScrollView.svg?style=flat)](https://travis-ci.org/APUtils/StretchScrollView) 9 | 10 | StretchScrollView provides functionality to enlarge title image and hide overlays when scrolling down. When scrolling up it allows to animate background of navigation bar. 11 | 12 | ## Example 13 | 14 | To run the example project, clone the repo, and run `pod install` from the Example directory first. 15 | 16 | ## GIF animation 17 | 18 | 19 | 20 | ## Installation 21 | 22 | #### Carthage 23 | 24 | **If you are setting `StretchScrollView` class in storyboard assure module field is also `StretchScrollView`** 25 | 26 | 27 | 28 | Please check [official guide](https://github.com/Carthage/Carthage#if-youre-building-for-ios-tvos-or-watchos) 29 | 30 | Cartfile: 31 | 32 | ``` 33 | github "APUtils/StretchScrollView" ~> 6.0 34 | ``` 35 | 36 | Install command: `carthage bootstrap --use-xcframeworks` 37 | 38 | Then add both `StretchScrollView` and `ViewState` frameworks to your project. Remove `APExtensionsViewState` dependency if you previously had it. 39 | 40 | #### CocoaPods 41 | 42 | StretchScrollView is available through [CocoaPods](http://cocoapods.org). To install 43 | it, simply add the following line to your Podfile: 44 | 45 | ```ruby 46 | pod 'StretchScrollView', '~> 6.0' 47 | ``` 48 | 49 | #### Swift Package Manager 50 | 51 | The Swift Package Manager is a tool for automating the distribution of Swift code and is integrated into the swift compiler. 52 | 53 | Once you have your Swift package set up, adding `StretchScrollView` as a dependency is as easy as adding it to the dependencies value of your `Package.swift`. 54 | 55 | ```swift 56 | dependencies: [ 57 | .package(url: "https://github.com/APUtils/StretchScrollView.git", .upToNextMajor(from: "6.0.0")) 58 | ] 59 | ``` 60 | 61 | ## Configuration 62 | 63 | Assign `StretchScrollView` class to your UIScrollView in storyboard, **assure module field is also `StretchScrollView`**: 64 | 65 | 66 | 67 | Set needed outlets and options. 68 | 69 | 70 | 71 | 72 | Usually content mode `Aspect Fill` fits well for `UIImageView`: 73 | 74 | 75 | 76 | Properly setup constraints for `stretchedView`. There are two resize modes available: by top and height constraints and by top and sides constraints. 77 | 78 | Example constraints setups: 79 | 80 | 81 | 82 | 83 | 84 | For second setup if scroll view is enlarged it'll be automatically zoomed at center. 85 | 86 | Also works when stretched view is inside `UIStackView` and have height constraint. 87 | 88 | ```swift 89 | /// StretchScrollView will manage navigation bar transparency by itself. 90 | /// You could disable this option to manage it by yourself or to disable navigation bar animations. 91 | @IBInspectable var manageNavigationBarTransparency: Bool = true 92 | 93 | /// In case of transparent navigation bar you may specify background color that will appear when you scroll up. 94 | @IBInspectable var navigationBackgroundColor: UIColor = .clear 95 | ``` 96 | 97 | You are done! See example project for more details. 98 | 99 | ## Contributions 100 | 101 | Any contribution is more than welcome! You can contribute through pull requests and issues on GitHub. 102 | 103 | ## Author 104 | 105 | Anton Plebanovich, anton.plebanovich@gmail.com 106 | 107 | ## License 108 | 109 | StretchScrollView is available under the MIT license. See the LICENSE file for more info. 110 | -------------------------------------------------------------------------------- /Scripts/Carthage/carthageAdd.command: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ### Script to add new framework to a project ### 4 | 5 | # Colors Constants 6 | red_color='\033[0;31m' 7 | green_color='\033[0;32m' 8 | blue_color='\033[0;34m' 9 | no_color='\033[0m' 10 | 11 | # Font Constants 12 | bold_text=$(tput bold) 13 | normal_text=$(tput sgr0) 14 | 15 | preserveCartfiles() { 16 | previous_cartfile=`cat "Cartfile"` 17 | previous_cartfile_resolved=`cat "Cartfile.resolved" 2>/dev/null || true` 18 | trap "restoreCartfiles" ERR 19 | trap "restoreCartfiles" INT 20 | } 21 | 22 | restoreCartfiles() { 23 | echo "$previous_cartfile" > "Cartfile" 24 | echo "$previous_cartfile_resolved" > "Cartfile.resolved" 25 | trap '' ERR 26 | trap '' INT 27 | } 28 | 29 | # Assume scripts are placed in /Scripts/Carthage dir 30 | _script_call_path="${BASH_SOURCE%/*}" 31 | if [[ ! -d "${_script_call_path}" ]]; then _script_call_path=$(dirname "$0"); fi 32 | cd "${_script_call_path}" 33 | cd .. 34 | cd .. 35 | 36 | # Try one level up if didn't find Cartfile. 37 | if [ ! -f "Cartfile" ]; then 38 | project_dir="${PWD##*/}" 39 | cd .. 40 | 41 | if [ ! -f "Cartfile" ]; then 42 | printf >&2 "\n${red_color}Unable to locate 'Cartfile'${no_color}\n\n" 43 | exit 1 44 | fi 45 | fi 46 | 47 | scripts_dir="Scripts/Carthage" 48 | 49 | github_framework=$1 50 | git_mark=$2 51 | 52 | # Requires `xcodeproj` installed - https://github.com/CocoaPods/Xcodeproj 53 | # sudo gem install xcodeproj 54 | hash xcodeproj 2>/dev/null || { printf >&2 "\n${red_color}Requires xcodeproj installed - 'sudo gem install xcodeproj'${no_color}\n\n"; exit 1; } 55 | 56 | # Any subsequent(*) commands which fail will cause the shell script to exit immediately 57 | set -e 58 | 59 | echo "" 60 | 61 | if [ -z $github_framework ]; then 62 | # Asking which one to add 63 | read -p "Specify github framework (e.g. APUtils/KeyboardAvoidingView): " github_framework 64 | fi 65 | 66 | if [ -z $git_mark ]; then 67 | # Asking additional info 68 | read -p "Specify branch (e.g. master) or tag (e.g. 1.0.0) or commit (e.g. b5f823918f7cfaf6208bd6a04b7a6b724992ff5d) or leave empty: " git_mark 69 | fi 70 | 71 | echo "" 72 | 73 | framework_name="$(echo $github_framework | cut -s -d/ -f2)" 74 | 75 | if [ -z $framework_name ]; then 76 | printf >&2 "\n${red_color}Invalid framework name${no_color}\n\n" 77 | exit 1 78 | fi 79 | 80 | # Assure Cartfile and Cartfile.resolved won't change if error occur 81 | preserveCartfiles 82 | 83 | # Add new framework entry 84 | script_separator="### SCRIPT SEPARATOR DO NOT EDIT ###" 85 | line_to_add="github \"$github_framework\"" 86 | if [ -n "$git_mark" ]; then 87 | line_to_add="$line_to_add \"$git_mark\"" 88 | fi 89 | 90 | # Check if separator exists 91 | if grep -q "$script_separator" "Cartfile"; then 92 | # Separator exists 93 | sed -i '' "s|$script_separator|$line_to_add"'\ 94 | '"$script_separator|" "Cartfile" 95 | 96 | # Sorting list 97 | separator_line=$(grep -n "$script_separator" "Cartfile" | cut -d: -f1) 98 | (head -n $(expr $separator_line - 1) | sort -fu) < "Cartfile" 1<> "Cartfile" 99 | else 100 | # Separator doesn't exist 101 | printf "\n$line_to_add" >> "Cartfile" 102 | sort -fu "Cartfile" -o "Cartfile" 103 | sed -i '' '/^$/d' "Cartfile" 104 | fi 105 | 106 | # Restore working directory 107 | if [ ! -z "${project_dir}" ]; then 108 | cd "${project_dir}" 109 | fi 110 | 111 | # Clone and build 112 | bash "$scripts_dir/carthageUpdate.command" $framework_name 113 | 114 | # Update project 115 | ruby "$scripts_dir/carthageAdd.rb" $framework_name 116 | 117 | printf >&2 "\n${bold_text}SUCCESSFULLY ADDED FRAMEWORK${normal_text}\n\n" 118 | 119 | trap '' ERR 120 | trap '' INT 121 | -------------------------------------------------------------------------------- /Scripts/Carthage/carthageAdd.rb: -------------------------------------------------------------------------------- 1 | require 'pathname' 2 | require_relative 'utils.rb' 3 | 4 | def addFrameworkToProject(project, framework_name) 5 | framework_full_name = framework_name + ".framework" 6 | framework_path = "Carthage/Build/iOS/" + framework_full_name 7 | 8 | if !File.exist?(framework_path) 9 | abort("\nFramework '#{framework_name}' doesnot exist at path '#{framework_path}'.\n".red) 10 | end 11 | 12 | # Adding to Frameworks folder and sorting 13 | frameworks_group = project.frameworks_group 14 | framework_reference = frameworks_group.new_file framework_path 15 | frameworks_group.sort 16 | 17 | # Enumberate each app target 18 | found_carthage_copy_phase = false 19 | project.targets.each do |target| 20 | target.build_phases.each do |build_phase| 21 | if build_phase.display_name == "Carthage Copy" 22 | # Adding framewok to building phase and sort 23 | target.frameworks_build_phase.add_file_reference(framework_reference) 24 | target.frameworks_build_phase.sort 25 | 26 | # Adding framework to input paths and sort 27 | build_phase.input_paths.push("$(SRCROOT)/" + framework_path) 28 | build_phase.input_paths.sort_by!(&:downcase) 29 | 30 | # Adding framework to output paths and sort 31 | build_phase.output_paths.push("$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/" + framework_full_name) 32 | build_phase.output_paths.sort_by!(&:downcase) 33 | 34 | found_carthage_copy_phase = true 35 | end 36 | end 37 | end 38 | 39 | if !found_carthage_copy_phase 40 | abort("\n'Carthage Copy' phase doesn't exist.\n".red) 41 | end 42 | end 43 | 44 | def addFrameworkWithDependenciesToProject(project, framework_name) 45 | if !framework_name 46 | framework_name = prompt "Framework name (e.g. Alamofire): " 47 | end 48 | 49 | if framework_name.to_s.empty? 50 | abort("\nFramework name is required\n".red) 51 | end 52 | 53 | all_framework_names = getSharediOSFrameworkNames(framework_name) 54 | 55 | if all_framework_names.to_s.empty? 56 | print "\n" 57 | framework_names_string = prompt "Unable to automatically locate frameworks. Please specify frameworks you want to add separating by space: " 58 | 59 | if framework_names_string.to_s.empty? 60 | abort "Framework names are required".red 61 | end 62 | 63 | framework_names = framework_names_string.split(" ") 64 | framework_names.each { |framework_name| addFrameworkToProject(project, framework_name) } 65 | 66 | elsif all_framework_names.count == 1 67 | addFrameworkToProject(project, all_framework_names.first) 68 | 69 | else 70 | print "\n" 71 | print "Available frameworks:\n" 72 | print all_framework_names.join("\n").blue 73 | print "\n" 74 | print "\n" 75 | 76 | framework_names_string = prompt "Please specify frameworks you want to add separating by space (press enter to add all): " 77 | 78 | if framework_names_string.to_s.empty? 79 | framework_names_string = all_framework_names.join(" ") 80 | end 81 | 82 | framework_names = framework_names_string.split(" ") 83 | framework_names.each { |framework_name| addFrameworkToProject(project, framework_name) } 84 | end 85 | 86 | framework_project_path = getCarthageProjectPath(framework_name) 87 | 88 | if framework_project_path.to_s.empty? 89 | return 90 | end 91 | 92 | project_dir = File.dirname(framework_project_path) 93 | framework_cartfile = Dir[project_dir + '/Cartfile'].first 94 | 95 | # Handle symlink case 96 | if !framework_names_string.to_s.empty? && File.exist?(framework_cartfile) && File.symlink?(framework_cartfile) 97 | framework_cartfile = Pathname.new(framework_cartfile).realpath 98 | end 99 | 100 | if !framework_cartfile.to_s.empty? 101 | data = File.read(framework_cartfile) 102 | unless data.nil? 103 | print "\nFramework dependencies:\n" 104 | cmd = "grep -o -E '^git.*|^binary.*' #{framework_cartfile} | sed -E 's/(github \"|git \"|binary \")//' | sed -e 's/\".*//' | sed -e 's/^.*\\\///' -e 's/\".*//' -e 's/.json//' | sort -fu" 105 | print (%x[ #{cmd} ]).blue 106 | print "\n" 107 | framework_names_string = prompt "Please specify dependencies you want to add separating by space (press enter to skip): " 108 | framework_names = framework_names_string.split(" ") 109 | framework_names.each { |framework_name| addFrameworkWithDependenciesToProject(project, framework_name) } 110 | end 111 | end 112 | end 113 | 114 | 115 | project_path = Dir['*.xcodeproj'].first 116 | project = Xcodeproj::Project.open(project_path) 117 | 118 | framework_name = ARGV[0] 119 | 120 | if framework_name.end_with?('.framework') 121 | addFrameworkToProject(project, framework_name.gsub('.framework', '')) 122 | else 123 | addFrameworkWithDependenciesToProject(project, framework_name) 124 | end 125 | 126 | # Save 127 | project.save 128 | -------------------------------------------------------------------------------- /Scripts/Carthage/carthageInstall.command: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ### Script to install frameworks ### 4 | 5 | # Any subsequent(*) commands which fail will cause the shell script to exit immediately 6 | set -e 7 | 8 | declare -a tests_frameworks=("github \"Quick\/Nimble\"" "github \"Quick\/Quick\"" "github \"uber\/ios-snapshot-test-case\"" "github \"ashfurrow\/Nimble-Snapshots\"") 9 | 10 | disableTestsFramework() { 11 | previous_cartfile=`cat "Cartfile.resolved"` 12 | for i in "${tests_frameworks[@]}"; do 13 | sed -i '' "/$i/d" "Cartfile.resolved" 14 | done 15 | trap "enableTestsFramework" ERR 16 | trap "enableTestsFramework" INT 17 | } 18 | 19 | enableTestsFramework() { 20 | echo "$previous_cartfile" > "Cartfile.resolved" 21 | trap '' ERR 22 | trap '' INT 23 | } 24 | 25 | # Assume scripts are placed in /Scripts/Carthage dir 26 | _script_call_path="${BASH_SOURCE%/*}" 27 | if [[ ! -d "${_script_call_path}" ]]; then _script_call_path=$(dirname "$0"); fi 28 | cd "${_script_call_path}" 29 | 30 | # includes 31 | . ./utils.sh 32 | 33 | cd .. 34 | cd .. 35 | 36 | applyXcode12Workaround 37 | 38 | # Try one level up if didn't find Cartfile. 39 | if [ ! -f "Cartfile" ]; then 40 | cd .. 41 | 42 | if [ ! -f "Cartfile" ]; then 43 | printf >&2 "\n${red_color}Unable to locate 'Cartfile'${no_color}\n\n" 44 | exit 1 45 | fi 46 | fi 47 | 48 | mkdir -p "Carthage" 49 | touch "Carthage/cartSum.txt" 50 | if [ ! -f "Carthage/cartSum.txt" ]; then 51 | prevSum="null"; 52 | else 53 | prevSum=`cat Carthage/cartSum.txt`; 54 | fi 55 | 56 | # Get checksum 57 | cartSum=`{ cat Cartfile.resolved; xcrun swift -version; } | md5` 58 | 59 | if [ "$prevSum" != "$cartSum" ] || [ ! -d "Carthage/Build/iOS" ]; then 60 | echo "Carthage frameworks are outdated. Updating..." 61 | rm "$cart_sum_file" 2> /dev/null || : 62 | 63 | # Install main app frameworks. Ignore tests frameworks. 64 | disableTestsFramework 65 | carthage bootstrap --use-xcframeworks --platform iOS,tvOS --cache-builds 66 | enableTestsFramework 67 | echo "" 68 | 69 | # Update checksum file 70 | cartSum=`{ cat Cartfile.resolved; xcrun swift -version; } | md5` 71 | echo $cartSum > Carthage/cartSum.txt 72 | else 73 | echo "Carthage frameworks up to date" 74 | fi 75 | -------------------------------------------------------------------------------- /Scripts/Carthage/carthageInstallTests.command: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ### Script to install frameworks ### 4 | 5 | # Any subsequent(*) commands which fail will cause the shell script to exit immediately 6 | set -e 7 | 8 | # Assume scripts are placed in /Scripts/Carthage dir 9 | _script_call_path="${BASH_SOURCE%/*}" 10 | if [[ ! -d "${_script_call_path}" ]]; then _script_call_path=$(dirname "$0"); fi 11 | cd "${_script_call_path}" 12 | 13 | # includes 14 | . ./utils.sh 15 | 16 | cd .. 17 | cd .. 18 | 19 | applyXcode12Workaround 20 | 21 | # Try one level up if didn't find Cartfile. 22 | if [ ! -f "Cartfile" ]; then 23 | cd .. 24 | 25 | if [ ! -f "Cartfile" ]; then 26 | printf >&2 "\n${red_color}Unable to locate 'Cartfile'${no_color}\n\n" 27 | exit 1 28 | fi 29 | fi 30 | 31 | cart_sum_file="Carthage/cartSumTests.txt" 32 | 33 | mkdir -p "Carthage" 34 | touch "$cart_sum_file" 35 | if [ ! -f "$cart_sum_file" ]; then 36 | prevSum="null" 37 | else 38 | prevSum=`cat $cart_sum_file` 39 | fi 40 | 41 | # Get checksum 42 | cartSum=`{ cat Cartfile.resolved; xcrun swift -version; } | md5` 43 | 44 | if [ "$prevSum" != "$cartSum" ] || [ ! -d "Carthage/Build/iOS" ]; then 45 | echo "Carthage frameworks are outdated. Updating..." 46 | rm "$cart_sum_file" 2> /dev/null || : 47 | 48 | # Install needed frameworks. 49 | carthage bootstrap --use-xcframeworks --platform iOS,tvOS --cache-builds 50 | 51 | # Update checksum file 52 | cartSum=`{ cat Cartfile.resolved; xcrun swift -version; } | md5` 53 | echo "$cartSum" > "$cart_sum_file" 54 | else 55 | echo "Carthage frameworks up to date" 56 | fi 57 | -------------------------------------------------------------------------------- /Scripts/Carthage/carthageRemove.command: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ### Script to remove framework ### 4 | 5 | # Assume scripts are placed in /Scripts/Carthage dir 6 | _script_call_path="${BASH_SOURCE%/*}" 7 | if [[ ! -d "${_script_call_path}" ]]; then _script_call_path=$(dirname "$0"); fi 8 | cd "${_script_call_path}" 9 | 10 | . "utils.sh" 11 | 12 | # Font Constants 13 | bold_text=$(tput bold) 14 | normal_text=$(tput sgr0) 15 | 16 | cd .. 17 | cd .. 18 | 19 | # Try one level up if didn't find Cartfile. 20 | if [ ! -f "Cartfile" ]; then 21 | project_dir="${PWD##*/}" 22 | cd .. 23 | 24 | if [ ! -f "Cartfile" ]; then 25 | printf >&2 "\n${red_color}Unable to locate 'Cartfile'${no_color}\n\n" 26 | exit 1 27 | fi 28 | fi 29 | 30 | scripts_dir="Scripts/Carthage" 31 | 32 | # Requires `xcodeproj` installed - https://github.com/CocoaPods/Xcodeproj 33 | # sudo gem install xcodeproj 34 | hash xcodeproj 2>/dev/null || { printf >&2 "\n${red_color}Requires xcodeproj installed - 'sudo gem install xcodeproj'${no_color}\n\n"; exit 1; } 35 | 36 | # Any subsequent(*) commands which fail will cause the shell script to exit immediately 37 | set -e 38 | 39 | echo "" 40 | 41 | framework_name=$1 42 | 43 | if [ -z $framework_name ]; then 44 | # Listing available frameworks 45 | getAllFrameworks 46 | 47 | # Asking which one to update 48 | read -p "Which framework to remove? " framework_name 49 | fi 50 | 51 | # Restore working directory 52 | if [ ! -z "${project_dir}" ]; then 53 | cd "${project_dir}" 54 | fi 55 | 56 | if [ -z $framework_name ]; then 57 | printf >&2 "\n${red_color}Invalid framework name${no_color}\n\n" 58 | exit 1 59 | elif [[ $frameworks_list = *$framework_name* ]]; then 60 | echo "" 61 | echo "Removing $framework_name from project..." 62 | 63 | ruby "$scripts_dir/carthageRemove.rb" $framework_name 64 | else 65 | printf >&2 "\n${red_color}Invalid framework name${no_color}\n\n" 66 | exit 1 67 | fi 68 | 69 | # Update Carthage files 70 | echo "Removing $framework_name from Carthage..." 71 | sed -i '' "/\/$framework_name\"/d" Cartfile 72 | sed -i '' "/\/$framework_name\"/d" Cartfile.resolved 73 | 74 | # Update md5 check sum 75 | cartSum=`{ cat Cartfile.resolved; xcrun swift -version; } | md5` 76 | echo $cartSum > Carthage/cartSum.txt 77 | 78 | printf >&2 "\n${bold_text}SUCCESSFULLY REMOVED FRAMEWORK${normal_text}\n\n" 79 | -------------------------------------------------------------------------------- /Scripts/Carthage/carthageRemove.rb: -------------------------------------------------------------------------------- 1 | require_relative 'utils.rb' 2 | 3 | def removeFramework(project, framework_name) 4 | framework_full_name = framework_name + ".framework" 5 | framework_path = "Carthage/Build/iOS/" + framework_full_name 6 | frameworks_reference = project.frameworks_group 7 | framework_reference = frameworks_reference[framework_full_name] 8 | 9 | # Enumerate each app target 10 | project.targets.each do |target| 11 | target.build_phases.each do |build_phase| 12 | if build_phase.display_name == "Carthage Copy" 13 | # Deleting framework from output paths and sorting 14 | build_phase.output_paths.delete("$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/" + framework_full_name) 15 | build_phase.output_paths.sort_by!(&:downcase) 16 | 17 | # Deleting framework from input paths and sorting 18 | build_phase.input_paths.delete("$(SRCROOT)/" + framework_path) 19 | build_phase.input_paths.sort_by!(&:downcase) 20 | 21 | # Deleting framewok from building phase and sorting 22 | target.frameworks_build_phase.remove_file_reference(framework_reference) 23 | target.frameworks_build_phase.sort 24 | end 25 | end 26 | end 27 | 28 | # Removing from Frameworks folder and sorting 29 | framework_reference.build_files.each { |file| file.remove_from_project } 30 | framework_reference&.remove_from_project 31 | frameworks_reference.sort 32 | end 33 | 34 | framework_name = ARGV[0] 35 | 36 | if !framework_name 37 | framework_name = prompt "Framework name (e.g. Alamofire): " 38 | end 39 | 40 | if framework_name.to_s.empty? 41 | abort("\nFramework name is required\n".red) 42 | end 43 | 44 | project_path = Dir['*.xcodeproj'].first 45 | project = Xcodeproj::Project.open(project_path) 46 | 47 | all_framework_names = getSharediOSFrameworkNames(framework_name) 48 | if all_framework_names.empty? 49 | abort("\nFramework wasn't found\n".red) 50 | 51 | elsif all_framework_names.count == 1 52 | removeFramework(project, all_framework_names.first) 53 | 54 | else 55 | print "\n" 56 | print "Available frameworks:\n" 57 | print all_framework_names.join("\n").blue 58 | print "\n" 59 | print "\n" 60 | 61 | framework_names_string = prompt "Please specify frameworks you want to remove separating by space (press enter to remove all): " 62 | 63 | if framework_names_string.to_s.empty? 64 | framework_names_string = all_framework_names.join(" ") 65 | end 66 | 67 | framework_names = framework_names_string.split(" ") 68 | framework_names.each { |framework_name| removeFramework(project, framework_name) } 69 | end 70 | 71 | framework_project_path = getCarthageProjectPath(framework_name) 72 | project_dir = File.dirname(framework_project_path) 73 | framework_cartfile = Dir[project_dir + '/Cartfile'].first 74 | if !framework_cartfile.to_s.empty? 75 | data = File.read(framework_cartfile) 76 | unless data.nil? 77 | print "\nFramework dependencies:\n" 78 | cmd = "grep -o -E '^git.*|^binary.*' #{framework_cartfile} | sed -E 's/(github \"|git \"|binary \")//' | sed -e 's/\".*//' | sed -e 's/^.*\\\///' -e 's/\".*//' -e 's/.json//' | sort -fu" 79 | print (%x[ #{cmd} ]).blue 80 | print "\n" 81 | framework_names_string = prompt "Please specify dependencies you want to remove separating by space (press enter to skip): " 82 | framework_names = framework_names_string.split(" ") 83 | framework_names.each { |framework_name| removeFramework(project, framework_name) } 84 | end 85 | end 86 | 87 | # Save 88 | project.save 89 | -------------------------------------------------------------------------------- /Scripts/Carthage/carthageSetup.command: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ### Script to setup Carthage for a project target ### 4 | 5 | # Colors Constants 6 | red_color='\033[0;31m' 7 | green_color='\033[0;32m' 8 | yellow_color='\033[0;33m' 9 | blue_color='\033[0;34m' 10 | no_color='\033[0m' 11 | 12 | # Font Constants 13 | bold_text=$(tput bold) 14 | normal_text=$(tput sgr0) 15 | 16 | # Assume scripts are placed in /Scripts/Carthage dir 17 | _script_call_path="${BASH_SOURCE%/*}" 18 | if [[ ! -d "${_script_call_path}" ]]; then _script_call_path=$(dirname "$0"); fi 19 | cd "${_script_call_path}" 20 | cd .. 21 | cd .. 22 | 23 | # Requires `xcodeproj` installed - https://github.com/CocoaPods/Xcodeproj 24 | # sudo gem install xcodeproj 25 | hash xcodeproj 2>/dev/null || { printf >&2 "\n${red_color}Requires xcodeproj installed - 'sudo gem install xcodeproj'${no_color}\n\n"; exit 1; } 26 | 27 | # Any subsequent(*) commands which fail will cause the shell script to exit immediately 28 | set -e 29 | 30 | # Project Update 31 | touch Cartfile 32 | ruby "Scripts/Carthage/carthageSetup.rb" 33 | 34 | # .gitignore Update 35 | printf >&2 "${blue_color}Updating .gitignore...${no_color}\n" 36 | if ! grep -q -F "Carthage/" ".gitignore"; then 37 | printf "\n/Carthage/\n" >> ".gitignore" 38 | elif ! grep -q -F "/Carthage/" ".gitignore"; then 39 | sed -i '' 's/Carthage\//\/Carthage\//g' ".gitignore" 40 | fi 41 | 42 | # Success 43 | printf >&2 "\n${bold_text}PROJECT SETUP SUCCESS${normal_text}\n\n" 44 | -------------------------------------------------------------------------------- /Scripts/Carthage/carthageSetup.rb: -------------------------------------------------------------------------------- 1 | begin 2 | require 'xcodeproj' 3 | rescue LoadError => e 4 | raise unless e.message =~ /some_gem/ 5 | puts 'please install xcodeproj first!' 6 | end 7 | 8 | # Input 9 | def prompt(*args) 10 | print(*args) 11 | STDIN.gets.strip 12 | end 13 | 14 | def setupTarget(target) 15 | puts "Updating '#{target.name}' target...".blue 16 | # Framework search path 17 | puts "Updating framework search paths...".blue 18 | if !target.common_resolved_build_setting("FRAMEWORK_SEARCH_PATHS")&.include?("$(PROJECT_DIR)/Carthage/Build/iOS") 19 | target.build_configurations.each { |build_configuration| 20 | framework_search_paths = build_configuration.build_settings["FRAMEWORK_SEARCH_PATHS"] 21 | if framework_search_paths 22 | framework_search_paths << "$(PROJECT_DIR)/Carthage/Build/iOS" 23 | puts framework_search_paths 24 | build_configuration.build_settings["FRAMEWORK_SEARCH_PATHS"] = framework_search_paths 25 | else 26 | build_configuration.build_settings["FRAMEWORK_SEARCH_PATHS"] = ["$(inherited)", "$(PROJECT_DIR)/Carthage/Build/iOS"] 27 | end 28 | } 29 | end 30 | 31 | # Carthage Install 32 | puts "Updating 'Carthage Install' build phase...".blue 33 | carthage_install_build_phase = target.shell_script_build_phases.detect { |x| x.name == "Carthage Install" || x.shell_script.include?("carthageInstall.command") } 34 | if !carthage_install_build_phase 35 | carthage_install_build_phase = target.new_shell_script_build_phase("Carthage Install") 36 | end 37 | carthage_install_build_phase.name = "Carthage Install" 38 | carthage_install_build_phase.shell_path = '/bin/bash' 39 | carthage_install_build_phase.shell_script = "source ~/.bash_profile\nenv -i GITHUB_ACCESS_TOKEN=\"$GITHUB_ACCESS_TOKEN\" DEVELOPER_DIR=\"$DEVELOPER_DIR\" PATH=\"$PATH\" bash \"Scripts/Carthage/carthageInstall.command\"\n" 40 | target.build_phases.move(carthage_install_build_phase, 0) 41 | 42 | 43 | # Carthage Copy 44 | puts "Updating 'Carthage Copy' build phase...".blue 45 | carthge_copy_build_phase = target.shell_script_build_phases.detect { |x| x.name == "Carthage Copy" || x.shell_script.include?("/usr/local/bin/carthage copy-frameworks") } 46 | if !carthge_copy_build_phase 47 | carthge_copy_build_phase = target.new_shell_script_build_phase("Carthage Copy") 48 | end 49 | carthge_copy_build_phase.name = "Carthage Copy" 50 | carthge_copy_build_phase.shell_path = '/bin/sh' 51 | carthge_copy_build_phase.shell_script = "/usr/local/bin/carthage copy-frameworks\n" 52 | end 53 | 54 | # Colorization 55 | class String 56 | def colorize(color_code) 57 | "\e[#{color_code}m#{self}\e[0m" 58 | end 59 | 60 | def red 61 | colorize(31) 62 | end 63 | 64 | def green 65 | colorize(32) 66 | end 67 | 68 | def yellow 69 | colorize(33) 70 | end 71 | 72 | def blue 73 | colorize(34) 74 | end 75 | 76 | def light_blue 77 | colorize(36) 78 | end 79 | end 80 | 81 | target_names = ARGV[0]&.split(' ') 82 | 83 | project_path = Dir['*.xcodeproj'].first 84 | project = Xcodeproj::Project.open(project_path) 85 | 86 | # Create _Carthage folder with script files 87 | puts "Updating '_Carthage' directory and scripts...".blue 88 | carthage_folder = project.frameworks_group['_Carthage'] || project.frameworks_group.new_group('_Carthage') 89 | project.frameworks_group.sort() 90 | if !carthage_folder['carthageAdd.command'] 91 | carthage_folder.new_file('Scripts/Carthage/carthageAdd.command') 92 | end 93 | if !carthage_folder['carthageRemove.command'] 94 | carthage_folder.new_file('Scripts/Carthage/carthageRemove.command') 95 | end 96 | if !carthage_folder['carthageUpdate.command'] 97 | carthage_folder.new_file('Scripts/Carthage/carthageUpdate.command') 98 | end 99 | carthage_folder.sort 100 | 101 | if !target_names 102 | all_target_names = project.native_targets.map { |native_target| native_target.name } 103 | 104 | print "\n" 105 | print "Available targets:\n" 106 | print all_target_names.join("\n").blue 107 | print "\n" 108 | print "\n" 109 | 110 | target_names_to_setup = prompt "Please specify targets you want to setup separating by comma: " 111 | target_names = target_names_to_setup.split(',') 112 | 113 | if target_names.to_s.empty? 114 | abort("\Target name is required\n".red) 115 | end 116 | end 117 | 118 | targets_to_setup = project.native_targets.select { |native_target| target_names.include?(native_target.name) } 119 | targets_to_setup.each { |target| setupTarget(target) } 120 | 121 | # Save 122 | project.save 123 | -------------------------------------------------------------------------------- /Scripts/Carthage/carthageUpdate.command: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ### Script to update frameworks ### 4 | 5 | # Xcodeproj is required 6 | hash xcodeproj 2>/dev/null || { printf >&2 "\n${red_color}Xcodeproj is required. Run 'sudo gem install xcodeproj'${no_color}\n\n"; exit 1; } 7 | 8 | # Any subsequent(*) commands which fail will cause the shell script to exit immediately 9 | set -e 10 | 11 | # Assume scripts are placed in /Scripts/Carthage dir 12 | _script_call_path="${BASH_SOURCE%/*}" 13 | if [[ ! -d "${_script_call_path}" ]]; then _script_call_path=$(dirname "$0"); fi 14 | cd "${_script_call_path}" 15 | 16 | # includes 17 | . ./utils.sh 18 | 19 | cd .. 20 | cd .. 21 | 22 | applyXcode12Workaround 23 | 24 | # Try one level up if didn't find Cartfile. 25 | if [ ! -f "Cartfile" ]; then 26 | project_dir="${PWD##*/}" 27 | cd .. 28 | 29 | if [ ! -f "Cartfile" ]; then 30 | printf >&2 "\n${red_color}Unable to locate 'Cartfile'${no_color}\n\n" 31 | exit 1 32 | fi 33 | fi 34 | 35 | framework_name=$1 36 | 37 | if [ -z $framework_name ]; then 38 | # Listing available frameworks 39 | getAllFrameworks 40 | 41 | # Asking which one to update 42 | read -p "Which framework to update? You can enter several separating with space. Press enter to update all: " framework_name 43 | fi 44 | 45 | # Update framework(s) 46 | echo "Synchronizing Carthage dependencies..." 47 | carthage update ${framework_name} --use-xcframeworks --platform iOS,tvOS --cache-builds 48 | echo "" 49 | 50 | # Update md5 check sum 51 | cartSum=`{ cat Cartfile.resolved; xcrun swift -version; } | md5` 52 | cart_sum_file='Carthage/cartSum.txt' 53 | if [ -f "${cart_sum_file}" ]; then 54 | echo "${cartSum}" > "${cart_sum_file}" 55 | fi 56 | -------------------------------------------------------------------------------- /Scripts/Carthage/utils.rb: -------------------------------------------------------------------------------- 1 | begin 2 | require 'xcodeproj' 3 | rescue LoadError => e 4 | raise unless e.message =~ /some_gem/ 5 | puts 'please install xcodeproj first!' 6 | end 7 | 8 | # Input 9 | def prompt(*args) 10 | print(*args) 11 | STDIN.gets.strip 12 | end 13 | 14 | class Xcodeproj::Project::Object::PBXNativeTarget 15 | def iOSSharedFramework?(framework_shared_schemes) 16 | isIOS = common_resolved_build_setting("SUPPORTED_PLATFORMS")&.include?("iphoneos") || platform_name == :ios 17 | 18 | # Check target configuration file also 19 | isIOS = isIOS || getConfigAttributes(self)&.dig("SUPPORTED_PLATFORMS")&.include?("iphoneos") 20 | 21 | # CHECK INCLUDES ALSO OMG WHY?! Defenitelly need to improve xcodeproj to resolve those settings properly. I'm out. 22 | 23 | isFramework = symbol_type == :framework 24 | isShared = framework_shared_schemes.include?(name) 25 | 26 | isIOS && isFramework && isShared 27 | end 28 | end 29 | 30 | # Returns file config attributes for a target 31 | def getConfigAttributes(framework_target) 32 | default_configuration = framework_target.build_configuration_list[framework_target.build_configuration_list.default_configuration_name] 33 | base_configuration_reference = default_configuration.base_configuration_reference 34 | if !base_configuration_reference&.real_path.to_s.empty? && File.file?(base_configuration_reference.real_path) 35 | config = Xcodeproj::Config.new(base_configuration_reference.real_path) 36 | config.attributes 37 | else 38 | return nil 39 | end 40 | end 41 | 42 | # Returns shared iOS framework names 43 | def getSharediOSFrameworkNames(framework_name) 44 | # TODO: Need to handle multiple projects 45 | framework_project_path = getCarthageProjectPath(framework_name) 46 | 47 | if framework_project_path.to_s.empty? 48 | return nil 49 | end 50 | 51 | framework_project = Xcodeproj::Project.open(framework_project_path) 52 | framework_shared_schemes = Xcodeproj::Project.schemes(framework_project_path) 53 | framework_targets = framework_project.native_targets.select { |framework_target| framework_target.iOSSharedFramework?(framework_shared_schemes) } 54 | all_framework_names = framework_targets.map { |framework_target| 55 | # Check target configuration file first 56 | framework_name = getConfigAttributes(framework_target)&.dig("PRODUCT_NAME")&.delete! ';' 57 | 58 | if framework_name.to_s.empty? 59 | framework_name = framework_target.common_resolved_build_setting("PRODUCT_NAME") 60 | end 61 | 62 | if framework_name == '$(TARGET_NAME)' 63 | framework_name = framework_target.name 64 | elsif framework_name == '$(TARGET_NAME:c99extidentifier)' 65 | # TODO: Add full support for 'c99extidentifier' if needed 66 | framework_name = framework_target.name 67 | elsif framework_name == '$(PROJECT_NAME)' 68 | framework_name = File.basename(framework_project_path, ".*") 69 | end 70 | 71 | framework_name 72 | } 73 | 74 | return all_framework_names 75 | end 76 | 77 | # Returns Project with shared iOS schemes 78 | def getCarthageProjectPath(framework_name) 79 | framework_project_paths = Dir['Carthage/Checkouts/' + framework_name + '/**/*.xcodeproj'] 80 | 81 | if framework_project_paths.empty? 82 | abort("\nCan't find framework project\n".red) 83 | end 84 | 85 | framework_project_paths.each { |framework_project_path| 86 | # Get proper targets 87 | framework_shared_schemes = Xcodeproj::Project.schemes(framework_project_path) 88 | framework_project = Xcodeproj::Project.open(framework_project_path) 89 | framework_targets = framework_project.native_targets.select { |framework_target| framework_target.iOSSharedFramework?(framework_shared_schemes) } 90 | 91 | if framework_targets.any? 92 | return framework_project_path 93 | end 94 | } 95 | 96 | return nil 97 | end 98 | 99 | # Colorization 100 | class String 101 | def colorize(color_code) 102 | "\e[#{color_code}m#{self}\e[0m" 103 | end 104 | 105 | def red 106 | colorize(31) 107 | end 108 | 109 | def green 110 | colorize(32) 111 | end 112 | 113 | def yellow 114 | colorize(33) 115 | end 116 | 117 | def blue 118 | colorize(34) 119 | end 120 | 121 | def light_blue 122 | colorize(36) 123 | end 124 | end 125 | -------------------------------------------------------------------------------- /Scripts/Carthage/utils.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ### Script to remove framework ### 4 | 5 | # Colors Constants 6 | red_color='\033[0;31m' 7 | green_color='\033[0;32m' 8 | blue_color='\033[0;34m' 9 | no_color='\033[0m' 10 | 11 | getFrameworks() { 12 | file_name="${1}" 13 | grep -o -E "^git.*|^binary.*" "${file_name}" | sed -E "s/(github \"|git \"|binary \")//" | sed -e "s/\".*//" | sed -e "s/^.*\///" -e "s/\".*//" -e "s/.json//" 14 | } 15 | 16 | getAllFrameworks() { 17 | echo "" 18 | echo "Frameworks list:" 19 | 20 | # Blue color 21 | printf '\033[0;34m' 22 | 23 | if [ -f "Cartfile" ]; then 24 | public_frameworks=$(getFrameworks Cartfile) 25 | fi 26 | 27 | if [ -f "Cartfile.private" ]; then 28 | private_frameworks=$(getFrameworks Cartfile.private) 29 | fi 30 | 31 | frameworks_list=$(echo -e "${public_frameworks}\n${private_frameworks}" | sort -fu | sed '/^$/d') 32 | printf "$frameworks_list\n" 33 | 34 | # No color 35 | printf '\033[0m' 36 | echo "" 37 | } 38 | 39 | # https://github.com/mapbox/mapbox-navigation-ios/blob/master/scripts/wcarthage.sh 40 | applyXcode12Workaround() { 41 | echo "Applying Xcode 12 workaround..." 42 | 43 | echo "Cleanup Carthage temporary items" 44 | for i in {1..1000}; do 45 | dir_name="${TMPDIR}TemporaryItems/(A Document Being Saved By carthage ${i})" 46 | [ -e "${dir_name}" ] && rm -rf "${dir_name}" || true 47 | done 48 | 49 | xcconfig=$(mktemp /tmp/static.xcconfig.XXXXXX) 50 | trap 'rm -f "${xcconfig}"' INT TERM HUP EXIT 51 | 52 | # For Xcode 12 make sure EXCLUDED_ARCHS is set to arm architectures otherwise 53 | # the build will fail on lipo due to duplicate architectures. 54 | echo 'EXCLUDED_ARCHS__EFFECTIVE_PLATFORM_SUFFIX_simulator__NATIVE_ARCH_64_BIT_x86_64__XCODE_1200 = arm64 arm64e armv7 armv7s armv6 armv8' >> $xcconfig 55 | echo 'EXCLUDED_ARCHS__EFFECTIVE_PLATFORM_SUFFIX_simulator__NATIVE_ARCH_64_BIT_x86_64__XCODE_1300 = arm64 arm64e armv7 armv7s armv6 armv8' >> $xcconfig 56 | echo 'EXCLUDED_ARCHS = $(inherited) $(EXCLUDED_ARCHS__EFFECTIVE_PLATFORM_SUFFIX_$(EFFECTIVE_PLATFORM_SUFFIX)__NATIVE_ARCH_64_BIT_$(NATIVE_ARCH_64_BIT)__XCODE_$(XCODE_VERSION_MAJOR))' >> $xcconfig 57 | 58 | export XCODE_XCCONFIG_FILE="${xcconfig}" 59 | echo "Workaround applied. xcconfig here: ${XCODE_XCCONFIG_FILE}" 60 | } 61 | -------------------------------------------------------------------------------- /StretchScrollView tvOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | 22 | 23 | -------------------------------------------------------------------------------- /StretchScrollView tvOS/StretchScrollView_tvOS.h: -------------------------------------------------------------------------------- 1 | // 2 | // StretchScrollView_tvOS.h 3 | // StretchScrollView tvOS 4 | // 5 | // Created by Anton Plebanovich on 4/13/21. 6 | // Copyright © 2021 Anton Plebanovich. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for StretchScrollView_tvOS. 12 | FOUNDATION_EXPORT double StretchScrollView_tvOSVersionNumber; 13 | 14 | //! Project version string for StretchScrollView_tvOS. 15 | FOUNDATION_EXPORT const unsigned char StretchScrollView_tvOSVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /StretchScrollView.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod lib lint StretchScrollView.podspec` to ensure this is a 3 | # valid spec before submitting. 4 | # 5 | # Any lines starting with a # are optional, but their use is encouraged 6 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | s.name = 'StretchScrollView' 11 | s.version = '6.0.0' 12 | s.summary = 'ScrollView that allows to stretch it`s image' 13 | 14 | # This description is used to generate tags and improve search results. 15 | # * Think: What does it do? Why did you write it? What is the focus? 16 | # * Try to keep it short, snappy and to the point. 17 | # * Write the description between the DESC delimiters below. 18 | # * Finally, don't worry about the indent, CocoaPods strips it! 19 | 20 | s.description = <<-DESC 21 | StretchScrollView provides functionality to enlarge title image and hide overlays when scrolling down. When scrolling up it allows to animate background of navigation bar. 22 | DESC 23 | 24 | s.homepage = 'https://github.com/APUtils/StretchScrollView' 25 | # s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2' 26 | s.license = { :type => 'MIT', :file => 'LICENSE' } 27 | s.author = { 'Anton Plebanovich' => 'anton.plebanovich@gmail.com' } 28 | s.source = { :git => 'https://github.com/APUtils/StretchScrollView.git', :tag => s.version.to_s } 29 | # s.social_media_url = 'https://twitter.com/' 30 | 31 | s.ios.deployment_target = '9.0' 32 | s.tvos.deployment_target = '9.0' 33 | s.swift_versions = ['5.1'] 34 | 35 | s.source_files = 'StretchScrollView/Classes/**/*' 36 | 37 | # s.resource_bundles = { 38 | # 'StretchScrollView' => ['StretchScrollView/Assets/*.png'] 39 | # } 40 | 41 | # s.public_header_files = 'Pod/Classes/**/*.h' 42 | s.frameworks = 'Foundation', 'UIKit' 43 | s.dependency 'ViewState', '>= 1.0.0' 44 | end 45 | -------------------------------------------------------------------------------- /StretchScrollView.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 52; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 0D19EB2B2625876E004850BC /* StretchScrollView_tvOS.h in Headers */ = {isa = PBXBuildFile; fileRef = 0D19EB292625876E004850BC /* StretchScrollView_tvOS.h */; settings = {ATTRIBUTES = (Public, ); }; }; 11 | 0D19EB3126258776004850BC /* StretchScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B02C3D7221EC9AC8008DE799 /* StretchScrollView.swift */; }; 12 | 0D19EB3226258776004850BC /* UIScrollView+Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0F1C4A821ED30580032088C /* UIScrollView+Utils.swift */; }; 13 | 0D19EB3326258776004850BC /* UIView+Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = B02C3D6F21EC9AC8008DE799 /* UIView+Utils.swift */; }; 14 | 0D19EB3426258776004850BC /* UIViewController+Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = B02C3D7121EC9AC8008DE799 /* UIViewController+Utils.swift */; }; 15 | 0D19EB3526258776004850BC /* CGRect+Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0F1C4A421ED2FEE0032088C /* CGRect+Utils.swift */; }; 16 | 0DF48EE92745FABB009B373F /* ViewState.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0DF48EE82745FABB009B373F /* ViewState.xcframework */; }; 17 | 0DF48EEA2745FABB009B373F /* ViewState.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0DF48EE82745FABB009B373F /* ViewState.xcframework */; }; 18 | B02C3D7321EC9AC8008DE799 /* UIView+Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = B02C3D6F21EC9AC8008DE799 /* UIView+Utils.swift */; }; 19 | B02C3D7521EC9AC8008DE799 /* UIViewController+Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = B02C3D7121EC9AC8008DE799 /* UIViewController+Utils.swift */; }; 20 | B02C3D7621EC9AC8008DE799 /* StretchScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B02C3D7221EC9AC8008DE799 /* StretchScrollView.swift */; }; 21 | B02C3D7721EC9AE1008DE799 /* StretchScrollView.swift in Headers */ = {isa = PBXBuildFile; fileRef = B02C3D7221EC9AC8008DE799 /* StretchScrollView.swift */; settings = {ATTRIBUTES = (Public, ); }; }; 22 | B0C6EAFF21E8D467004664FF /* StretchScrollView.h in Headers */ = {isa = PBXBuildFile; fileRef = B0C6EAFD21E8D467004664FF /* StretchScrollView.h */; settings = {ATTRIBUTES = (Public, ); }; }; 23 | B0F1C4A621ED2FEE0032088C /* CGRect+Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0F1C4A421ED2FEE0032088C /* CGRect+Utils.swift */; }; 24 | B0F1C4A921ED30580032088C /* UIScrollView+Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0F1C4A821ED30580032088C /* UIScrollView+Utils.swift */; }; 25 | /* End PBXBuildFile section */ 26 | 27 | /* Begin PBXFileReference section */ 28 | 0D19EB272625876E004850BC /* StretchScrollView.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = StretchScrollView.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 29 | 0D19EB292625876E004850BC /* StretchScrollView_tvOS.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = StretchScrollView_tvOS.h; sourceTree = ""; }; 30 | 0D19EB2A2625876E004850BC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 31 | 0DF48EE82745FABB009B373F /* ViewState.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = ViewState.xcframework; path = Carthage/Build/ViewState.xcframework; sourceTree = ""; }; 32 | 0FE4C5426D9336ED3448EF31 /* carthageUpdate.command */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; name = carthageUpdate.command; path = Scripts/Carthage/carthageUpdate.command; sourceTree = ""; }; 33 | 17095833951C17C99BC3BEED /* carthageRemove.command */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; name = carthageRemove.command; path = Scripts/Carthage/carthageRemove.command; sourceTree = ""; }; 34 | B02C3D6F21EC9AC8008DE799 /* UIView+Utils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+Utils.swift"; sourceTree = ""; }; 35 | B02C3D7121EC9AC8008DE799 /* UIViewController+Utils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIViewController+Utils.swift"; sourceTree = ""; }; 36 | B02C3D7221EC9AC8008DE799 /* StretchScrollView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StretchScrollView.swift; sourceTree = ""; }; 37 | B0C6EAFA21E8D467004664FF /* StretchScrollView.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = StretchScrollView.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 38 | B0C6EAFD21E8D467004664FF /* StretchScrollView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = StretchScrollView.h; sourceTree = ""; }; 39 | B0C6EAFE21E8D467004664FF /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 40 | B0F1C4A421ED2FEE0032088C /* CGRect+Utils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CGRect+Utils.swift"; sourceTree = ""; }; 41 | B0F1C4A821ED30580032088C /* UIScrollView+Utils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIScrollView+Utils.swift"; sourceTree = ""; }; 42 | FB3A6DB403898FAF9B36C60C /* carthageAdd.command */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; name = carthageAdd.command; path = Scripts/Carthage/carthageAdd.command; sourceTree = ""; }; 43 | /* End PBXFileReference section */ 44 | 45 | /* Begin PBXFrameworksBuildPhase section */ 46 | 0D19EB242625876E004850BC /* Frameworks */ = { 47 | isa = PBXFrameworksBuildPhase; 48 | buildActionMask = 2147483647; 49 | files = ( 50 | 0DF48EEA2745FABB009B373F /* ViewState.xcframework in Frameworks */, 51 | ); 52 | runOnlyForDeploymentPostprocessing = 0; 53 | }; 54 | B0C6EAF721E8D467004664FF /* Frameworks */ = { 55 | isa = PBXFrameworksBuildPhase; 56 | buildActionMask = 2147483647; 57 | files = ( 58 | 0DF48EE92745FABB009B373F /* ViewState.xcframework in Frameworks */, 59 | ); 60 | runOnlyForDeploymentPostprocessing = 0; 61 | }; 62 | /* End PBXFrameworksBuildPhase section */ 63 | 64 | /* Begin PBXGroup section */ 65 | 0D19EB282625876E004850BC /* StretchScrollView tvOS */ = { 66 | isa = PBXGroup; 67 | children = ( 68 | 0D19EB292625876E004850BC /* StretchScrollView_tvOS.h */, 69 | 0D19EB2A2625876E004850BC /* Info.plist */, 70 | ); 71 | path = "StretchScrollView tvOS"; 72 | sourceTree = ""; 73 | }; 74 | B02C3D6E21EC9AC8008DE799 /* Classes */ = { 75 | isa = PBXGroup; 76 | children = ( 77 | B0F1C4A421ED2FEE0032088C /* CGRect+Utils.swift */, 78 | B02C3D7221EC9AC8008DE799 /* StretchScrollView.swift */, 79 | B0F1C4A821ED30580032088C /* UIScrollView+Utils.swift */, 80 | B02C3D6F21EC9AC8008DE799 /* UIView+Utils.swift */, 81 | B02C3D7121EC9AC8008DE799 /* UIViewController+Utils.swift */, 82 | ); 83 | path = Classes; 84 | sourceTree = ""; 85 | }; 86 | B0C6EAF021E8D467004664FF = { 87 | isa = PBXGroup; 88 | children = ( 89 | B0C6EAFC21E8D467004664FF /* StretchScrollView */, 90 | 0D19EB282625876E004850BC /* StretchScrollView tvOS */, 91 | B0C6EAFB21E8D467004664FF /* Products */, 92 | DA5CA6E4FF0DB59F4937D477 /* Frameworks */, 93 | ); 94 | sourceTree = ""; 95 | }; 96 | B0C6EAFB21E8D467004664FF /* Products */ = { 97 | isa = PBXGroup; 98 | children = ( 99 | B0C6EAFA21E8D467004664FF /* StretchScrollView.framework */, 100 | 0D19EB272625876E004850BC /* StretchScrollView.framework */, 101 | ); 102 | name = Products; 103 | sourceTree = ""; 104 | }; 105 | B0C6EAFC21E8D467004664FF /* StretchScrollView */ = { 106 | isa = PBXGroup; 107 | children = ( 108 | B02C3D6E21EC9AC8008DE799 /* Classes */, 109 | B0C6EAFD21E8D467004664FF /* StretchScrollView.h */, 110 | B0C6EAFE21E8D467004664FF /* Info.plist */, 111 | ); 112 | path = StretchScrollView; 113 | sourceTree = ""; 114 | }; 115 | DA5CA6E4FF0DB59F4937D477 /* Frameworks */ = { 116 | isa = PBXGroup; 117 | children = ( 118 | E4B03C2B739E2F10FF5C1301 /* _Carthage */, 119 | 0DF48EE82745FABB009B373F /* ViewState.xcframework */, 120 | ); 121 | name = Frameworks; 122 | sourceTree = ""; 123 | }; 124 | E4B03C2B739E2F10FF5C1301 /* _Carthage */ = { 125 | isa = PBXGroup; 126 | children = ( 127 | FB3A6DB403898FAF9B36C60C /* carthageAdd.command */, 128 | 17095833951C17C99BC3BEED /* carthageRemove.command */, 129 | 0FE4C5426D9336ED3448EF31 /* carthageUpdate.command */, 130 | ); 131 | name = _Carthage; 132 | sourceTree = ""; 133 | }; 134 | /* End PBXGroup section */ 135 | 136 | /* Begin PBXHeadersBuildPhase section */ 137 | 0D19EB222625876E004850BC /* Headers */ = { 138 | isa = PBXHeadersBuildPhase; 139 | buildActionMask = 2147483647; 140 | files = ( 141 | 0D19EB2B2625876E004850BC /* StretchScrollView_tvOS.h in Headers */, 142 | ); 143 | runOnlyForDeploymentPostprocessing = 0; 144 | }; 145 | B0C6EAF521E8D467004664FF /* Headers */ = { 146 | isa = PBXHeadersBuildPhase; 147 | buildActionMask = 2147483647; 148 | files = ( 149 | B0C6EAFF21E8D467004664FF /* StretchScrollView.h in Headers */, 150 | B02C3D7721EC9AE1008DE799 /* StretchScrollView.swift in Headers */, 151 | ); 152 | runOnlyForDeploymentPostprocessing = 0; 153 | }; 154 | /* End PBXHeadersBuildPhase section */ 155 | 156 | /* Begin PBXNativeTarget section */ 157 | 0D19EB262625876E004850BC /* StretchScrollView tvOS */ = { 158 | isa = PBXNativeTarget; 159 | buildConfigurationList = 0D19EB2C2625876E004850BC /* Build configuration list for PBXNativeTarget "StretchScrollView tvOS" */; 160 | buildPhases = ( 161 | 0D19EB222625876E004850BC /* Headers */, 162 | 0D19EB232625876E004850BC /* Sources */, 163 | 0D19EB242625876E004850BC /* Frameworks */, 164 | 0D19EB252625876E004850BC /* Resources */, 165 | ); 166 | buildRules = ( 167 | ); 168 | dependencies = ( 169 | ); 170 | name = "StretchScrollView tvOS"; 171 | productName = "StretchScrollView tvOS"; 172 | productReference = 0D19EB272625876E004850BC /* StretchScrollView.framework */; 173 | productType = "com.apple.product-type.framework"; 174 | }; 175 | B0C6EAF921E8D467004664FF /* StretchScrollView */ = { 176 | isa = PBXNativeTarget; 177 | buildConfigurationList = B0C6EB0221E8D467004664FF /* Build configuration list for PBXNativeTarget "StretchScrollView" */; 178 | buildPhases = ( 179 | B0C6EAF521E8D467004664FF /* Headers */, 180 | B0C6EAF621E8D467004664FF /* Sources */, 181 | B0C6EAF721E8D467004664FF /* Frameworks */, 182 | B0C6EAF821E8D467004664FF /* Resources */, 183 | ); 184 | buildRules = ( 185 | ); 186 | dependencies = ( 187 | ); 188 | name = StretchScrollView; 189 | productName = StretchScrollView; 190 | productReference = B0C6EAFA21E8D467004664FF /* StretchScrollView.framework */; 191 | productType = "com.apple.product-type.framework"; 192 | }; 193 | /* End PBXNativeTarget section */ 194 | 195 | /* Begin PBXProject section */ 196 | B0C6EAF121E8D467004664FF /* Project object */ = { 197 | isa = PBXProject; 198 | attributes = { 199 | LastUpgradeCheck = 1310; 200 | ORGANIZATIONNAME = "Anton Plebanovich"; 201 | TargetAttributes = { 202 | 0D19EB262625876E004850BC = { 203 | CreatedOnToolsVersion = 12.4; 204 | }; 205 | B0C6EAF921E8D467004664FF = { 206 | CreatedOnToolsVersion = 10.1; 207 | LastSwiftMigration = 1130; 208 | }; 209 | }; 210 | }; 211 | buildConfigurationList = B0C6EAF421E8D467004664FF /* Build configuration list for PBXProject "StretchScrollView" */; 212 | compatibilityVersion = "Xcode 9.3"; 213 | developmentRegion = en; 214 | hasScannedForEncodings = 0; 215 | knownRegions = ( 216 | en, 217 | Base, 218 | ); 219 | mainGroup = B0C6EAF021E8D467004664FF; 220 | productRefGroup = B0C6EAFB21E8D467004664FF /* Products */; 221 | projectDirPath = ""; 222 | projectRoot = ""; 223 | targets = ( 224 | B0C6EAF921E8D467004664FF /* StretchScrollView */, 225 | 0D19EB262625876E004850BC /* StretchScrollView tvOS */, 226 | ); 227 | }; 228 | /* End PBXProject section */ 229 | 230 | /* Begin PBXResourcesBuildPhase section */ 231 | 0D19EB252625876E004850BC /* Resources */ = { 232 | isa = PBXResourcesBuildPhase; 233 | buildActionMask = 2147483647; 234 | files = ( 235 | ); 236 | runOnlyForDeploymentPostprocessing = 0; 237 | }; 238 | B0C6EAF821E8D467004664FF /* Resources */ = { 239 | isa = PBXResourcesBuildPhase; 240 | buildActionMask = 2147483647; 241 | files = ( 242 | ); 243 | runOnlyForDeploymentPostprocessing = 0; 244 | }; 245 | /* End PBXResourcesBuildPhase section */ 246 | 247 | /* Begin PBXSourcesBuildPhase section */ 248 | 0D19EB232625876E004850BC /* Sources */ = { 249 | isa = PBXSourcesBuildPhase; 250 | buildActionMask = 2147483647; 251 | files = ( 252 | 0D19EB3426258776004850BC /* UIViewController+Utils.swift in Sources */, 253 | 0D19EB3126258776004850BC /* StretchScrollView.swift in Sources */, 254 | 0D19EB3326258776004850BC /* UIView+Utils.swift in Sources */, 255 | 0D19EB3526258776004850BC /* CGRect+Utils.swift in Sources */, 256 | 0D19EB3226258776004850BC /* UIScrollView+Utils.swift in Sources */, 257 | ); 258 | runOnlyForDeploymentPostprocessing = 0; 259 | }; 260 | B0C6EAF621E8D467004664FF /* Sources */ = { 261 | isa = PBXSourcesBuildPhase; 262 | buildActionMask = 2147483647; 263 | files = ( 264 | B02C3D7521EC9AC8008DE799 /* UIViewController+Utils.swift in Sources */, 265 | B0F1C4A621ED2FEE0032088C /* CGRect+Utils.swift in Sources */, 266 | B02C3D7621EC9AC8008DE799 /* StretchScrollView.swift in Sources */, 267 | B0F1C4A921ED30580032088C /* UIScrollView+Utils.swift in Sources */, 268 | B02C3D7321EC9AC8008DE799 /* UIView+Utils.swift in Sources */, 269 | ); 270 | runOnlyForDeploymentPostprocessing = 0; 271 | }; 272 | /* End PBXSourcesBuildPhase section */ 273 | 274 | /* Begin XCBuildConfiguration section */ 275 | 0D19EB2D2625876E004850BC /* Debug */ = { 276 | isa = XCBuildConfiguration; 277 | buildSettings = { 278 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 279 | CODE_SIGN_STYLE = Automatic; 280 | DEFINES_MODULE = YES; 281 | DYLIB_COMPATIBILITY_VERSION = 1; 282 | DYLIB_CURRENT_VERSION = 1; 283 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 284 | INFOPLIST_FILE = "StretchScrollView tvOS/Info.plist"; 285 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 286 | LD_RUNPATH_SEARCH_PATHS = ( 287 | "$(inherited)", 288 | "@executable_path/Frameworks", 289 | "@loader_path/Frameworks", 290 | ); 291 | PRODUCT_BUNDLE_IDENTIFIER = "com.anton-plebanovich.StretchScrollView"; 292 | PRODUCT_NAME = StretchScrollView; 293 | SDKROOT = appletvos; 294 | SKIP_INSTALL = YES; 295 | SWIFT_VERSION = 5.0; 296 | TARGETED_DEVICE_FAMILY = 3; 297 | }; 298 | name = Debug; 299 | }; 300 | 0D19EB2E2625876E004850BC /* Release */ = { 301 | isa = XCBuildConfiguration; 302 | buildSettings = { 303 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 304 | CODE_SIGN_STYLE = Automatic; 305 | DEFINES_MODULE = YES; 306 | DYLIB_COMPATIBILITY_VERSION = 1; 307 | DYLIB_CURRENT_VERSION = 1; 308 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 309 | INFOPLIST_FILE = "StretchScrollView tvOS/Info.plist"; 310 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 311 | LD_RUNPATH_SEARCH_PATHS = ( 312 | "$(inherited)", 313 | "@executable_path/Frameworks", 314 | "@loader_path/Frameworks", 315 | ); 316 | PRODUCT_BUNDLE_IDENTIFIER = "com.anton-plebanovich.StretchScrollView"; 317 | PRODUCT_NAME = StretchScrollView; 318 | SDKROOT = appletvos; 319 | SKIP_INSTALL = YES; 320 | SWIFT_VERSION = 5.0; 321 | TARGETED_DEVICE_FAMILY = 3; 322 | }; 323 | name = Release; 324 | }; 325 | B0C6EB0021E8D467004664FF /* Debug */ = { 326 | isa = XCBuildConfiguration; 327 | buildSettings = { 328 | ALWAYS_SEARCH_USER_PATHS = NO; 329 | CLANG_ANALYZER_NONNULL = YES; 330 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 331 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 332 | CLANG_CXX_LIBRARY = "libc++"; 333 | CLANG_ENABLE_MODULES = YES; 334 | CLANG_ENABLE_OBJC_ARC = YES; 335 | CLANG_ENABLE_OBJC_WEAK = YES; 336 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 337 | CLANG_WARN_BOOL_CONVERSION = YES; 338 | CLANG_WARN_COMMA = YES; 339 | CLANG_WARN_CONSTANT_CONVERSION = YES; 340 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 341 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 342 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 343 | CLANG_WARN_EMPTY_BODY = YES; 344 | CLANG_WARN_ENUM_CONVERSION = YES; 345 | CLANG_WARN_INFINITE_RECURSION = YES; 346 | CLANG_WARN_INT_CONVERSION = YES; 347 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 348 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 349 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 350 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 351 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 352 | CLANG_WARN_STRICT_PROTOTYPES = YES; 353 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 354 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 355 | CLANG_WARN_UNREACHABLE_CODE = YES; 356 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 357 | CODE_SIGN_IDENTITY = "iPhone Developer"; 358 | COPY_PHASE_STRIP = NO; 359 | CURRENT_PROJECT_VERSION = 1; 360 | DEBUG_INFORMATION_FORMAT = dwarf; 361 | ENABLE_STRICT_OBJC_MSGSEND = YES; 362 | ENABLE_TESTABILITY = YES; 363 | FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/Carthage/Build"; 364 | GCC_C_LANGUAGE_STANDARD = gnu11; 365 | GCC_DYNAMIC_NO_PIC = NO; 366 | GCC_NO_COMMON_BLOCKS = YES; 367 | GCC_OPTIMIZATION_LEVEL = 0; 368 | GCC_PREPROCESSOR_DEFINITIONS = ( 369 | "DEBUG=1", 370 | "$(inherited)", 371 | ); 372 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 373 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 374 | GCC_WARN_UNDECLARED_SELECTOR = YES; 375 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 376 | GCC_WARN_UNUSED_FUNCTION = YES; 377 | GCC_WARN_UNUSED_VARIABLE = YES; 378 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 379 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 380 | MTL_FAST_MATH = YES; 381 | ONLY_ACTIVE_ARCH = YES; 382 | SDKROOT = iphoneos; 383 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 384 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 385 | SWIFT_VERSION = 5.0; 386 | TVOS_DEPLOYMENT_TARGET = 9.0; 387 | VERSIONING_SYSTEM = "apple-generic"; 388 | VERSION_INFO_PREFIX = ""; 389 | }; 390 | name = Debug; 391 | }; 392 | B0C6EB0121E8D467004664FF /* Release */ = { 393 | isa = XCBuildConfiguration; 394 | buildSettings = { 395 | ALWAYS_SEARCH_USER_PATHS = NO; 396 | CLANG_ANALYZER_NONNULL = YES; 397 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 398 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 399 | CLANG_CXX_LIBRARY = "libc++"; 400 | CLANG_ENABLE_MODULES = YES; 401 | CLANG_ENABLE_OBJC_ARC = YES; 402 | CLANG_ENABLE_OBJC_WEAK = YES; 403 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 404 | CLANG_WARN_BOOL_CONVERSION = YES; 405 | CLANG_WARN_COMMA = YES; 406 | CLANG_WARN_CONSTANT_CONVERSION = YES; 407 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 408 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 409 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 410 | CLANG_WARN_EMPTY_BODY = YES; 411 | CLANG_WARN_ENUM_CONVERSION = YES; 412 | CLANG_WARN_INFINITE_RECURSION = YES; 413 | CLANG_WARN_INT_CONVERSION = YES; 414 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 415 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 416 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 417 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 418 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 419 | CLANG_WARN_STRICT_PROTOTYPES = YES; 420 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 421 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 422 | CLANG_WARN_UNREACHABLE_CODE = YES; 423 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 424 | CODE_SIGN_IDENTITY = "iPhone Developer"; 425 | COPY_PHASE_STRIP = NO; 426 | CURRENT_PROJECT_VERSION = 1; 427 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 428 | ENABLE_NS_ASSERTIONS = NO; 429 | ENABLE_STRICT_OBJC_MSGSEND = YES; 430 | FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/Carthage/Build"; 431 | GCC_C_LANGUAGE_STANDARD = gnu11; 432 | GCC_NO_COMMON_BLOCKS = YES; 433 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 434 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 435 | GCC_WARN_UNDECLARED_SELECTOR = YES; 436 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 437 | GCC_WARN_UNUSED_FUNCTION = YES; 438 | GCC_WARN_UNUSED_VARIABLE = YES; 439 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 440 | MTL_ENABLE_DEBUG_INFO = NO; 441 | MTL_FAST_MATH = YES; 442 | SDKROOT = iphoneos; 443 | SWIFT_COMPILATION_MODE = wholemodule; 444 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 445 | SWIFT_VERSION = 5.0; 446 | TVOS_DEPLOYMENT_TARGET = 9.0; 447 | VALIDATE_PRODUCT = YES; 448 | VERSIONING_SYSTEM = "apple-generic"; 449 | VERSION_INFO_PREFIX = ""; 450 | }; 451 | name = Release; 452 | }; 453 | B0C6EB0321E8D467004664FF /* Debug */ = { 454 | isa = XCBuildConfiguration; 455 | buildSettings = { 456 | CODE_SIGN_IDENTITY = ""; 457 | CODE_SIGN_STYLE = Automatic; 458 | DEFINES_MODULE = YES; 459 | DYLIB_COMPATIBILITY_VERSION = 1; 460 | DYLIB_CURRENT_VERSION = 1; 461 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 462 | INFOPLIST_FILE = StretchScrollView/Info.plist; 463 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 464 | LD_RUNPATH_SEARCH_PATHS = ( 465 | "$(inherited)", 466 | "@executable_path/Frameworks", 467 | "@loader_path/Frameworks", 468 | ); 469 | PRODUCT_BUNDLE_IDENTIFIER = "com.anton-plebanovich.StretchScrollView"; 470 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 471 | SKIP_INSTALL = YES; 472 | TARGETED_DEVICE_FAMILY = "1,2"; 473 | }; 474 | name = Debug; 475 | }; 476 | B0C6EB0421E8D467004664FF /* Release */ = { 477 | isa = XCBuildConfiguration; 478 | buildSettings = { 479 | CODE_SIGN_IDENTITY = ""; 480 | CODE_SIGN_STYLE = Automatic; 481 | DEFINES_MODULE = YES; 482 | DYLIB_COMPATIBILITY_VERSION = 1; 483 | DYLIB_CURRENT_VERSION = 1; 484 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 485 | INFOPLIST_FILE = StretchScrollView/Info.plist; 486 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 487 | LD_RUNPATH_SEARCH_PATHS = ( 488 | "$(inherited)", 489 | "@executable_path/Frameworks", 490 | "@loader_path/Frameworks", 491 | ); 492 | PRODUCT_BUNDLE_IDENTIFIER = "com.anton-plebanovich.StretchScrollView"; 493 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 494 | SKIP_INSTALL = YES; 495 | TARGETED_DEVICE_FAMILY = "1,2"; 496 | }; 497 | name = Release; 498 | }; 499 | /* End XCBuildConfiguration section */ 500 | 501 | /* Begin XCConfigurationList section */ 502 | 0D19EB2C2625876E004850BC /* Build configuration list for PBXNativeTarget "StretchScrollView tvOS" */ = { 503 | isa = XCConfigurationList; 504 | buildConfigurations = ( 505 | 0D19EB2D2625876E004850BC /* Debug */, 506 | 0D19EB2E2625876E004850BC /* Release */, 507 | ); 508 | defaultConfigurationIsVisible = 0; 509 | defaultConfigurationName = Release; 510 | }; 511 | B0C6EAF421E8D467004664FF /* Build configuration list for PBXProject "StretchScrollView" */ = { 512 | isa = XCConfigurationList; 513 | buildConfigurations = ( 514 | B0C6EB0021E8D467004664FF /* Debug */, 515 | B0C6EB0121E8D467004664FF /* Release */, 516 | ); 517 | defaultConfigurationIsVisible = 0; 518 | defaultConfigurationName = Release; 519 | }; 520 | B0C6EB0221E8D467004664FF /* Build configuration list for PBXNativeTarget "StretchScrollView" */ = { 521 | isa = XCConfigurationList; 522 | buildConfigurations = ( 523 | B0C6EB0321E8D467004664FF /* Debug */, 524 | B0C6EB0421E8D467004664FF /* Release */, 525 | ); 526 | defaultConfigurationIsVisible = 0; 527 | defaultConfigurationName = Release; 528 | }; 529 | /* End XCConfigurationList section */ 530 | }; 531 | rootObject = B0C6EAF121E8D467004664FF /* Project object */; 532 | } 533 | -------------------------------------------------------------------------------- /StretchScrollView.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /StretchScrollView.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /StretchScrollView.xcodeproj/xcshareddata/xcschemes/StretchScrollView.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 50 | 51 | 52 | 53 | 59 | 60 | 66 | 67 | 68 | 69 | 71 | 72 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /StretchScrollView/Assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/APUtils/StretchScrollView/c66c6d66b6a3d0d08d9da823b103a3484556a592/StretchScrollView/Assets/.gitkeep -------------------------------------------------------------------------------- /StretchScrollView/Classes/CGRect+Utils.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CGRect+Utils.swift 3 | // StretchScrollView 4 | // 5 | // Created by Anton Plebanovich on 1/14/19. 6 | // Copyright © 2019 Anton Plebanovich. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | 12 | extension CGRect { 13 | /// Center point 14 | var _center: CGPoint { 15 | get { 16 | return CGPoint(x: midX, y: midY) 17 | } 18 | set { 19 | origin.x = newValue.x - width / 2 20 | origin.y = newValue.y - height / 2 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /StretchScrollView/Classes/StretchScrollView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // StretchScrollView.swift 3 | // StretchScrollView 4 | // 5 | // Created by Anton Plebanovich on 7/14/17. 6 | // Copyright © 2017 Anton Plebanovich. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import ViewState 11 | 12 | //----------------------------------------------------------------------------- 13 | // MARK: - Constants 14 | //----------------------------------------------------------------------------- 15 | 16 | private let FadeOutOffset: CGFloat = 60 17 | private let NavigationFadeInFinishOffset: CGFloat = 60 18 | 19 | //----------------------------------------------------------------------------- 20 | // MARK: - Class Implementation 21 | //----------------------------------------------------------------------------- 22 | 23 | /// Provides functionality to enlarge title image and hide overlays when scrolling down. When scrolling up it allows to 24 | /// animate background of navigation bar. 25 | /// - note: Title image constraints/fill mode should be configured properly for resizing to work. Controller configures 26 | /// top and height constraints only. 27 | public class StretchScrollView: UIScrollView { 28 | 29 | //----------------------------------------------------------------------------- 30 | // MARK: - Enums 31 | //----------------------------------------------------------------------------- 32 | 33 | enum ResizeType { 34 | case none 35 | case topAndHeight(topConstraint: NSLayoutConstraint, heightConstraint: NSLayoutConstraint, defaultHeight: CGFloat) 36 | case topAndSides(topConstraint: NSLayoutConstraint, leftConstraint: NSLayoutConstraint, rightConstraint: NSLayoutConstraint, aspectRatio: CGFloat) 37 | 38 | var isNone: Bool { 39 | switch self { 40 | case .none: return true 41 | default: return false 42 | } 43 | } 44 | } 45 | 46 | //----------------------------------------------------------------------------- 47 | // MARK: - @IBInspectable 48 | //----------------------------------------------------------------------------- 49 | 50 | /// StretchScrollView will manage navigation bar transparency by itself. 51 | /// You could disable this option to manage it by yourself or to disable navigation bar animations. 52 | /// Default is `true`. 53 | @IBInspectable var manageNavigationBarTransparency: Bool = true 54 | 55 | /// In case of transparent navigation bar you may specify background color that will appear when you scroll up. 56 | /// Default is clear color. 57 | @IBInspectable var navigationBackgroundColor: UIColor = .clear 58 | 59 | //----------------------------------------------------------------------------- 60 | // MARK: - @IBOutlets 61 | //----------------------------------------------------------------------------- 62 | 63 | @IBOutlet private weak var stretchedView: UIView? 64 | @IBOutlet private var fadeViews: [UIView]? 65 | 66 | //----------------------------------------------------------------------------- 67 | // MARK: - Private properties 68 | //----------------------------------------------------------------------------- 69 | 70 | private var resizeType: ResizeType = .none 71 | private var _stretchedView: UIView? 72 | private var _fadeViews = NSHashTable(options: [.weakMemory]) 73 | private var isSetupDone = false 74 | 75 | private var navigationControllerView: UIView? { 76 | return _viewController?.navigationController?.view 77 | } 78 | 79 | private var navigationBar: UINavigationBar? { 80 | return _viewController?.navigationController?.navigationBar 81 | } 82 | 83 | private lazy var navigationBarBackgroundView: UIView = { 84 | let navigationBarBackgroundView = UIView() 85 | navigationBarBackgroundView.isUserInteractionEnabled = false 86 | navigationBarBackgroundView.backgroundColor = navigationBackgroundColor 87 | navigationBarBackgroundView.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 64) 88 | navigationBarBackgroundView.autoresizingMask = [.flexibleWidth] 89 | 90 | return navigationBarBackgroundView 91 | }() 92 | 93 | //----------------------------------------------------------------------------- 94 | // MARK: - Initialization and Setup 95 | //----------------------------------------------------------------------------- 96 | 97 | deinit { 98 | navigationBarBackgroundView.removeFromSuperview() 99 | } 100 | 101 | override public func awakeFromNib() { 102 | super.awakeFromNib() 103 | 104 | if stretchedView != nil { 105 | // Setup from storybord flow 106 | setup() 107 | } 108 | } 109 | 110 | private func setup() { 111 | guard !isSetupDone else { 112 | print("StretchScrollView: Setup shouldn't be called twice") 113 | return 114 | } 115 | 116 | ViewState.setupOnce() 117 | isSetupDone = true 118 | setupProperties() 119 | setupNotifications() 120 | setupNavigationBar() 121 | detectResizeType() 122 | configure() 123 | } 124 | 125 | private func setupProperties() { 126 | // Decreased button touch delay configuration 127 | delaysContentTouches = false 128 | 129 | // Should bounce even if contentSize is not enough 130 | alwaysBounceVertical = true 131 | 132 | delegate = self 133 | 134 | if let fadeViews = fadeViews { 135 | fadeViews.forEach({ _fadeViews.add($0) }) 136 | self.fadeViews = nil 137 | } 138 | 139 | if let stretchedView = stretchedView { 140 | _stretchedView = stretchedView 141 | self.stretchedView = nil 142 | } 143 | } 144 | 145 | private func setupNotifications() { 146 | NotificationCenter.default.addObserver(self, selector: #selector(onWillMoveToParentViewController(_:)), name: .UIViewControllerWillMoveToParentViewController, object: nil) 147 | NotificationCenter.default.addObserver(self, selector: #selector(onViewWillAppear(_:)), name: .UIViewControllerViewWillAppear, object: _viewController) 148 | NotificationCenter.default.addObserver(self, selector: #selector(onViewWillDisappear(_:)), name: .UIViewControllerViewWillDisappear, object: _viewController) 149 | } 150 | 151 | private func setupNavigationBar() { 152 | if manageNavigationBarTransparency { 153 | saveTransparencyState(replace: false) 154 | makeTransparent() 155 | 156 | if #available(iOS 11.0, tvOS 11.0, *) { 157 | contentInsetAdjustmentBehavior = .never 158 | } else { 159 | _viewController?.automaticallyAdjustsScrollViewInsets = false 160 | } 161 | } 162 | 163 | // Stretch scroll view conflicts with navigation bar stretch. Force disable it. 164 | #if os(iOS) 165 | if #available(iOS 11.0, *) { _viewController?.navigationItem.largeTitleDisplayMode = .never } 166 | #endif 167 | 168 | configureNavigationBarBackgroundView() 169 | } 170 | 171 | //----------------------------------------------------------------------------- 172 | // MARK: - Configuration 173 | //----------------------------------------------------------------------------- 174 | 175 | private func configure() { 176 | configureStretchedView() 177 | configureVisibility() 178 | } 179 | 180 | private func configureStretchedView() { 181 | switch resizeType { 182 | case .none: break 183 | 184 | case .topAndHeight(let topConstraint, let heightConstraint, let defaultHeight): 185 | let compensatedContentOffsetY: CGFloat 186 | if #available(iOS 11.0, tvOS 11.0, *) { compensatedContentOffsetY = contentOffset.y + adjustedContentInset.top } 187 | else { compensatedContentOffsetY = contentOffset.y + contentInset.top } 188 | 189 | topConstraint.constant = min(0, compensatedContentOffsetY) 190 | heightConstraint.constant = max(defaultHeight, defaultHeight - compensatedContentOffsetY) 191 | 192 | case .topAndSides(let topConstraint, let leftConstraint, let rightConstraint, let aspectRatio): 193 | let compensatedContentOffsetY: CGFloat 194 | if #available(iOS 11.0, tvOS 11.0, *) { compensatedContentOffsetY = contentOffset.y + adjustedContentInset.top } 195 | else { compensatedContentOffsetY = contentOffset.y + contentInset.top } 196 | 197 | let newTopConstant = min(0, compensatedContentOffsetY) 198 | let newSidesConstant = newTopConstant * aspectRatio / 2 199 | topConstraint.constant = newTopConstant 200 | leftConstraint.constant = newSidesConstant 201 | rightConstraint.constant = newSidesConstant 202 | 203 | if let _stretchedView = _stretchedView { 204 | // Checking if there is nested UIScrollView to just its insets 205 | var viewsToCheck = [_stretchedView] 206 | viewsToCheck.append(contentsOf: _stretchedView._allSubviews) 207 | let scrollViewSubview = viewsToCheck 208 | .compactMap { $0 as? UIScrollView } 209 | .first 210 | 211 | if let scrollViewSubview = scrollViewSubview, scrollViewSubview.contentSize.width > 0 { 212 | // Force stop scrolling so we won't have overlapping animations 213 | scrollViewSubview._forceStopScrolling() 214 | 215 | // Assure we are enlarging content 216 | scrollViewSubview._clampContentOffset() 217 | 218 | // Need to zoom at center. So need to preserve relative center before transform 219 | // and make relative center after transform the same. 220 | // Also assure relative center is clamped so we won't look outside of a content. 221 | let previousBoundsRelativeCenterX = scrollViewSubview._relativeCenter.x 222 | setNeedsLayout() 223 | layoutIfNeeded() 224 | scrollViewSubview._relativeCenter.x = previousBoundsRelativeCenterX 225 | } 226 | } 227 | } 228 | } 229 | 230 | private func configureVisibility() { 231 | configureNavigationBarBackgroundView() 232 | 233 | let compensatedContentOffsetY: CGFloat 234 | if #available(iOS 11.0, tvOS 11.0, *) { compensatedContentOffsetY = contentOffset.y + adjustedContentInset.top } 235 | else { compensatedContentOffsetY = contentOffset.y + contentInset.top } 236 | 237 | // Fade views and navigation bar 238 | var newAlpha = (FadeOutOffset + compensatedContentOffsetY) / FadeOutOffset 239 | newAlpha = max(0, newAlpha) 240 | newAlpha = min(1, newAlpha) 241 | _fadeViews.allObjects.forEach { $0.alpha = newAlpha } 242 | 243 | // Navigation bar alpha won't be changed if content inset top is not zero or navigation bar is not translucent. 244 | let shouldChangeNavigationBarAlpha: Bool 245 | if #available(iOS 11.0, tvOS 11.0, *) { shouldChangeNavigationBarAlpha = adjustedContentInset.top == 0 && navigationBar?.isTranslucent == true } 246 | else { shouldChangeNavigationBarAlpha = contentInset.top == 0 && navigationBar?.isTranslucent == true } 247 | 248 | if shouldChangeNavigationBarAlpha { 249 | navigationBar?.subviews.forEach({ $0.alpha = newAlpha }) 250 | } 251 | 252 | // Navigation bar background alpha 253 | let fadeInFinishDistance = NavigationFadeInFinishOffset 254 | let startFadeInDistance = min(fadeInFinishDistance, 0) 255 | let distance = fadeInFinishDistance - startFadeInDistance 256 | var backgroundNewAlpha = (startFadeInDistance + compensatedContentOffsetY) / distance 257 | backgroundNewAlpha = max(0, backgroundNewAlpha) 258 | backgroundNewAlpha = min(1, backgroundNewAlpha) 259 | navigationBarBackgroundView.alpha = backgroundNewAlpha * newAlpha 260 | } 261 | 262 | private func configureNavigationBarBackgroundView() { 263 | // Assure `navigationBarBackgroundView` below navigation bar 264 | if let navigationBar = navigationBar { 265 | navigationControllerView?.insertSubview(navigationBarBackgroundView, belowSubview: navigationBar) 266 | } 267 | } 268 | 269 | //----------------------------------------------------------------------------- 270 | // MARK: - UIView Methods 271 | //----------------------------------------------------------------------------- 272 | 273 | public override func layoutSubviews() { 274 | super.layoutSubviews() 275 | 276 | if let navigationBar = navigationBar { 277 | navigationBarBackgroundView.frame = CGRect(x: 0, y: 0, width: navigationBar.bounds.width, height: navigationBar.frame.maxY) 278 | } 279 | } 280 | 281 | //----------------------------------------------------------------------------- 282 | // MARK: - UIScrollView Methods 283 | //----------------------------------------------------------------------------- 284 | 285 | // Decreased button touch delay configuration 286 | override open func touchesShouldCancel(in view: UIView) -> Bool { 287 | if view is UIButton { 288 | return true 289 | } 290 | 291 | return super.touchesShouldCancel(in: view) 292 | } 293 | 294 | //----------------------------------------------------------------------------- 295 | // MARK: - Public Methods 296 | //----------------------------------------------------------------------------- 297 | 298 | /// Sets stretched view. Also performs all needed setup. 299 | /// Be sure to call this one only if you have to setup stretched view from code. 300 | /// Should be called only once and only after all setup for view hierarchy, constraints and VCs composition is done. 301 | public func setStretchedView(_ view: UIView) { 302 | guard _stretchedView == nil && stretchedView == nil else { 303 | print("Stretched view can't be exchanged when it previously was set") 304 | return 305 | } 306 | 307 | // Setup from code flow 308 | _stretchedView = view 309 | setup() 310 | } 311 | 312 | /// Adds views to fade when scrolling to bottom. Safe to call at any time. 313 | public func addFadeViews(_ views: [UIView]) { 314 | views.forEach { _fadeViews.add($0) } 315 | configure() 316 | } 317 | 318 | //----------------------------------------------------------------------------- 319 | // MARK: - Private methods - Notifications 320 | //----------------------------------------------------------------------------- 321 | 322 | @objc private func onWillMoveToParentViewController(_ notification: Notification) { 323 | // iOS bug, must configure navigation bar future state in willMove(toParentViewController:) method of popping view controller 324 | guard let viewController = notification.object as? UIViewController else { return } 325 | 326 | // Moving from parent 327 | guard notification.userInfo?["parent"] == nil else { return } 328 | 329 | if viewController._previousViewController == self._viewController { 330 | // Popping to our controller 331 | if manageNavigationBarTransparency { 332 | makeTransparent() 333 | } 334 | } else if viewController == self._viewController { 335 | // Popping our controller 336 | navigationBarBackgroundView.alpha = 0 337 | 338 | if manageNavigationBarTransparency { 339 | restoreTransparencyState() 340 | } 341 | } 342 | } 343 | 344 | @objc private func onViewWillAppear(_ notification: Notification) { 345 | if manageNavigationBarTransparency { 346 | saveTransparencyState(replace: false) 347 | makeTransparent() 348 | } 349 | 350 | configureVisibility() 351 | } 352 | 353 | @objc private func onViewWillDisappear(_ notification: Notification) { 354 | navigationBarBackgroundView.alpha = 0 355 | 356 | if manageNavigationBarTransparency { 357 | restoreTransparencyState() 358 | } 359 | } 360 | 361 | //----------------------------------------------------------------------------- 362 | // MARK: - Transparency State 363 | //----------------------------------------------------------------------------- 364 | 365 | private struct TransparencyState { 366 | let isTranslucent: Bool 367 | let backgroundImage: UIImage? 368 | let shadowImage: UIImage? 369 | } 370 | 371 | private var transparencyState: TransparencyState? 372 | 373 | private func saveTransparencyState(replace: Bool) { 374 | guard replace || transparencyState == nil, let navigationBar = navigationBar else { return } 375 | 376 | transparencyState = TransparencyState(isTranslucent: navigationBar.isTranslucent, backgroundImage: navigationBar.backgroundImage(for: .default), shadowImage: navigationBar.shadowImage) 377 | } 378 | 379 | private func restoreTransparencyState() { 380 | guard let transparencyState = transparencyState else { return } 381 | 382 | navigationBar?.isTranslucent = transparencyState.isTranslucent 383 | navigationBar?.setBackgroundImage(transparencyState.backgroundImage, for: .default) 384 | navigationBar?.shadowImage = transparencyState.shadowImage 385 | } 386 | 387 | private func makeTransparent() { 388 | navigationBar?.isTranslucent = true 389 | navigationBar?.setBackgroundImage(UIImage(), for: .default) 390 | navigationBar?.shadowImage = UIImage() 391 | } 392 | 393 | // ******************************* MARK: - Private Methods 394 | 395 | private func detectResizeType() { 396 | guard resizeType.isNone else { return } 397 | guard let stretchedView = _stretchedView else { return } 398 | var childView = stretchedView 399 | guard var superview = childView.superview else { return } 400 | 401 | // Check if stretched view inside UIStackView and use it's constraints instead. 402 | if #available(iOS 9.0, *) { 403 | if let stackView = superview as? UIStackView, let stackViewSuperview = stackView.superview { 404 | childView = stackView 405 | superview = stackViewSuperview 406 | } 407 | } 408 | 409 | var topConstraint: NSLayoutConstraint? 410 | var leadingConstraint: NSLayoutConstraint? 411 | var trailingConstraint: NSLayoutConstraint? 412 | var heightConstraint: NSLayoutConstraint? 413 | var defaultHeight: CGFloat? 414 | 415 | for constraint in stretchedView.constraints { 416 | if (constraint.firstItem === stretchedView && constraint.firstAttribute == .height) { 417 | heightConstraint = constraint 418 | defaultHeight = constraint.constant 419 | break 420 | } 421 | } 422 | 423 | // TODO: If view is inside UIStackView - just use it and go next 424 | // TODO: Get top constraint and goto view that uses it 425 | // TODO: If view is StretchScrollView - use that top constraint 426 | 427 | for constraint in superview.constraints { 428 | if (constraint.firstItem === childView && constraint.secondItem === superview && constraint.firstAttribute == .top) || 429 | (constraint.secondItem === childView && constraint.firstItem === superview && constraint.secondAttribute == .top) { 430 | 431 | topConstraint = constraint 432 | } 433 | 434 | if (constraint.firstItem === childView && constraint.secondItem === superview && constraint.firstAttribute == .leading) || 435 | (constraint.secondItem === childView && constraint.firstItem === superview && constraint.secondAttribute == .leading) { 436 | 437 | leadingConstraint = constraint 438 | } 439 | 440 | if (constraint.firstItem === childView && constraint.secondItem === superview && constraint.firstAttribute == .trailing) || 441 | (constraint.secondItem === childView && constraint.firstItem === superview && constraint.secondAttribute == .trailing) { 442 | 443 | trailingConstraint = constraint 444 | } 445 | } 446 | 447 | if let topConstraint = topConstraint, let heightConstraint = heightConstraint, let defaultHeight = defaultHeight { 448 | resizeType = .topAndHeight(topConstraint: topConstraint, heightConstraint: heightConstraint, defaultHeight: defaultHeight) 449 | } else if let topConstraint = topConstraint, let leadingConstraint = leadingConstraint, let trailingConstraint = trailingConstraint { 450 | let aspectRatio: CGFloat = childView.bounds.width / childView.bounds.height 451 | resizeType = .topAndSides(topConstraint: topConstraint, leftConstraint: leadingConstraint, rightConstraint: trailingConstraint, aspectRatio: aspectRatio) 452 | } else { 453 | print("StretchScrollView: Unable to detect resize type") 454 | } 455 | } 456 | } 457 | 458 | //----------------------------------------------------------------------------- 459 | // MARK: - UIScrollViewDelegate 460 | //----------------------------------------------------------------------------- 461 | 462 | extension StretchScrollView: UIScrollViewDelegate { 463 | public func scrollViewDidScroll(_ scrollView: UIScrollView) { 464 | configure() 465 | } 466 | } 467 | -------------------------------------------------------------------------------- /StretchScrollView/Classes/UIScrollView+Utils.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIScrollView+Utils.swift 3 | // StretchScrollView 4 | // 5 | // Created by Anton Plebanovich on 1/14/19. 6 | // Copyright © 2019 Anton Plebanovich. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | 12 | extension UIScrollView { 13 | /// Bounds center relative to content size 14 | var _relativeCenter: CGPoint { 15 | get { 16 | let relativeCenterX: CGFloat 17 | if contentSize.width == 0 { 18 | relativeCenterX = 0 19 | } else { 20 | relativeCenterX = bounds._center.x / contentSize.width 21 | } 22 | 23 | let relativeCenterY: CGFloat 24 | if contentSize.height == 0 { 25 | relativeCenterY = 0 26 | } else { 27 | relativeCenterY = bounds._center.y / contentSize.height 28 | } 29 | 30 | return CGPoint(x: relativeCenterX, y: relativeCenterY) 31 | } 32 | 33 | set { 34 | let newCenter = CGPoint(x: newValue.x * contentSize.width, y: newValue.y * contentSize.height) 35 | bounds._center = newCenter 36 | } 37 | } 38 | 39 | /// Assures that contentOffset value is correct. 40 | func _clampContentOffset() { 41 | let minOffsetY = -contentInset.top 42 | let maxOffsetY = max(contentSize.height - bounds.size.height + contentInset.bottom, 0) 43 | let minOffsetX = -contentInset.left 44 | let maxOffsetX = max(contentSize.width - bounds.size.width + contentInset.right, 0) 45 | 46 | var newContentOffset = contentOffset 47 | newContentOffset.y = min(newContentOffset.y, maxOffsetY) 48 | newContentOffset.y = max(newContentOffset.y, minOffsetY) 49 | newContentOffset.x = min(newContentOffset.x, maxOffsetX) 50 | newContentOffset.x = max(newContentOffset.x, minOffsetX) 51 | 52 | contentOffset = newContentOffset 53 | } 54 | 55 | func _forceStopScrolling() { 56 | setContentOffset(contentOffset, animated: false) 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /StretchScrollView/Classes/UIView+Utils.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+Utils.swift 3 | // StretchScrollView 4 | // 5 | // Created by Anton Plebanovich on 8/8/17. 6 | // Copyright © 2017 Anton Plebanovich. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | 12 | extension UIView { 13 | /// Returns closest UIViewController from responders chain. 14 | var _viewController: UIViewController? { 15 | var nextResponder: UIResponder? = self 16 | while nextResponder != nil { 17 | nextResponder = nextResponder?.next 18 | 19 | if let viewController = nextResponder as? UIViewController { 20 | return viewController 21 | } 22 | } 23 | 24 | return nil 25 | } 26 | 27 | /// Returns all view's subviews 28 | var _allSubviews: [UIView] { 29 | var allSubviews = self.subviews 30 | 31 | allSubviews.forEach { allSubviews.append(contentsOf: $0._allSubviews) } 32 | 33 | return allSubviews 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /StretchScrollView/Classes/UIViewController+Utils.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewController+Utils.swift 3 | // StretchScrollView 4 | // 5 | // Created by Anton Plebanovich on 8/14/17. 6 | // Copyright © 2017 Anton Plebanovich. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | 12 | extension UIViewController { 13 | /// Previous view controller in navigation stack 14 | var _previousViewController: UIViewController? { 15 | guard let navigationViewControllers = navigationController?.viewControllers, let currentVcIndex = navigationViewControllers.firstIndex(of: self) else { return nil } 16 | 17 | let previousViewControllerIndex = currentVcIndex - 1 18 | if previousViewControllerIndex >= 0 { 19 | return navigationViewControllers[previousViewControllerIndex] 20 | } else { 21 | return nil 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /StretchScrollView/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | 22 | 23 | -------------------------------------------------------------------------------- /StretchScrollView/StretchScrollView.h: -------------------------------------------------------------------------------- 1 | // 2 | // StretchScrollView.h 3 | // StretchScrollView 4 | // 5 | // Created by mac-246 on 1/11/19. 6 | // Copyright © 2019 Anton Plebanovich. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for StretchScrollView. 12 | FOUNDATION_EXPORT double StretchScrollViewVersionNumber; 13 | 14 | //! Project version string for StretchScrollView. 15 | FOUNDATION_EXPORT const unsigned char StretchScrollViewVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /checkBuild.command: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | base_dir=$(dirname "$0") 6 | cd "$base_dir" 7 | 8 | echo "" 9 | echo "" 10 | 11 | echo -e "Checking Carthage integrity..." 12 | carthage_xcodeproj_path="StretchScrollView.xcodeproj" 13 | carthage_pbxproj_path="${carthage_xcodeproj_path}/project.pbxproj" 14 | swift_files=$(find 'StretchScrollView/Classes' -type f -name "*.swift" | grep -o "[0-9a-zA-Z+ ]*.swift" | sort -fu) 15 | swift_files_count=$(echo "${swift_files}" | wc -l | tr -d ' ') 16 | 17 | build_section_id=$(sed -n -e '/\/\* StretchScrollView \*\/ = {/,/};/p' "${carthage_pbxproj_path}" | sed -n '/PBXNativeTarget/,/Sources/p' | tail -1 | tr -d "\t" | cut -d ' ' -f 1) 18 | swift_files_in_project=$(sed -n "/${build_section_id}.* = {/,/};/p" "${carthage_pbxproj_path}" | grep -o "[A-Z].[0-9a-zA-Z+ ]*\.swift" | sort -fu) 19 | swift_files_in_project_count=$(echo "${swift_files_in_project}" | wc -l | tr -d ' ') 20 | if [ "${swift_files_count}" -ne "${swift_files_in_project_count}" ]; then 21 | echo >&2 "error: Carthage project missing dependencies." 22 | echo -e "\nFinder files:\n${swift_files}" 23 | echo -e "\nProject files:\n${swift_files_in_project}" 24 | echo -e "\nMissing dependencies:" 25 | comm -23 <(echo "${swift_files}") <(echo "${swift_files_in_project}") 26 | echo " " 27 | exit 1 28 | fi 29 | echo "" 30 | 31 | echo -e "Building Swift Package..." 32 | swift build -Xswiftc "-sdk" -Xswiftc "`xcrun --sdk iphonesimulator --show-sdk-path`" -Xswiftc "-target" -Xswiftc "x86_64-apple-ios14.4-simulator" 33 | swift build -Xswiftc "-sdk" -Xswiftc "`xcrun --sdk appletvsimulator --show-sdk-path`" -Xswiftc "-target" -Xswiftc "x86_64-apple-tvos14.3-simulator" 34 | echo "" 35 | 36 | echo "Building Pods project..." 37 | set -o pipefail && xcodebuild -workspace "Example/StretchScrollView.xcworkspace" -scheme "StretchScrollView-Example" -configuration "Release" -sdk iphonesimulator | xcpretty 38 | echo "" 39 | 40 | echo -e "Building Carthage projects..." 41 | . "./Scripts/Carthage/utils.sh" 42 | applyXcode12Workaround 43 | set -o pipefail && xcodebuild -project "StretchScrollView.xcodeproj" -sdk iphonesimulator -target "StretchScrollView" | xcpretty 44 | echo "" 45 | 46 | echo -e "Building with Carthage..." 47 | carthage build --use-xcframeworks --no-skip-current --platform iOS,tvOS --cache-builds 48 | echo "" 49 | 50 | echo -e "Performing tests..." 51 | simulator_id="$(xcrun simctl list devices available iPhone | grep " SE " | tail -1 | sed -e "s/.*(\([0-9A-Z-]*\)).*/\1/")" 52 | if [ -n "${simulator_id}" ]; then 53 | echo "Using iPhone SE simulator with ID: '${simulator_id}'" 54 | 55 | else 56 | simulator_id="$(xcrun simctl list devices available iPhone | grep "^ " | tail -1 | sed -e "s/.*(\([0-9A-Z-]*\)).*/\1/")" 57 | if [ -n "${simulator_id}" ]; then 58 | echo "Using iPhone simulator with ID: '${simulator_id}'" 59 | 60 | else 61 | echo >&2 "error: Please install iPhone simulator." 62 | echo " " 63 | exit 1 64 | fi 65 | fi 66 | 67 | set -o pipefail && xcodebuild -workspace "Example/StretchScrollView.xcworkspace" -sdk iphonesimulator -scheme "StretchScrollView-Example" -destination "platform=iOS Simulator,id=${simulator_id}" test | xcpretty 68 | 69 | echo "" 70 | echo "SUCCESS!" 71 | echo "" 72 | echo "" 73 | -------------------------------------------------------------------------------- /podCheck.command: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | base_dir=$(dirname "$0") 4 | cd "$base_dir" 5 | 6 | # Checking lib lint 7 | pod lib lint 8 | 9 | # Checking spec lint 10 | pod spec lint 11 | -------------------------------------------------------------------------------- /podPush.command: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | base_dir=$(dirname "$0") 4 | cd "$base_dir" 5 | 6 | # Pushing latest version to cocoapods 7 | pod trunk push 8 | --------------------------------------------------------------------------------