├── .gitignore ├── .travis.yml ├── CropPickerController.podspec ├── CropPickerController ├── Assets │ └── .gitkeep └── Classes │ ├── .gitkeep │ ├── ArrowView.swift │ ├── BezierPath+.swift │ ├── CameraView.swift │ ├── CheckBoxView.swift │ ├── CheckView.swift │ ├── CropPickerController.swift │ ├── Double+.swift │ ├── ImageAsset.swift │ ├── PermissionHelper.swift │ ├── PictureCell.swift │ ├── ProgressView.swift │ ├── TitleButton.swift │ ├── UIImage+.swift │ └── UIView+.swift ├── Example ├── CropPickerController.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── xcshareddata │ │ └── xcschemes │ │ └── CropPickerController-Example.xcscheme ├── CropPickerController.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── CropPickerController │ ├── AppDelegate.swift │ ├── Base.lproj │ │ ├── LaunchScreen.xib │ │ └── Main.storyboard │ ├── Images.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Info.plist │ └── ViewController.swift ├── Podfile ├── Podfile.lock ├── Pods │ ├── CropPickerView │ │ ├── CropPickerView │ │ │ └── Classes │ │ │ │ ├── BezierPath+.swift │ │ │ │ ├── CropDimView.swift │ │ │ │ ├── CropPickerView.swift │ │ │ │ ├── CropResult.swift │ │ │ │ ├── CropView.swift │ │ │ │ ├── LineButton.swift │ │ │ │ ├── NSLayoutConstraint+.swift │ │ │ │ ├── UIImage+.swift │ │ │ │ ├── UIImageView+.swift │ │ │ │ └── UIView+.swift │ │ ├── LICENSE │ │ └── README.md │ ├── Local Podspecs │ │ └── CropPickerController.podspec.json │ ├── Manifest.lock │ ├── Pods.xcodeproj │ │ └── project.pbxproj │ └── Target Support Files │ │ ├── CropPickerController │ │ ├── CropPickerController-Info.plist │ │ ├── CropPickerController-dummy.m │ │ ├── CropPickerController-prefix.pch │ │ ├── CropPickerController-umbrella.h │ │ ├── CropPickerController.debug.xcconfig │ │ ├── CropPickerController.modulemap │ │ ├── CropPickerController.release.xcconfig │ │ ├── CropPickerController.xcconfig │ │ └── Info.plist │ │ ├── CropPickerView │ │ ├── CropPickerView-Info.plist │ │ ├── CropPickerView-dummy.m │ │ ├── CropPickerView-prefix.pch │ │ ├── CropPickerView-umbrella.h │ │ ├── CropPickerView.debug.xcconfig │ │ ├── CropPickerView.modulemap │ │ ├── CropPickerView.release.xcconfig │ │ ├── CropPickerView.xcconfig │ │ └── Info.plist │ │ ├── Pods-CropPickerController_Example │ │ ├── Info.plist │ │ ├── Pods-CropPickerController_Example-Info.plist │ │ ├── Pods-CropPickerController_Example-acknowledgements.markdown │ │ ├── Pods-CropPickerController_Example-acknowledgements.plist │ │ ├── Pods-CropPickerController_Example-dummy.m │ │ ├── Pods-CropPickerController_Example-frameworks.sh │ │ ├── Pods-CropPickerController_Example-resources.sh │ │ ├── Pods-CropPickerController_Example-umbrella.h │ │ ├── Pods-CropPickerController_Example.debug.xcconfig │ │ ├── Pods-CropPickerController_Example.modulemap │ │ └── Pods-CropPickerController_Example.release.xcconfig │ │ └── Pods-CropPickerController_Tests │ │ ├── Info.plist │ │ ├── Pods-CropPickerController_Tests-Info.plist │ │ ├── Pods-CropPickerController_Tests-acknowledgements.markdown │ │ ├── Pods-CropPickerController_Tests-acknowledgements.plist │ │ ├── Pods-CropPickerController_Tests-dummy.m │ │ ├── Pods-CropPickerController_Tests-frameworks.sh │ │ ├── Pods-CropPickerController_Tests-resources.sh │ │ ├── Pods-CropPickerController_Tests-umbrella.h │ │ ├── Pods-CropPickerController_Tests.debug.xcconfig │ │ ├── Pods-CropPickerController_Tests.modulemap │ │ └── Pods-CropPickerController_Tests.release.xcconfig └── Tests │ ├── Info.plist │ └── Tests.swift ├── LICENSE ├── README.md ├── _Pods.xcodeproj └── img ├── 1.gif ├── 2.gif ├── 3.gif ├── 4.gif └── info.png /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xccheckout 23 | *.xcscmblueprint 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | *.ipa 28 | *.dSYM.zip 29 | *.dSYM 30 | 31 | ## Playgrounds 32 | timeline.xctimeline 33 | playground.xcworkspace 34 | 35 | # Swift Package Manager 36 | # 37 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 38 | # Packages/ 39 | # Package.pins 40 | # Package.resolved 41 | .build/ 42 | 43 | # CocoaPods 44 | # 45 | # We recommend against adding the Pods directory to your .gitignore. However 46 | # you should judge for yourself, the pros and cons are mentioned at: 47 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 48 | # 49 | # Pods/ 50 | 51 | # Carthage 52 | # 53 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 54 | # Carthage/Checkouts 55 | 56 | Carthage/Build 57 | 58 | # fastlane 59 | # 60 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 61 | # screenshots whenever they are needed. 62 | # For more information about the recommended setup visit: 63 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 64 | 65 | fastlane/report.xml 66 | fastlane/Preview.html 67 | fastlane/screenshots/**/*.png 68 | fastlane/test_output 69 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # references: 2 | # * https://www.objc.io/issues/6-build-tools/travis-ci/ 3 | # * https://github.com/supermarin/xcpretty#usage 4 | 5 | osx_image: xcode12.2 6 | language: swift 7 | # cache: cocoapods 8 | podfile: Example/Podfile 9 | before_install: 10 | - gem install cocoapods # Since Travis is not always on latest version 11 | - pod install --project-directory=Example 12 | script: 13 | - xcodebuild -version 14 | - xcodebuild -showsdks 15 | - xcodebuild -list 16 | - set -o pipefail && xcodebuild test -workspace Example/CropPickerController.xcworkspace -scheme CropPickerController-Example -destination 'platform=iOS Simulator,name=iPhone 12,OS=14.2' | xcpretty 17 | - pod lib lint 18 | -------------------------------------------------------------------------------- /CropPickerController.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod lib lint CropPickerController.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 https://guides.cocoapods.org/syntax/podspec.html 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | s.name = 'CropPickerController' 11 | s.version = '0.2.0' 12 | s.summary = 'There is a single image picker controller for cropping and a multi image picker controller for selecting various images.' 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 | There is a single image picker controller for cropping and a multi image picker controller for selecting various images. You can select an album and it will be updated automatically when you edit the album. 22 | DESC 23 | 24 | s.homepage = 'https://github.com/pikachu987/CropPickerController' 25 | # s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2' 26 | s.license = { :type => 'MIT', :file => 'LICENSE' } 27 | s.author = { 'pikachu987' => 'pikachu77769@gmail.com' } 28 | s.source = { :git => 'https://github.com/pikachu987/CropPickerController.git', :tag => s.version.to_s } 29 | # s.social_media_url = 'https://twitter.com/' 30 | 31 | s.ios.deployment_target = '9.0' 32 | 33 | s.swift_version = '5.0' 34 | 35 | s.source_files = 'CropPickerController/Classes/**/*' 36 | 37 | # s.resource_bundles = { 38 | # 'CropPickerController' => ['CropPickerController/Assets/*.png'] 39 | # } 40 | 41 | # s.public_header_files = 'Pod/Classes/**/*.h' 42 | # s.frameworks = 'UIKit', 'MapKit' 43 | s.dependency 'CropPickerView', '0.2.7' 44 | end 45 | -------------------------------------------------------------------------------- /CropPickerController/Assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pikachu987/CropPickerController/865f98729c15c8ca2d53acfe1b0ba96160b285c6/CropPickerController/Assets/.gitkeep -------------------------------------------------------------------------------- /CropPickerController/Classes/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pikachu987/CropPickerController/865f98729c15c8ca2d53acfe1b0ba96160b285c6/CropPickerController/Classes/.gitkeep -------------------------------------------------------------------------------- /CropPickerController/Classes/ArrowView.swift: -------------------------------------------------------------------------------- 1 | //Copyright (c) 2018 pikachu987 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 | 21 | import UIKit 22 | 23 | // Make Arrow Bottom Image 24 | class ArrowBottomView: UIView { 25 | static func imageView(_ color: UIColor) -> UIImage? { 26 | let view = ArrowBottomView(color) 27 | view.setNeedsDisplay() 28 | view.isOpaque = false 29 | view.tintColor = color 30 | return view.imageWithView?.withRenderingMode(.alwaysOriginal) 31 | } 32 | 33 | private var color: UIColor 34 | 35 | init(_ color: UIColor) { 36 | self.color = color 37 | super.init(frame: CGRect(x: 0, y: 0, width: 24, height: 24)) 38 | } 39 | 40 | required init?(coder aDecoder: NSCoder) { 41 | self.color = .black 42 | super.init(coder: aDecoder) 43 | } 44 | 45 | override func draw(_ rect: CGRect) { 46 | self.backgroundColor = .clear 47 | let path = UIBezierPath() 48 | .move(6, 9) 49 | .line(12, 16) 50 | .line(18, 9) 51 | .line(12, 16) 52 | .line(6, 9) 53 | path.closed() 54 | .strokeFill(self.color) 55 | } 56 | } 57 | 58 | // Make Scroll To Bottom Image 59 | class ArrowScrollBottomView: UIView { 60 | static func imageView(_ color: UIColor) -> UIImage? { 61 | let view = ArrowScrollBottomView(color) 62 | view.setNeedsDisplay() 63 | view.isOpaque = false 64 | view.tintColor = color 65 | return view.imageWithView?.withRenderingMode(.alwaysOriginal) 66 | } 67 | 68 | private var color: UIColor 69 | 70 | init(_ color: UIColor) { 71 | self.color = color 72 | super.init(frame: CGRect(x: 0, y: 0, width: 48, height: 48)) 73 | } 74 | 75 | required init?(coder aDecoder: NSCoder) { 76 | self.color = .black 77 | super.init(coder: aDecoder) 78 | } 79 | 80 | override func draw(_ rect: CGRect) { 81 | self.backgroundColor = .clear 82 | let path = UIBezierPath() 83 | .move(16, 23) 84 | .line(24, 32) 85 | .line(32, 23) 86 | .line(24, 32) 87 | .line(16, 23) 88 | .move(24, 32) 89 | .line(24, 16) 90 | .line(24, 32) 91 | path.closed() 92 | .strokeFill(self.color, lineWidth: 2) 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /CropPickerController/Classes/BezierPath+.swift: -------------------------------------------------------------------------------- 1 | //Copyright (c) 2018 pikachu987 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 | 21 | import UIKit 22 | 23 | extension UIBezierPath { 24 | @discardableResult 25 | func move(_ x: CGFloat, _ y: CGFloat) -> UIBezierPath{ 26 | self.move(to: CGPoint(x: x, y: y)) 27 | return self 28 | } 29 | 30 | @discardableResult 31 | func line(_ x: CGFloat, _ y: CGFloat) -> UIBezierPath { 32 | self.addLine(to: CGPoint(x: x, y: y)) 33 | return self 34 | } 35 | 36 | @discardableResult 37 | func closed() -> UIBezierPath { 38 | self.close() 39 | return self 40 | } 41 | 42 | @discardableResult 43 | func strokeFill(_ color: UIColor, lineWidth: CGFloat = 1) -> UIBezierPath { 44 | color.set() 45 | self.lineWidth = lineWidth 46 | self.stroke() 47 | self.fill() 48 | return self 49 | } 50 | 51 | @discardableResult 52 | func stroke(_ color: UIColor, lineWidth: CGFloat = 1) -> UIBezierPath { 53 | color.set() 54 | self.lineWidth = lineWidth 55 | self.stroke() 56 | return self 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /CropPickerController/Classes/CameraView.swift: -------------------------------------------------------------------------------- 1 | //Copyright (c) 2018 pikachu987 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 | 21 | import UIKit 22 | 23 | // Make Camera Image 24 | class CameraView: UIView { 25 | 26 | private var color: UIColor 27 | 28 | init(_ color: UIColor) { 29 | self.color = color 30 | super.init(frame: CGRect(x: 0, y: 0, width: 40, height: 40)) 31 | self.setNeedsDisplay() 32 | } 33 | 34 | required init?(coder aDecoder: NSCoder) { 35 | self.color = .black 36 | super.init(coder: aDecoder) 37 | self.setNeedsDisplay() 38 | } 39 | 40 | override func draw(_ rect: CGRect) { 41 | self.backgroundColor = .clear 42 | let path = UIBezierPath() 43 | .move(1, 7) 44 | .line(13, 7) 45 | .line(15, 4) 46 | .line(25, 4) 47 | .line(27, 7) 48 | .line(39, 7) 49 | .line(39, 35) 50 | .line(1, 35) 51 | .line(1, 7) 52 | path.closed() 53 | .stroke(self.color) 54 | 55 | let smallCirclePath = UIBezierPath() 56 | smallCirclePath.addArc(withCenter: CGPoint(x: 8, y: 13), radius: 2, startAngle: 0, endAngle: CGFloat.pi*2, clockwise: true) 57 | smallCirclePath.closed() 58 | .stroke(self.color) 59 | 60 | let centerCirclePath = UIBezierPath() 61 | centerCirclePath.addArc(withCenter: CGPoint(x: rect.width/2, y: rect.height/2 + 2), radius: 8, startAngle: 0, endAngle: CGFloat.pi*2, clockwise: true) 62 | centerCirclePath.closed() 63 | .stroke(self.color) 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /CropPickerController/Classes/CheckBoxView.swift: -------------------------------------------------------------------------------- 1 | //Copyright (c) 2018 pikachu987 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 | 21 | import UIKit 22 | 23 | // Check Box Or Check Number View 24 | class CheckBoxView: UIView { 25 | static var selectBackgroundColor = UIColor(red: 53/255, green: 150/255, blue: 240/255, alpha: 1) 26 | static var layerColor = UIColor.white 27 | static var selectTintColor = UIColor.white 28 | 29 | private lazy var numberLabel: UILabel = { 30 | let label = UILabel() 31 | self.addSubview(label) 32 | label.translatesAutoresizingMaskIntoConstraints = false 33 | self.leadingConstraint(subView: label, constant: -3) 34 | self.trailingConstraint(subView: label, constant: 3) 35 | self.centerYConstraint(subView: label) 36 | return label 37 | }() 38 | 39 | private lazy var imageView: UIImageView = { 40 | let imageView = UIImageView() 41 | self.addSubview(imageView) 42 | imageView.translatesAutoresizingMaskIntoConstraints = false 43 | self.leadingConstraint(subView: imageView, constant: -3) 44 | self.trailingConstraint(subView: imageView, constant: 3) 45 | self.topConstraint(subView: imageView, constant: 3) 46 | self.bottomConstraint(subView: imageView, constant: 3) 47 | return imageView 48 | }() 49 | 50 | override init(frame: CGRect) { 51 | super.init(frame: frame) 52 | 53 | self.backgroundColor = .clear 54 | self.clipsToBounds = true 55 | self.layer.borderWidth = 1 56 | self.layer.borderColor = CheckBoxView.layerColor.cgColor 57 | self.layer.cornerRadius = 12 58 | self.numberLabel.textColor = CheckBoxView.selectTintColor 59 | self.numberLabel.font = UIFont.systemFont(ofSize: 13) 60 | self.numberLabel.textAlignment = .center 61 | self.numberLabel.adjustsFontSizeToFitWidth = true 62 | self.numberLabel.minimumScaleFactor = 0.3 63 | } 64 | 65 | required init?(coder aDecoder: NSCoder) { 66 | super.init(coder: aDecoder) 67 | } 68 | 69 | func setEntity(_ number: Int = 0) { 70 | self.imageView.isHidden = true 71 | if number == 0 { 72 | self.backgroundColor = .clear 73 | self.numberLabel.isHidden = true 74 | } else { 75 | self.backgroundColor = CheckBoxView.selectBackgroundColor 76 | self.numberLabel.isHidden = false 77 | self.numberLabel.text = "\(number)" 78 | } 79 | } 80 | 81 | func setEntity(_ isSelected: Bool) { 82 | self.backgroundColor = isSelected ? CheckBoxView.selectBackgroundColor : .clear 83 | self.numberLabel.isHidden = true 84 | self.imageView.isHidden = false 85 | self.imageView.image = isSelected ? CheckView.image(CheckBoxView.selectTintColor) : nil 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /CropPickerController/Classes/CheckView.swift: -------------------------------------------------------------------------------- 1 | //Copyright (c) 2018 pikachu987 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 | 21 | import UIKit 22 | 23 | // Make Check Image 24 | class CheckView: UIView { 25 | private static var staticImage: UIImage? 26 | 27 | static func image(_ color: UIColor) -> UIImage? { 28 | if CheckView.staticImage == nil { 29 | let image = CheckView.imageView(color) 30 | CheckView.staticImage = image 31 | return image 32 | } else { 33 | return CheckView.staticImage 34 | } 35 | } 36 | 37 | static func imageView(_ color: UIColor) -> UIImage? { 38 | let view = CheckView(color) 39 | view.setNeedsDisplay() 40 | view.isOpaque = false 41 | view.tintColor = color 42 | return view.imageWithView?.withRenderingMode(.alwaysOriginal) 43 | } 44 | 45 | private var color: UIColor 46 | 47 | init(_ color: UIColor) { 48 | self.color = color 49 | super.init(frame: CGRect(x: 0, y: 0, width: 24, height: 24)) 50 | } 51 | 52 | required init?(coder aDecoder: NSCoder) { 53 | self.color = .black 54 | super.init(coder: aDecoder) 55 | } 56 | 57 | override func draw(_ rect: CGRect) { 58 | self.backgroundColor = .clear 59 | let path = UIBezierPath() 60 | .move(6, 15) 61 | .line(12, 19) 62 | .line(20, 11) 63 | .line(12, 18) 64 | .line(6, 15) 65 | path.closed() 66 | .strokeFill(self.color, lineWidth: 1.5) 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /CropPickerController/Classes/Double+.swift: -------------------------------------------------------------------------------- 1 | //Copyright (c) 2018 pikachu987 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 | 21 | import UIKit 22 | 23 | extension Double { 24 | public var degreesToRadians: Double { 25 | return self * Double.pi / 180 26 | } 27 | public var radiansToDegrees: Double { 28 | return self * 180 / Double.pi 29 | } 30 | } 31 | 32 | extension CGFloat { 33 | public var degreesToRadians: CGFloat { 34 | return self * CGFloat.pi / 180 35 | } 36 | public var radiansToDegrees: CGFloat { 37 | return self * 180 / CGFloat.pi 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /CropPickerController/Classes/ImageAsset.swift: -------------------------------------------------------------------------------- 1 | //Copyright (c) 2018 pikachu987 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 | 21 | import Foundation 22 | import Photos 23 | 24 | // Image Asset 25 | struct ImageAsset { 26 | // Camera Type, Image Type, Camera Image Type 27 | enum ImageAssetType { 28 | case camera, image, cameraImage 29 | } 30 | 31 | var type = ImageAssetType.image 32 | var asset: PHAsset? 33 | var image: UIImage? 34 | var isCheck = false 35 | var number = 0 36 | 37 | init() { 38 | self.type = .camera 39 | } 40 | 41 | init(_ image: UIImage) { 42 | self.type = .cameraImage 43 | self.image = image 44 | } 45 | 46 | init(_ asset: PHAsset) { 47 | self.asset = asset 48 | self.type = .image 49 | } 50 | 51 | mutating func checkCancel() { 52 | self.isCheck = false 53 | self.number = 0 54 | } 55 | 56 | static func ==(lhs: ImageAsset, rhs: ImageAsset) -> Bool { 57 | if lhs.type == rhs.type { 58 | if lhs.type == .image { 59 | return lhs.asset == rhs.asset 60 | } else if lhs.type == .cameraImage { 61 | return lhs.image == rhs.image 62 | } else { return true } 63 | } else { return false } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /CropPickerController/Classes/PermissionHelper.swift: -------------------------------------------------------------------------------- 1 | //Copyright (c) 2018 pikachu987 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 | 21 | import Foundation 22 | import Photos 23 | 24 | class PermissionHelper: NSObject { 25 | private override init() { } 26 | 27 | static var permissionGalleryDeniedTitle: String? = "Permission Error" 28 | static var permissionGalleryDeniedMessage: String? = "Please allow photo albums permission" 29 | static var permissionCameraDeniedTitle: String? = "Permission Error" 30 | static var permissionCameraDeniedMessage: String? = "Please allow camera albums permission" 31 | static var permissionActionCancelTitle: String? = "Cancel" 32 | static var permissionActionMoveTitle: String? = "Move" 33 | 34 | // Gallery Permission 35 | static func galleryPermission(_ handler: @escaping ((UIAlertController?) -> Void)) { 36 | DispatchQueue.main.async { 37 | if PHPhotoLibrary.authorizationStatus() == .authorized { 38 | handler(nil) 39 | } else if PHPhotoLibrary.authorizationStatus() == .denied { 40 | handler(self.deniedAlertController(self.permissionGalleryDeniedTitle, message: self.permissionGalleryDeniedMessage)) 41 | } else { 42 | PHPhotoLibrary.requestAuthorization() { (status) in 43 | switch status { 44 | case .authorized: 45 | DispatchQueue.main.async { 46 | handler(nil) 47 | } 48 | break 49 | default: 50 | DispatchQueue.main.async { 51 | handler(self.deniedAlertController(self.permissionGalleryDeniedTitle, message: self.permissionGalleryDeniedMessage)) 52 | } 53 | } 54 | } 55 | } 56 | } 57 | } 58 | 59 | 60 | // Camera Permission 61 | static func cameraPermission(_ handler: @escaping ((UIAlertController?) -> Void)) { 62 | DispatchQueue.main.async { 63 | if AVCaptureDevice.authorizationStatus(for: AVMediaType.video) == .authorized { 64 | handler(nil) 65 | } else if AVCaptureDevice.authorizationStatus(for: AVMediaType.video) == .denied { 66 | handler(self.deniedAlertController(self.permissionCameraDeniedTitle, message: self.permissionCameraDeniedMessage)) 67 | } else { 68 | AVCaptureDevice.requestAccess(for: AVMediaType.video) { (isAccess) in 69 | if isAccess{ 70 | DispatchQueue.main.async { 71 | handler(nil) 72 | } 73 | } else { 74 | DispatchQueue.main.async { 75 | handler(self.deniedAlertController(self.permissionCameraDeniedTitle, message: self.permissionCameraDeniedMessage)) 76 | } 77 | } 78 | } 79 | } 80 | } 81 | } 82 | 83 | // Denied 84 | private static func deniedAlertController(_ title: String?, message: String?) -> UIAlertController { 85 | let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert) 86 | alertController.addAction(UIAlertAction(title: self.permissionActionCancelTitle, style: .cancel, handler: nil)) 87 | alertController.addAction(UIAlertAction(title: self.permissionActionMoveTitle, style: .default, handler: { (_) in 88 | self.openSetting() 89 | })) 90 | return alertController 91 | } 92 | 93 | // Setting 94 | private static func openSetting() { 95 | guard let bundleIdentifier = Bundle.main.bundleIdentifier else { return } 96 | guard let url = URL(string: "\(UIApplication.openSettingsURLString)\(bundleIdentifier)") else { return } 97 | if !UIApplication.shared.canOpenURL(url) { return } 98 | 99 | if #available(iOS 8.0, *) { 100 | UIApplication.shared.openURL(url) 101 | } else { 102 | UIApplication.shared.open(url, options: [:], completionHandler: nil) 103 | } 104 | } 105 | 106 | } 107 | -------------------------------------------------------------------------------- /CropPickerController/Classes/PictureCell.swift: -------------------------------------------------------------------------------- 1 | //Copyright (c) 2018 pikachu987 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 | 21 | import UIKit 22 | 23 | // PictureCell 24 | class PictureCell: UICollectionViewCell { 25 | static let identifier = "PictureCell" 26 | static var cameraBackgroundColor = UIColor(white: 212/255, alpha: 1) 27 | static var cameraTintColor = UIColor.white 28 | static var dimColor = UIColor(white: 0, alpha: 0.5) 29 | 30 | private lazy var imageView: UIImageView = { 31 | let imageView = UIImageView() 32 | self.contentView.addSubview(imageView) 33 | imageView.translatesAutoresizingMaskIntoConstraints = false 34 | self.contentView.edgesConstraint(subView: imageView) 35 | return imageView 36 | }() 37 | 38 | private lazy var dimView: UIView = { 39 | let view = UIView() 40 | self.contentView.addSubview(view) 41 | view.translatesAutoresizingMaskIntoConstraints = false 42 | self.contentView.edgesConstraint(subView: view) 43 | return view 44 | }() 45 | 46 | private lazy var checkBoxView: CheckBoxView = { 47 | let view = CheckBoxView() 48 | self.contentView.addSubview(view) 49 | view.translatesAutoresizingMaskIntoConstraints = false 50 | self.contentView.topConstraint(subView: view, constant: -10) 51 | self.contentView.trailingConstraint(subView: view, constant: 10) 52 | view.sizeConstraint(constant: 24) 53 | return view 54 | }() 55 | 56 | private lazy var cameraView: CameraView = { 57 | let view = CameraView(PictureCell.cameraTintColor) 58 | view.backgroundColor = PictureCell.cameraBackgroundColor 59 | self.contentView.addSubview(view) 60 | view.translatesAutoresizingMaskIntoConstraints = false 61 | self.contentView.centerXConstraint(subView: view) 62 | self.contentView.centerYConstraint(subView: view) 63 | view.sizeConstraint(constant: 40) 64 | return view 65 | }() 66 | 67 | override func prepareForReuse() { 68 | super.prepareForReuse() 69 | 70 | self.imageView.image = nil 71 | self.dimView.backgroundColor = .clear 72 | self.checkBoxView.isHidden = true 73 | } 74 | 75 | override init(frame: CGRect) { 76 | super.init(frame: frame) 77 | 78 | self.clipsToBounds = true 79 | self.imageView.contentMode = .scaleAspectFill 80 | self.dimView.backgroundColor = .clear 81 | self.cameraView.isHidden = true 82 | } 83 | 84 | required init?(coder aDecoder: NSCoder) { 85 | super.init(coder: aDecoder) 86 | } 87 | 88 | func setEntity(_ cropPickerType: CropPickerType, item: ImageAsset, isSelected: Bool) { 89 | if item.type == .camera { 90 | self.cameraView.isHidden = false 91 | self.dimView.backgroundColor = PictureCell.cameraBackgroundColor 92 | } else { 93 | self.cameraView.isHidden = true 94 | self.imageView.image = item.image 95 | self.dimView.backgroundColor = isSelected ? PictureCell.dimColor : .clear 96 | self.checkBoxView.isHidden = false 97 | if cropPickerType == .single { 98 | self.checkBoxView.setEntity(isSelected) 99 | } else { 100 | self.checkBoxView.setEntity(item.number) 101 | } 102 | } 103 | } 104 | 105 | func setEntity(_ item: ImageAsset) { 106 | self.imageView.image = item.image 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /CropPickerController/Classes/ProgressView.swift: -------------------------------------------------------------------------------- 1 | //Copyright (c) 2018 pikachu987 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 | 21 | import UIKit 22 | 23 | // ProgressView 24 | class ProgressView: UIView { 25 | static var textColor = UIColor.white 26 | static var progressColor = UIColor(white: 206/255, alpha: 1) 27 | static var progressTintColor = UIColor(red: 15/255, green: 148/255, blue: 252/255, alpha: 1) 28 | static var progressBackgroundColor = UIColor.black 29 | 30 | 31 | private var progress: CGFloat = 0 32 | 33 | private lazy var label: UILabel = { 34 | let label = UILabel() 35 | self.addSubview(label) 36 | label.font = UIFont.systemFont(ofSize: 10) 37 | label.textColor = ProgressView.textColor 38 | label.translatesAutoresizingMaskIntoConstraints = false 39 | self.centerXConstraint(subView: label) 40 | self.centerYConstraint(subView: label) 41 | return label 42 | }() 43 | 44 | func setProgress(_ progress: CGFloat) { 45 | self.progress = progress 46 | self.label.text = String(format: "%.1f", progress*100).appending("%") 47 | self.setNeedsDisplay() 48 | } 49 | 50 | override func draw(_ rect: CGRect) { 51 | self.backgroundColor = UIColor.clear 52 | self.layer.cornerRadius = 25 53 | self.clipsToBounds = true 54 | 55 | let bezierPath = UIBezierPath(rect: rect) 56 | ProgressView.progressBackgroundColor.setFill() 57 | bezierPath.fill() 58 | bezierPath.close() 59 | 60 | let center = CGPoint(x: rect.width/2, y: rect.height/2) 61 | 62 | let backgroundBezierPath = UIBezierPath() 63 | backgroundBezierPath.addArc(withCenter: center, radius: rect.width/2-1.5, startAngle: 0, endAngle: CGFloat.pi * 2, clockwise: true) 64 | backgroundBezierPath.lineWidth = 3 65 | ProgressView.progressColor.set() 66 | backgroundBezierPath.stroke() 67 | backgroundBezierPath.close() 68 | 69 | let foregroundBezierPath = UIBezierPath() 70 | let startAngle = CGFloat.pi * 3.5 71 | let endAngle = startAngle + (CGFloat.pi * 2 * self.progress) 72 | foregroundBezierPath.addArc(withCenter: center, radius: rect.width/2, startAngle: startAngle, endAngle: endAngle, clockwise: true) 73 | foregroundBezierPath.lineWidth = 8 74 | foregroundBezierPath.lineJoinStyle = .miter 75 | ProgressView.progressTintColor.set() 76 | foregroundBezierPath.stroke() 77 | foregroundBezierPath.close() 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /CropPickerController/Classes/TitleButton.swift: -------------------------------------------------------------------------------- 1 | //Copyright (c) 2018 pikachu987 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 | 21 | import UIKit 22 | 23 | // Title Button 24 | class TitleButton: UIButton { 25 | 26 | override func setTitleColor(_ color: UIColor?, for state: UIControl.State) { 27 | super.setTitleColor(color, for: state) 28 | if self.currentTitle != nil { 29 | self.setImage(ArrowBottomView.imageView(color ?? .black), for: .normal) 30 | } 31 | } 32 | 33 | override func setTitle(_ title: String?, for state: UIControl.State) { 34 | super.setTitle(title, for: state) 35 | if title != nil { 36 | self.setImage(ArrowBottomView.imageView(self.currentTitleColor), for: .normal) 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /CropPickerController/Classes/UIImage+.swift: -------------------------------------------------------------------------------- 1 | //Copyright (c) 2018 pikachu987 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 | 21 | import UIKit 22 | 23 | extension UIImage { 24 | var fixOrientation: UIImage? { 25 | if self.imageOrientation == .up { return self } 26 | var transform = CGAffineTransform.identity 27 | 28 | if ( self.imageOrientation == .down || self.imageOrientation == .downMirrored ) { 29 | transform = transform.translatedBy(x: self.size.width, y: self.size.height) 30 | transform = transform.rotated(by: CGFloat.pi) 31 | } 32 | 33 | if ( self.imageOrientation == .left || self.imageOrientation == .leftMirrored ) { 34 | transform = transform.translatedBy(x: self.size.width, y: 0) 35 | transform = transform.rotated(by: CGFloat.pi / 2.0) 36 | } 37 | 38 | if ( self.imageOrientation == .right || self.imageOrientation == .rightMirrored ) { 39 | transform = transform.translatedBy(x: 0, y: self.size.height); 40 | transform = transform.rotated(by: -CGFloat.pi / 2.0); 41 | } 42 | 43 | if ( self.imageOrientation == .upMirrored || self.imageOrientation == .downMirrored ) { 44 | transform = transform.translatedBy(x: self.size.width, y: 0) 45 | transform = transform.scaledBy(x: -1, y: 1) 46 | } 47 | 48 | if ( self.imageOrientation == .leftMirrored || self.imageOrientation == .rightMirrored ) { 49 | transform = transform.translatedBy(x: self.size.height, y: 0); 50 | transform = transform.scaledBy(x: -1, y: 1); 51 | } 52 | 53 | guard let cgImage = self.cgImage, 54 | let colorSpace = cgImage.colorSpace else { return nil } 55 | 56 | guard let ctx = CGContext(data: nil, width: Int(self.size.width), height: Int(self.size.height), 57 | bitsPerComponent: cgImage.bitsPerComponent, bytesPerRow: 0, 58 | space: colorSpace, 59 | bitmapInfo: cgImage.bitmapInfo.rawValue) else { return nil } 60 | 61 | ctx.concatenate(transform) 62 | 63 | if ( self.imageOrientation == .left || 64 | self.imageOrientation == .leftMirrored || 65 | self.imageOrientation == .right || 66 | self.imageOrientation == .rightMirrored ) { 67 | ctx.draw(cgImage, in: CGRect(x: 0,y: 0,width: self.size.height,height: self.size.width)) 68 | } else { 69 | ctx.draw(cgImage, in: CGRect(x: 0,y: 0,width: self.size.width,height: self.size.height)) 70 | } 71 | guard let makeImage = ctx.makeImage() else { return nil } 72 | return UIImage(cgImage: makeImage) 73 | } 74 | } 75 | 76 | -------------------------------------------------------------------------------- /CropPickerController/Classes/UIView+.swift: -------------------------------------------------------------------------------- 1 | //Copyright (c) 2018 pikachu987 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 | 21 | import UIKit 22 | 23 | extension UIView { 24 | var imageWithView: UIImage? { 25 | if #available(iOS 10.0, *) { 26 | let renderer = UIGraphicsImageRenderer(bounds: self.bounds) 27 | return renderer.image { rendererContext in 28 | self.layer.render(in: rendererContext.cgContext) 29 | } 30 | } else { 31 | UIGraphicsBeginImageContextWithOptions(self.bounds.size, self.isOpaque, 0.0) 32 | if let cgContext = UIGraphicsGetCurrentContext() { 33 | self.layer.render(in: cgContext) 34 | } 35 | self.drawHierarchy(in: self.bounds, afterScreenUpdates: true) 36 | let image = UIGraphicsGetImageFromCurrentImageContext() 37 | UIGraphicsEndImageContext() 38 | return image 39 | } 40 | } 41 | 42 | func edgesConstraint(subView: UIView, constant: CGFloat = 0) { 43 | self.leadingConstraint(subView: subView, constant: constant) 44 | self.trailingConstraint(subView: subView, constant: constant) 45 | self.topConstraint(subView: subView, constant: constant) 46 | self.bottomConstraint(subView: subView, constant: constant) 47 | } 48 | 49 | func sizeConstraint(subView: UIView, constant: CGFloat = 0) { 50 | self.widthConstraint(subView: subView, constant: constant) 51 | self.heightConstraint(subView: subView, constant: constant) 52 | } 53 | 54 | func sizeConstraint(constant: CGFloat = 0) { 55 | self.widthConstraint(constant: constant) 56 | self.heightConstraint(constant: constant) 57 | } 58 | 59 | @discardableResult 60 | func leadingConstraint(subView: UIView, constant: CGFloat = 0, multiplier: CGFloat = 1, relatedBy: NSLayoutConstraint.Relation = .equal) -> NSLayoutConstraint { 61 | let constraint = NSLayoutConstraint(item: self, attribute: .leading, relatedBy: relatedBy, toItem: subView, attribute: .leading, multiplier: multiplier, constant: constant) 62 | self.addConstraint(constraint) 63 | return constraint 64 | } 65 | 66 | @discardableResult 67 | func trailingConstraint(subView: UIView, constant: CGFloat = 0, multiplier: CGFloat = 1, relatedBy: NSLayoutConstraint.Relation = .equal) -> NSLayoutConstraint { 68 | let constraint = NSLayoutConstraint(item: self, attribute: .trailing, relatedBy: relatedBy, toItem: subView, attribute: .trailing, multiplier: multiplier, constant: constant) 69 | self.addConstraint(constraint) 70 | return constraint 71 | } 72 | 73 | @discardableResult 74 | func topConstraint(subView: UIView, constant: CGFloat = 0, multiplier: CGFloat = 1, relatedBy: NSLayoutConstraint.Relation = .equal) -> NSLayoutConstraint { 75 | let constraint = NSLayoutConstraint(item: self, attribute: .top, relatedBy: relatedBy, toItem: subView, attribute: .top, multiplier: multiplier, constant: constant) 76 | self.addConstraint(constraint) 77 | return constraint 78 | } 79 | 80 | @discardableResult 81 | func bottomConstraint(subView: UIView, constant: CGFloat = 0, multiplier: CGFloat = 1, relatedBy: NSLayoutConstraint.Relation = .equal) -> NSLayoutConstraint { 82 | let constraint = NSLayoutConstraint(item: self, attribute: .bottom, relatedBy: relatedBy, toItem: subView, attribute: .bottom, multiplier: multiplier, constant: constant) 83 | self.addConstraint(constraint) 84 | return constraint 85 | } 86 | 87 | @discardableResult 88 | func centerXConstraint(subView: UIView, constant: CGFloat = 0, multiplier: CGFloat = 1, relatedBy: NSLayoutConstraint.Relation = .equal) -> NSLayoutConstraint { 89 | let constraint = NSLayoutConstraint(item: self, attribute: .centerX, relatedBy: relatedBy, toItem: subView, attribute: .centerX, multiplier: multiplier, constant: constant) 90 | self.addConstraint(constraint) 91 | return constraint 92 | } 93 | 94 | @discardableResult 95 | func centerYConstraint(subView: UIView, constant: CGFloat = 0, multiplier: CGFloat = 1, relatedBy: NSLayoutConstraint.Relation = .equal) -> NSLayoutConstraint { 96 | let constraint = NSLayoutConstraint(item: self, attribute: .centerY, relatedBy: relatedBy, toItem: subView, attribute: .centerY, multiplier: multiplier, constant: constant) 97 | self.addConstraint(constraint) 98 | return constraint 99 | } 100 | 101 | @discardableResult 102 | func leadingConstraint(item: UIView, subView: UIView, constant: CGFloat = 0, multiplier: CGFloat = 1, relatedBy: NSLayoutConstraint.Relation = .equal) -> NSLayoutConstraint { 103 | let constraint = NSLayoutConstraint(item: item, attribute: .leading, relatedBy: relatedBy, toItem: subView, attribute: .leading, multiplier: multiplier, constant: constant) 104 | self.addConstraint(constraint) 105 | return constraint 106 | } 107 | 108 | @discardableResult 109 | func trailingConstraint(item: UIView, subView: UIView, constant: CGFloat = 0, multiplier: CGFloat = 1, relatedBy: NSLayoutConstraint.Relation = .equal) -> NSLayoutConstraint { 110 | let constraint = NSLayoutConstraint(item: item, attribute: .trailing, relatedBy: relatedBy, toItem: subView, attribute: .trailing, multiplier: multiplier, constant: constant) 111 | self.addConstraint(constraint) 112 | return constraint 113 | } 114 | 115 | @discardableResult 116 | func topConstraint(item: UIView, subView: UIView, constant: CGFloat = 0, multiplier: CGFloat = 1, relatedBy: NSLayoutConstraint.Relation = .equal) -> NSLayoutConstraint { 117 | let constraint = NSLayoutConstraint(item: item, attribute: .top, relatedBy: relatedBy, toItem: subView, attribute: .top, multiplier: multiplier, constant: constant) 118 | self.addConstraint(constraint) 119 | return constraint 120 | } 121 | 122 | @discardableResult 123 | func bottomConstraint(item: UIView, subView: UIView, constant: CGFloat = 0, multiplier: CGFloat = 1, relatedBy: NSLayoutConstraint.Relation = .equal) -> NSLayoutConstraint { 124 | let constraint = NSLayoutConstraint(item: item, attribute: .bottom, relatedBy: relatedBy, toItem: subView, attribute: .bottom, multiplier: multiplier, constant: constant) 125 | self.addConstraint(constraint) 126 | return constraint 127 | } 128 | 129 | @discardableResult 130 | func centerXConstraint(item: UIView, subView: UIView, constant: CGFloat = 0, multiplier: CGFloat = 1, relatedBy: NSLayoutConstraint.Relation = .equal) -> NSLayoutConstraint { 131 | let constraint = NSLayoutConstraint(item: item, attribute: .centerX, relatedBy: relatedBy, toItem: subView, attribute: .centerX, multiplier: multiplier, constant: constant) 132 | self.addConstraint(constraint) 133 | return constraint 134 | } 135 | 136 | @discardableResult 137 | func centerYConstraint(item: UIView, subView: UIView, constant: CGFloat = 0, multiplier: CGFloat = 1, relatedBy: NSLayoutConstraint.Relation = .equal) -> NSLayoutConstraint { 138 | let constraint = NSLayoutConstraint(item: item, attribute: .centerY, relatedBy: relatedBy, toItem: subView, attribute: .centerY, multiplier: multiplier, constant: constant) 139 | self.addConstraint(constraint) 140 | return constraint 141 | } 142 | 143 | @discardableResult 144 | func widthConstraint(item: UIView, subView: UIView, constant: CGFloat = 0, multiplier: CGFloat = 1, relatedBy: NSLayoutConstraint.Relation = .equal) -> NSLayoutConstraint { 145 | let constraint = NSLayoutConstraint(item: item, attribute: .width, relatedBy: relatedBy, toItem: subView, attribute: .width, multiplier: multiplier, constant: constant) 146 | self.addConstraint(constraint) 147 | return constraint 148 | } 149 | 150 | @discardableResult 151 | func heightConstraint(item: UIView, subView: UIView, constant: CGFloat = 0, multiplier: CGFloat = 1, relatedBy: NSLayoutConstraint.Relation = .equal) -> NSLayoutConstraint { 152 | let constraint = NSLayoutConstraint(item: item, attribute: .height, relatedBy: relatedBy, toItem: subView, attribute: .height, multiplier: multiplier, constant: constant) 153 | self.addConstraint(constraint) 154 | return constraint 155 | } 156 | 157 | @discardableResult 158 | func widthConstraint(subView: UIView, constant: CGFloat = 0, multiplier: CGFloat = 1, relatedBy: NSLayoutConstraint.Relation = .equal) -> NSLayoutConstraint { 159 | let constraint = NSLayoutConstraint(item: self, attribute: .width, relatedBy: relatedBy, toItem: subView, attribute: .width, multiplier: multiplier, constant: constant) 160 | self.addConstraint(constraint) 161 | return constraint 162 | } 163 | 164 | @discardableResult 165 | func heightConstraint(subView: UIView, constant: CGFloat = 0, multiplier: CGFloat = 1, relatedBy: NSLayoutConstraint.Relation = .equal) -> NSLayoutConstraint { 166 | let constraint = NSLayoutConstraint(item: self, attribute: .height, relatedBy: relatedBy, toItem: subView, attribute: .height, multiplier: multiplier, constant: constant) 167 | self.addConstraint(constraint) 168 | return constraint 169 | } 170 | 171 | @discardableResult 172 | func widthConstraint(constant: CGFloat = 0, multiplier: CGFloat = 1, relatedBy: NSLayoutConstraint.Relation = .equal) -> NSLayoutConstraint { 173 | let constraint = NSLayoutConstraint(item: self, attribute: .width, relatedBy: relatedBy, toItem: nil, attribute: .width, multiplier: multiplier, constant: constant) 174 | self.addConstraint(constraint) 175 | return constraint 176 | } 177 | 178 | @discardableResult 179 | func heightConstraint(constant: CGFloat = 0, multiplier: CGFloat = 1, relatedBy: NSLayoutConstraint.Relation = .equal) -> NSLayoutConstraint { 180 | let constraint = NSLayoutConstraint(item: self, attribute: .height, relatedBy: relatedBy, toItem: nil, attribute: .height, multiplier: multiplier, constant: constant) 181 | self.addConstraint(constraint) 182 | return constraint 183 | } 184 | } 185 | -------------------------------------------------------------------------------- /Example/CropPickerController.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/CropPickerController.xcodeproj/xcshareddata/xcschemes/CropPickerController-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/CropPickerController.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Example/CropPickerController.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/CropPickerController/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // CropPickerController 4 | // 5 | // Created by pikachu987 on 11/28/2018. 6 | // Copyright (c) 2018 pikachu987. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool { 18 | 19 | return true 20 | } 21 | 22 | func applicationWillResignActive(_ application: UIApplication) { 23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 24 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 25 | } 26 | 27 | func applicationDidEnterBackground(_ application: UIApplication) { 28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 30 | } 31 | 32 | func applicationWillEnterForeground(_ application: UIApplication) { 33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 34 | } 35 | 36 | func applicationDidBecomeActive(_ application: UIApplication) { 37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 38 | } 39 | 40 | func applicationWillTerminate(_ application: UIApplication) { 41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 42 | } 43 | 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /Example/CropPickerController/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/CropPickerController/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 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 | -------------------------------------------------------------------------------- /Example/CropPickerController/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 | } 54 | -------------------------------------------------------------------------------- /Example/CropPickerController/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 | NSCameraUsageDescription 34 | Camera Usage Description 35 | NSPhotoLibraryUsageDescription 36 | Photo Libray Usage Description 37 | UISupportedInterfaceOrientations 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationLandscapeLeft 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /Example/CropPickerController/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // CropPickerController 4 | // 5 | // Created by pikachu987 on 11/28/2018. 6 | // Copyright (c) 2018 pikachu987. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import CropPickerController 11 | 12 | class TitleCell: UICollectionViewCell { 13 | @IBOutlet weak var titleLabel: UILabel! 14 | } 15 | 16 | class ImageCell: UITableViewCell { 17 | @IBOutlet weak var cropImageView: UIImageView! 18 | } 19 | 20 | enum CropType: String { 21 | case presentSignle = "Single present" 22 | case presentComplex = "Complex present" 23 | case pushSignle = "Single push" 24 | case pushComplex = "Complex push" 25 | case noneCameraSingle = "None Camera Single present" 26 | case noneCameraComplex = "None Camera Complex present" 27 | 28 | static let array = [ 29 | CropType.presentSignle, 30 | CropType.presentComplex, 31 | CropType.pushSignle, 32 | CropType.pushComplex, 33 | CropType.noneCameraSingle, 34 | CropType.noneCameraComplex, 35 | ] 36 | } 37 | 38 | class ViewController: UIViewController { 39 | @IBOutlet weak var collectionView: UICollectionView! 40 | @IBOutlet weak var tableView: UITableView! 41 | 42 | var array = [UIImage]() 43 | 44 | override func viewDidLoad() { 45 | super.viewDidLoad() 46 | // Do any additional setup after loading the view, typically from a nib. 47 | 48 | self.tableView.rowHeight = 150 49 | } 50 | 51 | override func didReceiveMemoryWarning() { 52 | super.didReceiveMemoryWarning() 53 | // Dispose of any resources that can be recreated. 54 | } 55 | 56 | func makeCropPickerController(_ type: CropPickerType, isCamera: Bool) -> CropPickerController { 57 | let cropPickerController = CropPickerController(type, isCamera: isCamera) 58 | cropPickerController.delegate = self 59 | 60 | // cropPickerController.leftBarButtonItem = UIBarButtonItem(title: "Back", style: .plain, target: cropPickerController, action: #selector(cropPickerController.backTap(_:))) 61 | // cropPickerController.rightBarButtonItem = UIBarButtonItem(title: "Crop", style: .done, target: cropPickerController, action: #selector(cropPickerController.cropTap(_:))) 62 | // 63 | // cropPickerController.leftBarButtonItem?.tintColor = .black 64 | // cropPickerController.rightBarButtonItem?.tintColor = .black 65 | // cropPickerController.titleButton.setTitleColor(.black, for: .normal) 66 | // 67 | // cropPickerController.cameraTintColor = .red 68 | // cropPickerController.cameraBackgroundColor = UIColor(white: 0.2, alpha: 1) 69 | // 70 | // cropPickerController.pictureDimColor = UIColor(red: 242/255, green: 121/255, blue: 141/255, alpha: 0.5) 71 | // 72 | // cropPickerController.selectBoxTintColor = .black 73 | // cropPickerController.selectBoxLayerColor = .gray 74 | // cropPickerController.selectBoxBackgroundColor = .gray 75 | // 76 | // cropPickerController.permissionGalleryDeniedTitle = "Denied" 77 | // cropPickerController.permissionGalleryDeniedMessage = "Denied Gallery" 78 | // cropPickerController.permissionCameraDeniedTitle = "Denied" 79 | // cropPickerController.permissionCameraDeniedMessage = "Denied Camera" 80 | // cropPickerController.permissionActionMoveTitle = "Move~" 81 | // cropPickerController.permissionActionCancelTitle = "Cancel!" 82 | // 83 | // cropPickerController.progressTextColor = .black 84 | // cropPickerController.progressColor = .red 85 | // cropPickerController.progressTintColor = .blue 86 | // cropPickerController.progressBackgroundColor = .white 87 | // 88 | // cropPickerController.cropLineColor = .blue 89 | // cropPickerController.imageBackgroundColor = .white 90 | // cropPickerController.scrollBackgroundColor = .white 91 | // cropPickerController.cropDimBackgroundColor = UIColor(white: 0, alpha: 0.9) 92 | // cropPickerController.scrollMinimumZoomScale = 0.1 93 | // cropPickerController.scrollMaximumZoomScale = 12 94 | 95 | return cropPickerController 96 | } 97 | } 98 | 99 | // MARK: CropPickerDelegate 100 | extension ViewController: CropPickerDelegate { 101 | func cropPickerBackAction(_ cropPickerController: CropPickerController) { 102 | if (cropPickerController.navigationController?.viewControllers.first as? CropPickerController) == nil { 103 | cropPickerController.navigationController?.popViewController(animated: true) 104 | } else { 105 | cropPickerController.dismiss(animated: true, completion: nil) 106 | } 107 | } 108 | func cropPickerCompleteAction(_ cropPickerController: CropPickerController, images: [UIImage]?, error: Error?) { 109 | if let error = error as NSError? { 110 | let alertController = UIAlertController(title: "Error", message: error.domain, preferredStyle: .alert) 111 | alertController.addAction(UIAlertAction(title: "Ok", style: .cancel, handler: nil)) 112 | cropPickerController.present(alertController, animated: true, completion: nil) 113 | return 114 | } 115 | 116 | if (cropPickerController.navigationController?.viewControllers.first as? CropPickerController) == nil { 117 | cropPickerController.navigationController?.popViewController(animated: true) 118 | } else { 119 | cropPickerController.dismiss(animated: true, completion: nil) 120 | } 121 | 122 | if let images = images { 123 | self.array = images 124 | self.tableView.reloadData() 125 | } 126 | } 127 | } 128 | 129 | 130 | extension ViewController: UITableViewDelegate, UITableViewDataSource, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout { 131 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { 132 | let text = CropType.array[indexPath.row].rawValue 133 | let size = text.size(withAttributes: [NSAttributedString.Key.font : UIFont.systemFont(ofSize: 17)]) 134 | return CGSize(width: size.width + 20, height: 60) 135 | } 136 | 137 | func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 138 | return CropType.array.count 139 | } 140 | 141 | func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 142 | let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "TitleCell", for: indexPath) as! TitleCell 143 | cell.titleLabel.text = CropType.array[indexPath.row].rawValue 144 | return cell 145 | } 146 | 147 | func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { 148 | let element = CropType.array[indexPath.row] 149 | if element == .presentSignle { 150 | let cropPickerController = self.makeCropPickerController(.single, isCamera: true) 151 | let navigationController = UINavigationController(rootViewController: cropPickerController) 152 | self.present(navigationController, animated: true, completion: nil) 153 | } 154 | else if element == .presentComplex { 155 | let cropPickerController = self.makeCropPickerController(.complex, isCamera: true) 156 | let navigationController = UINavigationController(rootViewController: cropPickerController) 157 | self.present(navigationController, animated: true, completion: nil) 158 | } 159 | else if element == .pushSignle { 160 | let cropPickerController = self.makeCropPickerController(.single, isCamera: true) 161 | self.navigationController?.pushViewController(cropPickerController, animated: true) 162 | } 163 | else if element == .pushComplex { 164 | let cropPickerController = self.makeCropPickerController(.complex, isCamera: true) 165 | self.navigationController?.pushViewController(cropPickerController, animated: true) 166 | } 167 | else if element == .noneCameraSingle { 168 | let cropPickerController = self.makeCropPickerController(.single, isCamera: false) 169 | let navigationController = UINavigationController(rootViewController: cropPickerController) 170 | self.present(navigationController, animated: true, completion: nil) 171 | } 172 | else if element == .noneCameraComplex { 173 | let cropPickerController = self.makeCropPickerController(.complex, isCamera: false) 174 | let navigationController = UINavigationController(rootViewController: cropPickerController) 175 | self.present(navigationController, animated: true, completion: nil) 176 | } 177 | } 178 | 179 | 180 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 181 | return self.array.count 182 | } 183 | 184 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 185 | let cell = tableView.dequeueReusableCell(withIdentifier: "ImageCell", for: indexPath) as! ImageCell 186 | cell.cropImageView.image = self.array[indexPath.row] 187 | return cell 188 | } 189 | } 190 | -------------------------------------------------------------------------------- /Example/Podfile: -------------------------------------------------------------------------------- 1 | use_frameworks! 2 | 3 | target 'CropPickerController_Example' do 4 | pod 'CropPickerController', :path => '../' 5 | 6 | target 'CropPickerController_Tests' do 7 | inherit! :search_paths 8 | 9 | 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /Example/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - CropPickerController (0.1.4): 3 | - CropPickerView (= 0.2.7) 4 | - CropPickerView (0.2.7) 5 | 6 | DEPENDENCIES: 7 | - CropPickerController (from `../`) 8 | 9 | SPEC REPOS: 10 | trunk: 11 | - CropPickerView 12 | 13 | EXTERNAL SOURCES: 14 | CropPickerController: 15 | :path: "../" 16 | 17 | SPEC CHECKSUMS: 18 | CropPickerController: 6f1d936ec911207d452b436518460cf3198f5095 19 | CropPickerView: 22104910c3daeb7d9da9018dd10831736e20df3a 20 | 21 | PODFILE CHECKSUM: 9bf33656ba265ea726d5aec83a61aa09c91c0e6d 22 | 23 | COCOAPODS: 1.10.1 24 | -------------------------------------------------------------------------------- /Example/Pods/CropPickerView/CropPickerView/Classes/BezierPath+.swift: -------------------------------------------------------------------------------- 1 | //Copyright (c) 2018 pikachu987 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 | 21 | import UIKit 22 | 23 | extension UIBezierPath { 24 | @discardableResult 25 | func move(_ x: CGFloat, _ y: CGFloat) -> UIBezierPath{ 26 | self.move(to: CGPoint(x: x, y: y)) 27 | return self 28 | } 29 | 30 | @discardableResult 31 | func line(_ x: CGFloat, _ y: CGFloat) -> UIBezierPath { 32 | self.addLine(to: CGPoint(x: x, y: y)) 33 | return self 34 | } 35 | 36 | @discardableResult 37 | func closed() -> UIBezierPath { 38 | self.close() 39 | return self 40 | } 41 | 42 | @discardableResult 43 | func strokeFill(_ color: UIColor, lineWidth: CGFloat = 1) -> UIBezierPath { 44 | color.set() 45 | self.lineWidth = lineWidth 46 | self.stroke() 47 | self.fill() 48 | return self 49 | } 50 | 51 | @discardableResult 52 | func stroke(_ color: UIColor, lineWidth: CGFloat = 1) -> UIBezierPath { 53 | color.set() 54 | self.lineWidth = lineWidth 55 | self.stroke() 56 | return self 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Example/Pods/CropPickerView/CropPickerView/Classes/CropDimView.swift: -------------------------------------------------------------------------------- 1 | //Copyright (c) 2018 pikachu987 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 | 21 | import UIKit 22 | 23 | // CropDimView 24 | class CropDimView: UIView { 25 | private var path: CGPath? 26 | 27 | init() { 28 | super.init(frame: .zero) 29 | self.isUserInteractionEnabled = false 30 | } 31 | 32 | required init?(coder aDecoder: NSCoder) { 33 | super.init(coder: aDecoder) 34 | } 35 | 36 | func mask(_ path: CGPath, duration: TimeInterval, animated: Bool) { 37 | self.path = path 38 | if let mask = self.layer.mask as? CAShapeLayer { 39 | mask.removeAllAnimations() 40 | if animated { 41 | let animation = CABasicAnimation(keyPath: "path") 42 | animation.delegate = self 43 | animation.fromValue = mask.path 44 | animation.toValue = path 45 | animation.byValue = path 46 | animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut) 47 | animation.isRemovedOnCompletion = false 48 | animation.fillMode = .forwards 49 | animation.duration = duration 50 | mask.add(animation, forKey: "path") 51 | } else { 52 | mask.path = path 53 | } 54 | } else { 55 | let maskLayer = CAShapeLayer() 56 | maskLayer.fillRule = CAShapeLayerFillRule.evenOdd 57 | maskLayer.backgroundColor = UIColor.clear.cgColor 58 | maskLayer.path = path 59 | self.layer.mask = maskLayer 60 | } 61 | } 62 | } 63 | 64 | // MARK: CAAnimationDelegate 65 | extension CropDimView: CAAnimationDelegate { 66 | public func animationDidStop(_ anim: CAAnimation, finished flag: Bool) { 67 | guard let path = self.path else { return } 68 | if let mask = self.layer.mask as? CAShapeLayer { 69 | mask.removeAllAnimations() 70 | mask.path = path 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /Example/Pods/CropPickerView/CropPickerView/Classes/CropResult.swift: -------------------------------------------------------------------------------- 1 | //Copyright (c) 2018 pikachu987 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 | 21 | import Foundation 22 | 23 | public struct CropResult { 24 | public var error: Error? 25 | public var image: UIImage? 26 | public var cropFrame: CGRect? 27 | public var imageSize: CGSize? 28 | public var realCropFrame: CGRect? 29 | 30 | public init() { } 31 | } 32 | -------------------------------------------------------------------------------- /Example/Pods/CropPickerView/CropPickerView/Classes/CropView.swift: -------------------------------------------------------------------------------- 1 | //Copyright (c) 2018 pikachu987 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 | 21 | import UIKit 22 | 23 | // Crop LineView 24 | class CropView: UIView { 25 | private let margin: CGFloat = 0 26 | private let lineSize: CGFloat = 1 27 | 28 | var lineColor: UIColor? = .white { 29 | willSet { 30 | self.topLineView.backgroundColor = newValue 31 | self.bottomLineView.backgroundColor = newValue 32 | self.leftLineView.backgroundColor = newValue 33 | self.rightLineView.backgroundColor = newValue 34 | self.horizontalRightLineView.backgroundColor = newValue 35 | self.horizontalLeftLineView.backgroundColor = newValue 36 | self.verticalTopLineView.backgroundColor = newValue 37 | self.verticalBottomLineView.backgroundColor = newValue 38 | } 39 | } 40 | 41 | private lazy var topLineView: UIView = { 42 | let view = UIView() 43 | self.addSubview(view) 44 | view.translatesAutoresizingMaskIntoConstraints = false 45 | self.addConstraint(NSLayoutConstraint(item: self, attribute: .leading, relatedBy: .equal, toItem: view, attribute: .leading, multiplier: 1, constant: self.margin).priority(950)) 46 | self.addConstraint(NSLayoutConstraint(item: self, attribute: .trailing, relatedBy: .equal, toItem: view, attribute: .trailing, multiplier: 1, constant: self.margin).priority(950)) 47 | self.addConstraint(NSLayoutConstraint(item: self, attribute: .top, relatedBy: .equal, toItem: view, attribute: .top, multiplier: 1, constant: self.margin).priority(950)) 48 | view.addConstraint(NSLayoutConstraint(item: view, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 1, constant: self.lineSize).priority(950)) 49 | return view 50 | }() 51 | 52 | private lazy var leftLineView: UIView = { 53 | let view = UIView() 54 | self.addSubview(view) 55 | view.translatesAutoresizingMaskIntoConstraints = false 56 | self.addConstraint(NSLayoutConstraint(item: self, attribute: .leading, relatedBy: .equal, toItem: view, attribute: .leading, multiplier: 1, constant: self.margin).priority(950)) 57 | self.addConstraint(NSLayoutConstraint(item: self, attribute: .bottom, relatedBy: .equal, toItem: view, attribute: .bottom, multiplier: 1, constant: self.margin).priority(950)) 58 | self.addConstraint(NSLayoutConstraint(item: self, attribute: .top, relatedBy: .equal, toItem: view, attribute: .top, multiplier: 1, constant: self.margin).priority(950)) 59 | view.addConstraint(NSLayoutConstraint(item: view, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .width, multiplier: 1, constant: self.lineSize).priority(950)) 60 | return view 61 | }() 62 | 63 | private lazy var bottomLineView: UIView = { 64 | let view = UIView() 65 | self.addSubview(view) 66 | view.translatesAutoresizingMaskIntoConstraints = false 67 | self.addConstraint(NSLayoutConstraint(item: self, attribute: .leading, relatedBy: .equal, toItem: view, attribute: .leading, multiplier: 1, constant: self.margin).priority(950)) 68 | self.addConstraint(NSLayoutConstraint(item: self, attribute: .trailing, relatedBy: .equal, toItem: view, attribute: .trailing, multiplier: 1, constant: self.margin).priority(950)) 69 | self.addConstraint(NSLayoutConstraint(item: self, attribute: .bottom, relatedBy: .equal, toItem: view, attribute: .top, multiplier: 1, constant: self.margin).priority(950)) 70 | view.addConstraint(NSLayoutConstraint(item: view, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 1, constant: self.lineSize).priority(950)) 71 | return view 72 | }() 73 | 74 | private lazy var rightLineView: UIView = { 75 | let view = UIView() 76 | self.addSubview(view) 77 | view.translatesAutoresizingMaskIntoConstraints = false 78 | self.addConstraint(NSLayoutConstraint(item: self, attribute: .trailing, relatedBy: .equal, toItem: view, attribute: .trailing, multiplier: 1, constant: self.margin).priority(950)) 79 | self.addConstraint(NSLayoutConstraint(item: self, attribute: .bottom, relatedBy: .equal, toItem: view, attribute: .bottom, multiplier: 1, constant: self.margin).priority(950)) 80 | self.addConstraint(NSLayoutConstraint(item: self, attribute: .top, relatedBy: .equal, toItem: view, attribute: .top, multiplier: 1, constant: self.margin).priority(950)) 81 | view.addConstraint(NSLayoutConstraint(item: view, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .width, multiplier: 1, constant: self.lineSize).priority(950)) 82 | return view 83 | }() 84 | 85 | private lazy var horizontalLeftLineView: UIView = { 86 | let view = UIView() 87 | self.addSubview(view) 88 | view.translatesAutoresizingMaskIntoConstraints = false 89 | self.addConstraint(NSLayoutConstraint(item: self.horizontalLeftView, attribute: .trailing, relatedBy: .equal, toItem: view, attribute: .leading, multiplier: 1, constant: 0).priority(950)) 90 | self.addConstraint(NSLayoutConstraint(item: self.bottomLineView, attribute: .top, relatedBy: .equal, toItem: view, attribute: .bottom, multiplier: 1, constant: 0).priority(950)) 91 | self.addConstraint(NSLayoutConstraint(item: self.topLineView, attribute: .bottom, relatedBy: .equal, toItem: view, attribute: .top, multiplier: 1, constant: 0).priority(950)) 92 | view.addConstraint(NSLayoutConstraint(item: view, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .width, multiplier: 1, constant: self.lineSize).priority(950)) 93 | return view 94 | }() 95 | 96 | private lazy var horizontalRightLineView: UIView = { 97 | let view = UIView() 98 | self.addSubview(view) 99 | view.translatesAutoresizingMaskIntoConstraints = false 100 | self.addConstraint(NSLayoutConstraint(item: self.horizontalCenterView, attribute: .trailing, relatedBy: .equal, toItem: view, attribute: .leading, multiplier: 1, constant: 0).priority(950)) 101 | self.addConstraint(NSLayoutConstraint(item: self.bottomLineView, attribute: .top, relatedBy: .equal, toItem: view, attribute: .bottom, multiplier: 1, constant: 0).priority(950)) 102 | self.addConstraint(NSLayoutConstraint(item: self.topLineView, attribute: .bottom, relatedBy: .equal, toItem: view, attribute: .top, multiplier: 1, constant: 0).priority(950)) 103 | view.addConstraint(NSLayoutConstraint(item: view, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .width, multiplier: 1, constant: self.lineSize).priority(950)) 104 | return view 105 | }() 106 | 107 | private lazy var verticalTopLineView: UIView = { 108 | let view = UIView() 109 | self.addSubview(view) 110 | view.translatesAutoresizingMaskIntoConstraints = false 111 | self.addConstraint(NSLayoutConstraint(item: self.verticalTopView, attribute: .bottom, relatedBy: .equal, toItem: view, attribute: .top, multiplier: 1, constant: 0).priority(950)) 112 | self.addConstraint(NSLayoutConstraint(item: self.leftLineView, attribute: .trailing, relatedBy: .equal, toItem: view, attribute: .leading, multiplier: 1, constant: 0).priority(950)) 113 | self.addConstraint(NSLayoutConstraint(item: self.rightLineView, attribute: .leading, relatedBy: .equal, toItem: view, attribute: .trailing, multiplier: 1, constant: 0).priority(950)) 114 | view.addConstraint(NSLayoutConstraint(item: view, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 1, constant: self.lineSize).priority(950)) 115 | return view 116 | }() 117 | 118 | private lazy var verticalBottomLineView: UIView = { 119 | let view = UIView() 120 | self.addSubview(view) 121 | view.translatesAutoresizingMaskIntoConstraints = false 122 | self.addConstraint(NSLayoutConstraint(item: self.verticalCenterView, attribute: .bottom, relatedBy: .equal, toItem: view, attribute: .top, multiplier: 1, constant: 0).priority(950)) 123 | self.addConstraint(NSLayoutConstraint(item: self.leftLineView, attribute: .trailing, relatedBy: .equal, toItem: view, attribute: .leading, multiplier: 1, constant: 0).priority(950)) 124 | self.addConstraint(NSLayoutConstraint(item: self.rightLineView, attribute: .leading, relatedBy: .equal, toItem: view, attribute: .trailing, multiplier: 1, constant: 0).priority(950)) 125 | view.addConstraint(NSLayoutConstraint(item: view, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 1, constant: self.lineSize).priority(950)) 126 | return view 127 | }() 128 | 129 | private lazy var horizontalLeftView: UIView = { 130 | let view = UIView() 131 | self.addSubview(view) 132 | view.translatesAutoresizingMaskIntoConstraints = false 133 | self.addConstraint(NSLayoutConstraint(item: self.leftLineView, attribute: .trailing, relatedBy: .equal, toItem: view, attribute: .leading, multiplier: 1, constant: 0).priority(950)) 134 | self.addConstraint(NSLayoutConstraint(item: self.bottomLineView, attribute: .top, relatedBy: .equal, toItem: view, attribute: .bottom, multiplier: 1, constant: 0).priority(950)) 135 | self.addConstraint(NSLayoutConstraint(item: self.topLineView, attribute: .bottom, relatedBy: .equal, toItem: view, attribute: .top, multiplier: 1, constant: 0).priority(950)) 136 | return view 137 | }() 138 | 139 | private lazy var horizontalCenterView: UIView = { 140 | let view = UIView() 141 | self.addSubview(view) 142 | view.translatesAutoresizingMaskIntoConstraints = false 143 | self.addConstraint(NSLayoutConstraint(item: self.horizontalLeftLineView, attribute: .trailing, relatedBy: .equal, toItem: view, attribute: .leading, multiplier: 1, constant: 0).priority(950)) 144 | self.addConstraint(NSLayoutConstraint(item: self.bottomLineView, attribute: .top, relatedBy: .equal, toItem: view, attribute: .bottom, multiplier: 1, constant: 0).priority(950)) 145 | self.addConstraint(NSLayoutConstraint(item: self.topLineView, attribute: .bottom, relatedBy: .equal, toItem: view, attribute: .top, multiplier: 1, constant: 0).priority(950)) 146 | self.addConstraint(NSLayoutConstraint(item: self.horizontalLeftView, attribute: .width, relatedBy: .equal, toItem: view, attribute: .width, multiplier: 1, constant: 0).priority(950)) 147 | return view 148 | }() 149 | 150 | private lazy var horizontalRightView: UIView = { 151 | let view = UIView() 152 | self.addSubview(view) 153 | view.translatesAutoresizingMaskIntoConstraints = false 154 | self.addConstraint(NSLayoutConstraint(item: self.horizontalRightLineView, attribute: .trailing, relatedBy: .equal, toItem: view, attribute: .leading, multiplier: 1, constant: 0).priority(950)) 155 | self.addConstraint(NSLayoutConstraint(item: self.bottomLineView, attribute: .top, relatedBy: .equal, toItem: view, attribute: .bottom, multiplier: 1, constant: 0).priority(950)) 156 | self.addConstraint(NSLayoutConstraint(item: self.topLineView, attribute: .bottom, relatedBy: .equal, toItem: view, attribute: .top, multiplier: 1, constant: 0).priority(950)) 157 | self.addConstraint(NSLayoutConstraint(item: self.rightLineView, attribute: .leading, relatedBy: .equal, toItem: view, attribute: .trailing, multiplier: 1, constant: 0).priority(950)) 158 | self.addConstraint(NSLayoutConstraint(item: self.horizontalLeftView, attribute: .width, relatedBy: .equal, toItem: view, attribute: .width, multiplier: 1, constant: 0).priority(950)) 159 | return view 160 | }() 161 | 162 | private lazy var verticalTopView: UIView = { 163 | let view = UIView() 164 | self.addSubview(view) 165 | view.translatesAutoresizingMaskIntoConstraints = false 166 | self.addConstraint(NSLayoutConstraint(item: self.topLineView, attribute: .bottom, relatedBy: .equal, toItem: view, attribute: .top, multiplier: 1, constant: 0).priority(950)) 167 | self.addConstraint(NSLayoutConstraint(item: self.leftLineView, attribute: .trailing, relatedBy: .equal, toItem: view, attribute: .leading, multiplier: 1, constant: 0).priority(950)) 168 | self.addConstraint(NSLayoutConstraint(item: self.rightLineView, attribute: .leading, relatedBy: .equal, toItem: view, attribute: .trailing, multiplier: 1, constant: 0).priority(950)) 169 | return view 170 | }() 171 | 172 | private lazy var verticalCenterView: UIView = { 173 | let view = UIView() 174 | self.addSubview(view) 175 | view.translatesAutoresizingMaskIntoConstraints = false 176 | self.addConstraint(NSLayoutConstraint(item: self.verticalTopLineView, attribute: .bottom, relatedBy: .equal, toItem: view, attribute: .top, multiplier: 1, constant: 0).priority(950)) 177 | self.addConstraint(NSLayoutConstraint(item: self.leftLineView, attribute: .trailing, relatedBy: .equal, toItem: view, attribute: .leading, multiplier: 1, constant: 0).priority(950)) 178 | self.addConstraint(NSLayoutConstraint(item: self.rightLineView, attribute: .leading, relatedBy: .equal, toItem: view, attribute: .trailing, multiplier: 1, constant: 0).priority(950)) 179 | self.addConstraint(NSLayoutConstraint(item: self.verticalTopView, attribute: .height, relatedBy: .equal, toItem: view, attribute: .height, multiplier: 1, constant: 0).priority(950)) 180 | return view 181 | }() 182 | 183 | private lazy var verticalBottomView: UIView = { 184 | let view = UIView() 185 | self.addSubview(view) 186 | view.translatesAutoresizingMaskIntoConstraints = false 187 | self.addConstraint(NSLayoutConstraint(item: self.verticalBottomLineView, attribute: .bottom, relatedBy: .equal, toItem: view, attribute: .top, multiplier: 1, constant: 0).priority(950)) 188 | self.addConstraint(NSLayoutConstraint(item: self.leftLineView, attribute: .trailing, relatedBy: .equal, toItem: view, attribute: .leading, multiplier: 1, constant: 0).priority(950)) 189 | self.addConstraint(NSLayoutConstraint(item: self.rightLineView, attribute: .leading, relatedBy: .equal, toItem: view, attribute: .trailing, multiplier: 1, constant: 0).priority(950)) 190 | self.addConstraint(NSLayoutConstraint(item: self.verticalTopView, attribute: .height, relatedBy: .equal, toItem: view, attribute: .height, multiplier: 1, constant: 0).priority(950)) 191 | self.addConstraint(NSLayoutConstraint(item: self.bottomLineView, attribute: .top, relatedBy: .equal, toItem: view, attribute: .bottom, multiplier: 1, constant: 0).priority(950)) 192 | return view 193 | }() 194 | 195 | override func awakeFromNib() { 196 | super.awakeFromNib() 197 | 198 | self.initVars() 199 | } 200 | 201 | init() { 202 | super.init(frame: .zero) 203 | 204 | self.initVars() 205 | } 206 | 207 | override init(frame: CGRect) { 208 | super.init(frame: frame) 209 | 210 | self.initVars() 211 | } 212 | 213 | required init?(coder aDecoder: NSCoder) { 214 | super.init(coder: aDecoder) 215 | } 216 | 217 | private func initVars() { 218 | self.isUserInteractionEnabled = false 219 | self.backgroundColor = .clear 220 | self.topLineView.alpha = 1 221 | self.leftLineView.alpha = 1 222 | self.bottomLineView.alpha = 1 223 | self.rightLineView.alpha = 1 224 | self.horizontalLeftLineView.alpha = 0 225 | self.horizontalRightLineView.alpha = 0 226 | self.verticalTopLineView.alpha = 0 227 | self.verticalBottomLineView.alpha = 0 228 | 229 | self.horizontalLeftView.alpha = 0 230 | self.horizontalCenterView.alpha = 0 231 | self.horizontalRightView.alpha = 0 232 | self.verticalTopView.alpha = 0 233 | self.verticalCenterView.alpha = 0 234 | self.verticalBottomView.alpha = 0 235 | } 236 | 237 | func line(_ isHidden: Bool, animated: Bool) { 238 | if animated { 239 | UIView.animate(withDuration: 0.3) { 240 | if isHidden { 241 | self.horizontalRightLineView.alpha = 0 242 | self.horizontalLeftLineView.alpha = 0 243 | self.verticalTopLineView.alpha = 0 244 | self.verticalBottomLineView.alpha = 0 245 | } else { 246 | self.horizontalRightLineView.alpha = 1 247 | self.horizontalLeftLineView.alpha = 1 248 | self.verticalTopLineView.alpha = 1 249 | self.verticalBottomLineView.alpha = 1 250 | } 251 | } 252 | } else { 253 | if isHidden { 254 | self.horizontalRightLineView.alpha = 0 255 | self.horizontalLeftLineView.alpha = 0 256 | self.verticalTopLineView.alpha = 0 257 | self.verticalBottomLineView.alpha = 0 258 | } else { 259 | self.horizontalRightLineView.alpha = 1 260 | self.horizontalLeftLineView.alpha = 1 261 | self.verticalTopLineView.alpha = 1 262 | self.verticalBottomLineView.alpha = 1 263 | } 264 | } 265 | } 266 | } 267 | -------------------------------------------------------------------------------- /Example/Pods/CropPickerView/CropPickerView/Classes/LineButton.swift: -------------------------------------------------------------------------------- 1 | //Copyright (c) 2018 pikachu987 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 | 21 | import UIKit 22 | 23 | // Called when the button's highlighted is false. 24 | protocol LineButtonDelegate: class { 25 | func lineButtonUnHighlighted() 26 | } 27 | 28 | // Side, Edge LineButton 29 | class LineButton: UIButton { 30 | weak var delegate: LineButtonDelegate? 31 | 32 | private var type: ButtonLineType 33 | 34 | override var isHighlighted: Bool { 35 | didSet { 36 | if !self.isHighlighted { 37 | self.delegate?.lineButtonUnHighlighted() 38 | } 39 | } 40 | } 41 | 42 | // MARK: Init 43 | init(_ type: ButtonLineType) { 44 | self.type = type 45 | super.init(frame: CGRect(x: 0, y: 0, width: 50, height: 50)) 46 | 47 | self.setTitle(nil, for: .normal) 48 | self.translatesAutoresizingMaskIntoConstraints = false 49 | if type != .center { 50 | self.widthConstraint(constant: 50) 51 | self.heightConstraint(constant: 50) 52 | self.alpha = 0 53 | } 54 | } 55 | 56 | required init?(coder aDecoder: NSCoder) { 57 | fatalError("init(coder:) has not been implemented") 58 | } 59 | 60 | func edgeLine(_ color: UIColor?) { 61 | self.setImage(self.type.view(color)?.imageWithView?.withRenderingMode(.alwaysOriginal), for: .normal) 62 | } 63 | } 64 | 65 | enum ButtonLineType { 66 | case center 67 | case leftTop, rightTop, leftBottom, rightBottom, top, left, right, bottom 68 | 69 | var rotate: CGFloat { 70 | switch self { 71 | case .leftTop: 72 | return 0 73 | case .rightTop: 74 | return CGFloat.pi/2 75 | case .rightBottom: 76 | return CGFloat.pi 77 | case .leftBottom: 78 | return CGFloat.pi/2*3 79 | case .top: 80 | return 0 81 | case .left: 82 | return CGFloat.pi/2*3 83 | case .right: 84 | return CGFloat.pi/2 85 | case .bottom: 86 | return CGFloat.pi 87 | case .center: 88 | return 0 89 | } 90 | } 91 | 92 | var yMargin: CGFloat { 93 | switch self { 94 | case .rightBottom, .bottom: 95 | return 1 96 | default: 97 | return 0 98 | } 99 | } 100 | 101 | var xMargin: CGFloat { 102 | switch self { 103 | case .leftBottom: 104 | return 1 105 | default: 106 | return 0 107 | } 108 | } 109 | 110 | func view(_ color: UIColor?) -> UIView? { 111 | var view: UIView? 112 | if self == .leftTop || self == .rightTop || self == .leftBottom || self == .rightBottom { 113 | view = ButtonLineType.EdgeView(self, color: color) 114 | } else { 115 | view = ButtonLineType.SideView(self, color: color) 116 | } 117 | view?.isOpaque = false 118 | view?.tintColor = color 119 | return view 120 | } 121 | 122 | class LineView: UIView { 123 | var type: ButtonLineType 124 | var color: UIColor? 125 | init(_ type: ButtonLineType, color: UIColor?) { 126 | self.type = type 127 | self.color = color 128 | super.init(frame: CGRect(x: 0, y: 0, width: 50, height: 50)) 129 | } 130 | required init?(coder aDecoder: NSCoder) { 131 | fatalError("init(coder:) has not been implemented") 132 | } 133 | func apply(_ path: UIBezierPath) { 134 | var pathTransform = CGAffineTransform.identity 135 | pathTransform = pathTransform.translatedBy(x: 25, y: 25) 136 | pathTransform = pathTransform.rotated(by: self.type.rotate) 137 | pathTransform = pathTransform.translatedBy(x: -25 - self.type.xMargin, y: -25 - self.type.yMargin) 138 | path.apply(pathTransform) 139 | path.closed() 140 | .strokeFill(self.color ?? .white) 141 | } 142 | } 143 | 144 | class EdgeView: LineView { 145 | override func draw(_ rect: CGRect) { 146 | let path = UIBezierPath() 147 | .move(6, 6) 148 | .line(6, 20) 149 | .line(8, 20) 150 | .line(8, 8) 151 | .line(20, 8) 152 | .line(20, 6) 153 | .line(6, 6) 154 | self.apply(path) 155 | } 156 | } 157 | class SideView: LineView { 158 | override func draw(_ rect: CGRect) { 159 | let path = UIBezierPath() 160 | .move(15, 6) 161 | .line(35, 6) 162 | .line(35, 8) 163 | .line(15, 8) 164 | .line(15, 6) 165 | self.apply(path) 166 | } 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /Example/Pods/CropPickerView/CropPickerView/Classes/NSLayoutConstraint+.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NSLayoutConstraint+.swift 3 | // CropPickerView 4 | // 5 | // Created by Gwanho Kim on 02/12/2018. 6 | // 7 | 8 | import UIKit 9 | 10 | extension NSLayoutConstraint { 11 | func priority(_ value: CGFloat) -> NSLayoutConstraint { 12 | self.priority = UILayoutPriority(Float(value)) 13 | return self 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Example/Pods/CropPickerView/CropPickerView/Classes/UIImage+.swift: -------------------------------------------------------------------------------- 1 | //Copyright (c) 2018 pikachu987 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 | 21 | import UIKit 22 | 23 | extension UIImage { 24 | var fixOrientation: UIImage? { 25 | if self.imageOrientation == .up { return self } 26 | var transform = CGAffineTransform.identity 27 | 28 | if self.imageOrientation == .down || self.imageOrientation == .downMirrored { 29 | transform = transform.translatedBy(x: self.size.width, y: self.size.height) 30 | transform = transform.rotated(by: CGFloat(Double.pi)) 31 | } 32 | 33 | if self.imageOrientation == .left || self.imageOrientation == .leftMirrored { 34 | transform = transform.translatedBy(x: self.size.width, y: 0) 35 | transform = transform.rotated(by: CGFloat(Double.pi / 2.0)) 36 | } 37 | 38 | if self.imageOrientation == .right || self.imageOrientation == .rightMirrored { 39 | transform = transform.translatedBy(x: 0, y: self.size.height) 40 | transform = transform.rotated(by: CGFloat(-Double.pi / 2.0)) 41 | } 42 | 43 | if self.imageOrientation == .upMirrored || self.imageOrientation == .downMirrored { 44 | transform = transform.translatedBy(x: self.size.width, y: 0) 45 | transform = transform.scaledBy(x: -1, y: 1) 46 | } 47 | 48 | if self.imageOrientation == .leftMirrored || self.imageOrientation == .rightMirrored { 49 | transform = transform.translatedBy(x: self.size.height, y: 0) 50 | transform = transform.scaledBy(x: -1, y: 1) 51 | } 52 | 53 | guard let cgImage = self.cgImage, 54 | let colorSpace = cgImage.colorSpace else { return nil } 55 | 56 | guard let ctx = CGContext(data: nil, width: Int(self.size.width), height: Int(self.size.height), 57 | bitsPerComponent: cgImage.bitsPerComponent, bytesPerRow: 0, 58 | space: colorSpace, 59 | bitmapInfo: cgImage.bitmapInfo.rawValue) else { return nil } 60 | 61 | ctx.concatenate(transform) 62 | 63 | if self.imageOrientation == .left || 64 | self.imageOrientation == .leftMirrored || 65 | self.imageOrientation == .right || 66 | self.imageOrientation == .rightMirrored { 67 | ctx.draw(cgImage, in: CGRect(x: 0, y: 0, width: self.size.height, height: self.size.width)) 68 | } else { 69 | ctx.draw(cgImage, in: CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height)) 70 | } 71 | guard let makeImage = ctx.makeImage() else { return nil } 72 | return UIImage(cgImage: makeImage) 73 | } 74 | 75 | func crop(_ rect: CGRect, radius: CGFloat, radiusScale: CGFloat, scale: CGFloat = 1) -> UIImage? { 76 | UIGraphicsBeginImageContextWithOptions(CGSize(width: rect.size.width / scale, height: rect.size.height / scale), true, 0.0) 77 | self.draw(at: CGPoint(x: -rect.origin.x / scale, y: -rect.origin.y / scale)) 78 | let croppedImage = UIGraphicsGetImageFromCurrentImageContext() 79 | UIGraphicsEndImageContext() 80 | if radius == 0 { 81 | return croppedImage 82 | } else { 83 | guard let image = croppedImage else { return nil } 84 | let imageView = UIImageView(image: image) 85 | let layer = imageView.layer 86 | layer.masksToBounds = true 87 | layer.cornerRadius = radius * radiusScale 88 | UIGraphicsBeginImageContext(imageView.bounds.size) 89 | if let currentContext = UIGraphicsGetCurrentContext() { 90 | layer.render(in: currentContext) 91 | } 92 | let croppedImage = UIGraphicsGetImageFromCurrentImageContext() 93 | UIGraphicsEndImageContext() 94 | return croppedImage 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /Example/Pods/CropPickerView/CropPickerView/Classes/UIImageView+.swift: -------------------------------------------------------------------------------- 1 | //Copyright (c) 2018 pikachu987 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 | 21 | import UIKit 22 | 23 | extension UIImageView { 24 | var frameForImageInImageViewAspectFit: CGRect { 25 | if let img = self.image { 26 | let imageRatio = img.size.width / img.size.height 27 | let viewRatio = self.frame.size.width / self.frame.size.height 28 | if(imageRatio < viewRatio) { 29 | let scale = self.frame.size.height / img.size.height 30 | let width = scale * img.size.width 31 | let topLeftX = (self.frame.size.width - width) * 0.5 32 | return CGRect(x: topLeftX, y: 0, width: width, height: self.frame.size.height) 33 | } else { 34 | let scale = self.frame.size.width / img.size.width 35 | let height = scale * img.size.height 36 | let topLeftY = (self.frame.size.height - height) * 0.5 37 | return CGRect(x: 0, y: topLeftY, width: self.frame.size.width, height: height) 38 | } 39 | } 40 | return CGRect(x: 0, y: 0, width: 0, height: 0) 41 | } 42 | 43 | var imageFrame: CGRect { 44 | let imageViewSize = self.frame.size 45 | guard let imageSize = self.image?.size else { return CGRect.zero } 46 | let imageRatio = imageSize.width / imageSize.height 47 | let imageViewRatio = imageViewSize.width / imageViewSize.height 48 | if imageRatio < imageViewRatio { 49 | let scaleFactor = imageViewSize.height / imageSize.height 50 | let width = imageSize.width * scaleFactor 51 | let topLeftX = (imageViewSize.width - width) * 0.5 52 | return CGRect(x: topLeftX, y: 0, width: width, height: imageViewSize.height) 53 | } else { 54 | let scalFactor = imageViewSize.width / imageSize.width 55 | let height = imageSize.height * scalFactor 56 | let topLeftY = (imageViewSize.height - height) * 0.5 57 | return CGRect(x: 0, y: topLeftY, width: imageViewSize.width, height: height) 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Example/Pods/CropPickerView/CropPickerView/Classes/UIView+.swift: -------------------------------------------------------------------------------- 1 | //Copyright (c) 2018 pikachu987 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 | 21 | import UIKit 22 | 23 | extension UIView { 24 | 25 | var imageWithView: UIImage? { 26 | if #available(iOS 10.0, *) { 27 | let renderer = UIGraphicsImageRenderer(bounds: self.bounds) 28 | return renderer.image { rendererContext in 29 | self.layer.render(in: rendererContext.cgContext) 30 | } 31 | } else { 32 | UIGraphicsBeginImageContextWithOptions(self.bounds.size, self.isOpaque, 0.0) 33 | if let cgContext = UIGraphicsGetCurrentContext() { 34 | self.layer.render(in: cgContext) 35 | } 36 | self.drawHierarchy(in: self.bounds, afterScreenUpdates: true) 37 | let image = UIGraphicsGetImageFromCurrentImageContext() 38 | UIGraphicsEndImageContext() 39 | return image 40 | } 41 | } 42 | 43 | func edgesConstraint(subView: UIView, constant: CGFloat = 0) { 44 | self.leadingConstraint(subView: subView, constant: constant) 45 | self.trailingConstraint(subView: subView, constant: constant) 46 | self.topConstraint(subView: subView, constant: constant) 47 | self.bottomConstraint(subView: subView, constant: constant) 48 | } 49 | 50 | func sizeConstraint(subView: UIView, constant: CGFloat = 0) { 51 | self.widthConstraint(subView: subView, constant: constant) 52 | self.heightConstraint(subView: subView, constant: constant) 53 | } 54 | 55 | func sizeConstraint(constant: CGFloat = 0) { 56 | self.widthConstraint(constant: constant) 57 | self.heightConstraint(constant: constant) 58 | } 59 | 60 | @discardableResult 61 | func leadingConstraint(subView: UIView, constant: CGFloat = 0, multiplier: CGFloat = 1, relatedBy: NSLayoutConstraint.Relation = .equal) -> NSLayoutConstraint { 62 | let constraint = NSLayoutConstraint(item: self, attribute: .leading, relatedBy: relatedBy, toItem: subView, attribute: .leading, multiplier: multiplier, constant: constant) 63 | self.addConstraint(constraint) 64 | return constraint 65 | } 66 | 67 | @discardableResult 68 | func trailingConstraint(subView: UIView, constant: CGFloat = 0, multiplier: CGFloat = 1, relatedBy: NSLayoutConstraint.Relation = .equal) -> NSLayoutConstraint { 69 | let constraint = NSLayoutConstraint(item: self, attribute: .trailing, relatedBy: relatedBy, toItem: subView, attribute: .trailing, multiplier: multiplier, constant: constant) 70 | self.addConstraint(constraint) 71 | return constraint 72 | } 73 | 74 | @discardableResult 75 | func topConstraint(subView: UIView, constant: CGFloat = 0, multiplier: CGFloat = 1, relatedBy: NSLayoutConstraint.Relation = .equal) -> NSLayoutConstraint { 76 | let constraint = NSLayoutConstraint(item: self, attribute: .top, relatedBy: relatedBy, toItem: subView, attribute: .top, multiplier: multiplier, constant: constant) 77 | self.addConstraint(constraint) 78 | return constraint 79 | } 80 | 81 | @discardableResult 82 | func bottomConstraint(subView: UIView, constant: CGFloat = 0, multiplier: CGFloat = 1, relatedBy: NSLayoutConstraint.Relation = .equal) -> NSLayoutConstraint { 83 | let constraint = NSLayoutConstraint(item: self, attribute: .bottom, relatedBy: relatedBy, toItem: subView, attribute: .bottom, multiplier: multiplier, constant: constant) 84 | self.addConstraint(constraint) 85 | return constraint 86 | } 87 | 88 | @discardableResult 89 | func centerXConstraint(subView: UIView, constant: CGFloat = 0, multiplier: CGFloat = 1, relatedBy: NSLayoutConstraint.Relation = .equal) -> NSLayoutConstraint { 90 | let constraint = NSLayoutConstraint(item: self, attribute: .centerX, relatedBy: relatedBy, toItem: subView, attribute: .centerX, multiplier: multiplier, constant: constant) 91 | self.addConstraint(constraint) 92 | return constraint 93 | } 94 | 95 | @discardableResult 96 | func centerYConstraint(subView: UIView, constant: CGFloat = 0, multiplier: CGFloat = 1, relatedBy: NSLayoutConstraint.Relation = .equal) -> NSLayoutConstraint { 97 | let constraint = NSLayoutConstraint(item: self, attribute: .centerY, relatedBy: relatedBy, toItem: subView, attribute: .centerY, multiplier: multiplier, constant: constant) 98 | self.addConstraint(constraint) 99 | return constraint 100 | } 101 | 102 | @discardableResult 103 | func leadingConstraint(item: UIView, subView: UIView, constant: CGFloat = 0, multiplier: CGFloat = 1, relatedBy: NSLayoutConstraint.Relation = .equal) -> NSLayoutConstraint { 104 | let constraint = NSLayoutConstraint(item: item, attribute: .leading, relatedBy: relatedBy, toItem: subView, attribute: .leading, multiplier: multiplier, constant: constant) 105 | self.addConstraint(constraint) 106 | return constraint 107 | } 108 | 109 | @discardableResult 110 | func trailingConstraint(item: UIView, subView: UIView, constant: CGFloat = 0, multiplier: CGFloat = 1, relatedBy: NSLayoutConstraint.Relation = .equal) -> NSLayoutConstraint { 111 | let constraint = NSLayoutConstraint(item: item, attribute: .trailing, relatedBy: relatedBy, toItem: subView, attribute: .trailing, multiplier: multiplier, constant: constant) 112 | self.addConstraint(constraint) 113 | return constraint 114 | } 115 | 116 | @discardableResult 117 | func topConstraint(item: UIView, subView: UIView, constant: CGFloat = 0, multiplier: CGFloat = 1, relatedBy: NSLayoutConstraint.Relation = .equal) -> NSLayoutConstraint { 118 | let constraint = NSLayoutConstraint(item: item, attribute: .top, relatedBy: relatedBy, toItem: subView, attribute: .top, multiplier: multiplier, constant: constant) 119 | self.addConstraint(constraint) 120 | return constraint 121 | } 122 | 123 | @discardableResult 124 | func bottomConstraint(item: UIView, subView: UIView, constant: CGFloat = 0, multiplier: CGFloat = 1, relatedBy: NSLayoutConstraint.Relation = .equal) -> NSLayoutConstraint { 125 | let constraint = NSLayoutConstraint(item: item, attribute: .bottom, relatedBy: relatedBy, toItem: subView, attribute: .bottom, multiplier: multiplier, constant: constant) 126 | self.addConstraint(constraint) 127 | return constraint 128 | } 129 | 130 | @discardableResult 131 | func centerXConstraint(item: UIView, subView: UIView, constant: CGFloat = 0, multiplier: CGFloat = 1, relatedBy: NSLayoutConstraint.Relation = .equal) -> NSLayoutConstraint { 132 | let constraint = NSLayoutConstraint(item: item, attribute: .centerX, relatedBy: relatedBy, toItem: subView, attribute: .centerX, multiplier: multiplier, constant: constant) 133 | self.addConstraint(constraint) 134 | return constraint 135 | } 136 | 137 | @discardableResult 138 | func centerYConstraint(item: UIView, subView: UIView, constant: CGFloat = 0, multiplier: CGFloat = 1, relatedBy: NSLayoutConstraint.Relation = .equal) -> NSLayoutConstraint { 139 | let constraint = NSLayoutConstraint(item: item, attribute: .centerY, relatedBy: relatedBy, toItem: subView, attribute: .centerY, multiplier: multiplier, constant: constant) 140 | self.addConstraint(constraint) 141 | return constraint 142 | } 143 | 144 | @discardableResult 145 | func widthConstraint(item: UIView, subView: UIView, constant: CGFloat = 0, multiplier: CGFloat = 1, relatedBy: NSLayoutConstraint.Relation = .equal) -> NSLayoutConstraint { 146 | let constraint = NSLayoutConstraint(item: item, attribute: .width, relatedBy: relatedBy, toItem: subView, attribute: .width, multiplier: multiplier, constant: constant) 147 | self.addConstraint(constraint) 148 | return constraint 149 | } 150 | 151 | @discardableResult 152 | func heightConstraint(item: UIView, subView: UIView, constant: CGFloat = 0, multiplier: CGFloat = 1, relatedBy: NSLayoutConstraint.Relation = .equal) -> NSLayoutConstraint { 153 | let constraint = NSLayoutConstraint(item: item, attribute: .height, relatedBy: relatedBy, toItem: subView, attribute: .height, multiplier: multiplier, constant: constant) 154 | self.addConstraint(constraint) 155 | return constraint 156 | } 157 | 158 | @discardableResult 159 | func widthConstraint(subView: UIView, constant: CGFloat = 0, multiplier: CGFloat = 1, relatedBy: NSLayoutConstraint.Relation = .equal) -> NSLayoutConstraint { 160 | let constraint = NSLayoutConstraint(item: self, attribute: .width, relatedBy: relatedBy, toItem: subView, attribute: .width, multiplier: multiplier, constant: constant) 161 | self.addConstraint(constraint) 162 | return constraint 163 | } 164 | 165 | @discardableResult 166 | func heightConstraint(subView: UIView, constant: CGFloat = 0, multiplier: CGFloat = 1, relatedBy: NSLayoutConstraint.Relation = .equal) -> NSLayoutConstraint { 167 | let constraint = NSLayoutConstraint(item: self, attribute: .height, relatedBy: relatedBy, toItem: subView, attribute: .height, multiplier: multiplier, constant: constant) 168 | self.addConstraint(constraint) 169 | return constraint 170 | } 171 | 172 | @discardableResult 173 | func widthConstraint(constant: CGFloat = 0, multiplier: CGFloat = 1, relatedBy: NSLayoutConstraint.Relation = .equal) -> NSLayoutConstraint { 174 | let constraint = NSLayoutConstraint(item: self, attribute: .width, relatedBy: relatedBy, toItem: nil, attribute: .width, multiplier: multiplier, constant: constant) 175 | self.addConstraint(constraint) 176 | return constraint 177 | } 178 | 179 | @discardableResult 180 | func heightConstraint(constant: CGFloat = 0, multiplier: CGFloat = 1, relatedBy: NSLayoutConstraint.Relation = .equal) -> NSLayoutConstraint { 181 | let constraint = NSLayoutConstraint(item: self, attribute: .height, relatedBy: relatedBy, toItem: nil, attribute: .height, multiplier: multiplier, constant: constant) 182 | self.addConstraint(constraint) 183 | return constraint 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /Example/Pods/CropPickerView/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018 pikachu987 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 | -------------------------------------------------------------------------------- /Example/Pods/CropPickerView/README.md: -------------------------------------------------------------------------------- 1 | # CropPickerView 2 | 3 | [![CI Status](https://img.shields.io/travis/pikachu987/CropPickerView.svg?style=flat)](https://travis-ci.org/pikachu987/CropPickerView) 4 | [![Version](https://img.shields.io/cocoapods/v/CropPickerView.svg?style=flat)](https://cocoapods.org/pods/CropPickerView) 5 | [![License](https://img.shields.io/cocoapods/l/CropPickerView.svg?style=flat)](https://cocoapods.org/pods/CropPickerView) 6 | [![Platform](https://img.shields.io/cocoapods/p/CropPickerView.svg?style=flat)](https://cocoapods.org/pods/CropPickerView) 7 | ![](https://img.shields.io/badge/Supported-iOS9%20%7C%20OSX%2010.9-4BC51D.svg?style=flat-square) 8 | ![](https://img.shields.io/badge/Swift-5.0-orange.svg?style=flat) 9 | 10 | ## Introduce 11 | 12 | The Corner and Side buttons allow you to modify the position of the crop and UIScrollView to zoom the image. If the image is larger than the area of the UIScrollView, the image can be scrolled up and down, left and right, and if the image is smaller than the area of the UIScrollView, the image is always centered. 13 | 14 | ### [CropPickerController](https://github.com/pikachu987/CropPickerController) 15 | 16 | If you want to see the CropPickerViewController that is created with CropView, see [CropPickerController](https://github.com/pikachu987/CropPickerController) 17 | 18 |
19 | 20 | ### CropPickerView 21 | 22 | |-|-|-| 23 | |---|---|---| 24 | |||| 25 | 26 | |-|-| 27 | |---|---| 28 | ||| 29 | 30 | ## Requirements 31 | 32 | `CropPickerView` written in Swift 5.0. Compatible with iOS 8.0+ 33 | 34 | ## Installation 35 | 36 | CropPickerView is available through [CocoaPods](https://cocoapods.org). To install 37 | it, simply add the following line to your Podfile: 38 | 39 | ```ruby 40 | pod 'CropPickerView' 41 | ``` 42 | 43 | ## Usage 44 | 45 | 46 | ### Xib or Storyboard file 47 | 48 | setting 49 | 50 | ![image](./img/1.png) 51 | 52 | ![image](./img/2.png) 53 | 54 | done! 55 | 56 |


57 | 58 | ### Code editor 59 | 60 | ```swift 61 | import CropPickerView 62 | ``` 63 | 64 | ```swift 65 | let cropPickerView = CropPickerView() 66 | self.view.addSubview(cropPickerView) 67 | ``` 68 | 69 | done! 70 | 71 |


72 | 73 | 74 | 75 | ### Property 76 | 77 | image 78 | 79 | ```swift 80 | 81 | cropPickerView.image = image 82 | cropPickerView.image(image, crop: CGRect(x: 50, y: 30, width: 100, height: 80), isRealCropRect: false) 83 | cropPickerView.image(image, crop: CGRect(x: 50, y: 30, width: 100, height: 80), isRealCropRect: true) 84 | cropPickerView.image(image, isMin: false, crop: CGRect(x: 50, y: 30, width: 100, height: 80), isRealCropRect: true) 85 | cropPickerView.image(image, isMin: false) 86 | 87 | ``` 88 | 89 | color 90 | 91 | ```swift 92 | 93 | cropPickerView.cropLineColor = UIColor.gray 94 | cropPickerView.scrollBackgroundColor = UIColor.gray 95 | cropPickerView.imageBackgroundColor = UIColor.gray 96 | cropPickerView.dimBackgroundColor = UIColor(white: 0, alpha: 0.1) 97 | 98 | ``` 99 | 100 | zoom 101 | 102 | ```swift 103 | 104 | cropPickerView.scrollMinimumZoomScale = 1 105 | cropPickerView.scrollMaximumZoomScale = 2 106 | 107 | ``` 108 | 109 | radius 110 | 111 | ```swift 112 | 113 | cropPickerView.radius = 50 114 | 115 | ``` 116 | 117 | cropSize 118 | 119 | ```swift 120 | 121 | cropPickerView.cropMinSize = 200 122 | 123 | ``` 124 | 125 |

126 | 127 | ### Method 128 | 129 | crop 130 | 131 | ```swift 132 | 133 | cropPickerView.crop { (result) in 134 | if let error = (result.error as NSError?) { 135 | let alertController = UIAlertController(title: "Error", message: error.domain, preferredStyle: .alert) 136 | alertController.addAction(UIAlertAction(title: "Ok", style: .cancel, handler: nil)) 137 | self.present(alertController, animated: true, completion: nil) 138 | return 139 | } 140 | self.imageView.image = result.image 141 | } 142 | 143 | ``` 144 | 145 |

146 | 147 | ### Delegate 148 | 149 | ```swift 150 | 151 | class ViewController: UIViewController{ 152 | override func viewDidLoad() { 153 | super.viewDidLoad() 154 | 155 | let cropPickerView = CropPickerView() 156 | cropPickerView.delegate = self 157 | } 158 | } 159 | 160 | // MARK: CropPickerViewDelegate 161 | extension ViewController: CropPickerViewDelegate { 162 | func cropPickerView(_ cropPickerView: CropPickerView, result: CropResult) { 163 | 164 | } 165 | 166 | func cropPickerView(_ cropPickerView: CropPickerView, didChange frame: CGRect) { 167 | print("frame: \(frame)") 168 | } 169 | } 170 | 171 | ``` 172 | 173 | 174 | ## Author 175 | 176 | pikachu987, pikachu77769@gmail.com 177 | 178 | ## License 179 | 180 | CropPickerView is available under the MIT license. See the LICENSE file for more info. 181 | -------------------------------------------------------------------------------- /Example/Pods/Local Podspecs/CropPickerController.podspec.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "CropPickerController", 3 | "version": "0.1.4", 4 | "summary": "There is a single image picker controller for cropping and a multi image picker controller for selecting various images.", 5 | "description": "There is a single image picker controller for cropping and a multi image picker controller for selecting various images. You can select an album and it will be updated automatically when you edit the album.", 6 | "homepage": "https://github.com/pikachu987/CropPickerController", 7 | "license": { 8 | "type": "MIT", 9 | "file": "LICENSE" 10 | }, 11 | "authors": { 12 | "pikachu987": "pikachu77769@gmail.com" 13 | }, 14 | "source": { 15 | "git": "https://github.com/pikachu987/CropPickerController.git", 16 | "tag": "0.1.4" 17 | }, 18 | "platforms": { 19 | "ios": "9.0" 20 | }, 21 | "swift_versions": "5.0", 22 | "source_files": "CropPickerController/Classes/**/*", 23 | "dependencies": { 24 | "CropPickerView": [ 25 | "0.2.7" 26 | ] 27 | }, 28 | "swift_version": "5.0" 29 | } 30 | -------------------------------------------------------------------------------- /Example/Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - CropPickerController (0.1.4): 3 | - CropPickerView (= 0.2.7) 4 | - CropPickerView (0.2.7) 5 | 6 | DEPENDENCIES: 7 | - CropPickerController (from `../`) 8 | 9 | SPEC REPOS: 10 | trunk: 11 | - CropPickerView 12 | 13 | EXTERNAL SOURCES: 14 | CropPickerController: 15 | :path: "../" 16 | 17 | SPEC CHECKSUMS: 18 | CropPickerController: 6f1d936ec911207d452b436518460cf3198f5095 19 | CropPickerView: 22104910c3daeb7d9da9018dd10831736e20df3a 20 | 21 | PODFILE CHECKSUM: 9bf33656ba265ea726d5aec83a61aa09c91c0e6d 22 | 23 | COCOAPODS: 1.10.1 24 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/CropPickerController/CropPickerController-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | $(MARKETING_VERSION) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/CropPickerController/CropPickerController-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_CropPickerController : NSObject 3 | @end 4 | @implementation PodsDummy_CropPickerController 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/CropPickerController/CropPickerController-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/CropPickerController/CropPickerController-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double CropPickerControllerVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char CropPickerControllerVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/CropPickerController/CropPickerController.debug.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 2 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/CropPickerController 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CropPickerView" 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 6 | PODS_BUILD_DIR = ${BUILD_DIR} 7 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 8 | PODS_ROOT = ${SRCROOT} 9 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../.. 10 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 11 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 12 | SKIP_INSTALL = YES 13 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 14 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/CropPickerController/CropPickerController.modulemap: -------------------------------------------------------------------------------- 1 | framework module CropPickerController { 2 | umbrella header "CropPickerController-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/CropPickerController/CropPickerController.release.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 2 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/CropPickerController 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CropPickerView" 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 6 | PODS_BUILD_DIR = ${BUILD_DIR} 7 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 8 | PODS_ROOT = ${SRCROOT} 9 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../.. 10 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 11 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 12 | SKIP_INSTALL = YES 13 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 14 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/CropPickerController/CropPickerController.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/CropPickerController 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CropPickerView" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 5 | PODS_BUILD_DIR = ${BUILD_DIR} 6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_ROOT = ${SRCROOT} 8 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../.. 9 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 10 | SKIP_INSTALL = YES 11 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/CropPickerController/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 0.1.3 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/CropPickerView/CropPickerView-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 0.2.7 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/CropPickerView/CropPickerView-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_CropPickerView : NSObject 3 | @end 4 | @implementation PodsDummy_CropPickerView 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/CropPickerView/CropPickerView-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/CropPickerView/CropPickerView-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double CropPickerViewVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char CropPickerViewVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/CropPickerView/CropPickerView.debug.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 2 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/CropPickerView 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 5 | PODS_BUILD_DIR = ${BUILD_DIR} 6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_ROOT = ${SRCROOT} 8 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/CropPickerView 9 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 10 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 11 | SKIP_INSTALL = YES 12 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 13 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/CropPickerView/CropPickerView.modulemap: -------------------------------------------------------------------------------- 1 | framework module CropPickerView { 2 | umbrella header "CropPickerView-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/CropPickerView/CropPickerView.release.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 2 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/CropPickerView 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 5 | PODS_BUILD_DIR = ${BUILD_DIR} 6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_ROOT = ${SRCROOT} 8 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/CropPickerView 9 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 10 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 11 | SKIP_INSTALL = YES 12 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 13 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/CropPickerView/CropPickerView.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/CropPickerView 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 4 | PODS_BUILD_DIR = ${BUILD_DIR} 5 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 6 | PODS_ROOT = ${SRCROOT} 7 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/CropPickerView 8 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 9 | SKIP_INSTALL = YES 10 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/CropPickerView/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 0.1.1 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-CropPickerController_Example/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-CropPickerController_Example/Pods-CropPickerController_Example-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-CropPickerController_Example/Pods-CropPickerController_Example-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## CropPickerController 5 | 6 | Copyright (c) 2018 pikachu987 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in 16 | all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | THE SOFTWARE. 25 | 26 | 27 | ## CropPickerView 28 | 29 | Copyright (c) 2018 pikachu987 30 | 31 | Permission is hereby granted, free of charge, to any person obtaining a copy 32 | of this software and associated documentation files (the "Software"), to deal 33 | in the Software without restriction, including without limitation the rights 34 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 35 | copies of the Software, and to permit persons to whom the Software is 36 | furnished to do so, subject to the following conditions: 37 | 38 | The above copyright notice and this permission notice shall be included in 39 | all copies or substantial portions of the Software. 40 | 41 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 42 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 43 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 44 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 45 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 46 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 47 | THE SOFTWARE. 48 | 49 | Generated by CocoaPods - https://cocoapods.org 50 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-CropPickerController_Example/Pods-CropPickerController_Example-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | Copyright (c) 2018 pikachu987 <pikachu77769@gmail.com> 18 | 19 | Permission is hereby granted, free of charge, to any person obtaining a copy 20 | of this software and associated documentation files (the "Software"), to deal 21 | in the Software without restriction, including without limitation the rights 22 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 23 | copies of the Software, and to permit persons to whom the Software is 24 | furnished to do so, subject to the following conditions: 25 | 26 | The above copyright notice and this permission notice shall be included in 27 | all copies or substantial portions of the Software. 28 | 29 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 30 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 31 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 32 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 33 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 34 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 35 | THE SOFTWARE. 36 | 37 | License 38 | MIT 39 | Title 40 | CropPickerController 41 | Type 42 | PSGroupSpecifier 43 | 44 | 45 | FooterText 46 | Copyright (c) 2018 pikachu987 <pikachu77769@gmail.com> 47 | 48 | Permission is hereby granted, free of charge, to any person obtaining a copy 49 | of this software and associated documentation files (the "Software"), to deal 50 | in the Software without restriction, including without limitation the rights 51 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 52 | copies of the Software, and to permit persons to whom the Software is 53 | furnished to do so, subject to the following conditions: 54 | 55 | The above copyright notice and this permission notice shall be included in 56 | all copies or substantial portions of the Software. 57 | 58 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 59 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 60 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 61 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 62 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 63 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 64 | THE SOFTWARE. 65 | 66 | License 67 | MIT 68 | Title 69 | CropPickerView 70 | Type 71 | PSGroupSpecifier 72 | 73 | 74 | FooterText 75 | Generated by CocoaPods - https://cocoapods.org 76 | Title 77 | 78 | Type 79 | PSGroupSpecifier 80 | 81 | 82 | StringsTable 83 | Acknowledgements 84 | Title 85 | Acknowledgements 86 | 87 | 88 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-CropPickerController_Example/Pods-CropPickerController_Example-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_CropPickerController_Example : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_CropPickerController_Example 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-CropPickerController_Example/Pods-CropPickerController_Example-frameworks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | set -u 4 | set -o pipefail 5 | 6 | function on_error { 7 | echo "$(realpath -mq "${0}"):$1: error: Unexpected failure" 8 | } 9 | trap 'on_error $LINENO' ERR 10 | 11 | if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then 12 | # If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy 13 | # frameworks to, so exit 0 (signalling the script phase was successful). 14 | exit 0 15 | fi 16 | 17 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 18 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 19 | 20 | COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}" 21 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" 22 | BCSYMBOLMAP_DIR="BCSymbolMaps" 23 | 24 | 25 | # This protects against multiple targets copying the same framework dependency at the same time. The solution 26 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html 27 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") 28 | 29 | # Copies and strips a vendored framework 30 | install_framework() 31 | { 32 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then 33 | local source="${BUILT_PRODUCTS_DIR}/$1" 34 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then 35 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" 36 | elif [ -r "$1" ]; then 37 | local source="$1" 38 | fi 39 | 40 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 41 | 42 | if [ -L "${source}" ]; then 43 | echo "Symlinked..." 44 | source="$(readlink "${source}")" 45 | fi 46 | 47 | if [ -d "${source}/${BCSYMBOLMAP_DIR}" ]; then 48 | # Locate and install any .bcsymbolmaps if present, and remove them from the .framework before the framework is copied 49 | find "${source}/${BCSYMBOLMAP_DIR}" -name "*.bcsymbolmap"|while read f; do 50 | echo "Installing $f" 51 | install_bcsymbolmap "$f" "$destination" 52 | rm "$f" 53 | done 54 | rmdir "${source}/${BCSYMBOLMAP_DIR}" 55 | fi 56 | 57 | # Use filter instead of exclude so missing patterns don't throw errors. 58 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" 59 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" 60 | 61 | local basename 62 | basename="$(basename -s .framework "$1")" 63 | binary="${destination}/${basename}.framework/${basename}" 64 | 65 | if ! [ -r "$binary" ]; then 66 | binary="${destination}/${basename}" 67 | elif [ -L "${binary}" ]; then 68 | echo "Destination binary is symlinked..." 69 | dirname="$(dirname "${binary}")" 70 | binary="${dirname}/$(readlink "${binary}")" 71 | fi 72 | 73 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 74 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then 75 | strip_invalid_archs "$binary" 76 | fi 77 | 78 | # Resign the code if required by the build settings to avoid unstable apps 79 | code_sign_if_enabled "${destination}/$(basename "$1")" 80 | 81 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. 82 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then 83 | local swift_runtime_libs 84 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u) 85 | for lib in $swift_runtime_libs; do 86 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" 87 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" 88 | code_sign_if_enabled "${destination}/${lib}" 89 | done 90 | fi 91 | } 92 | # Copies and strips a vendored dSYM 93 | install_dsym() { 94 | local source="$1" 95 | warn_missing_arch=${2:-true} 96 | if [ -r "$source" ]; then 97 | # Copy the dSYM into the targets temp dir. 98 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\"" 99 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}" 100 | 101 | local basename 102 | basename="$(basename -s .dSYM "$source")" 103 | binary_name="$(ls "$source/Contents/Resources/DWARF")" 104 | binary="${DERIVED_FILES_DIR}/${basename}.dSYM/Contents/Resources/DWARF/${binary_name}" 105 | 106 | # Strip invalid architectures from the dSYM. 107 | if [[ "$(file "$binary")" == *"Mach-O "*"dSYM companion"* ]]; then 108 | strip_invalid_archs "$binary" "$warn_missing_arch" 109 | fi 110 | if [[ $STRIP_BINARY_RETVAL == 0 ]]; then 111 | # Move the stripped file into its final destination. 112 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\"" 113 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.dSYM" "${DWARF_DSYM_FOLDER_PATH}" 114 | else 115 | # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing. 116 | touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.dSYM" 117 | fi 118 | fi 119 | } 120 | 121 | # Used as a return value for each invocation of `strip_invalid_archs` function. 122 | STRIP_BINARY_RETVAL=0 123 | 124 | # Strip invalid architectures 125 | strip_invalid_archs() { 126 | binary="$1" 127 | warn_missing_arch=${2:-true} 128 | # Get architectures for current target binary 129 | binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)" 130 | # Intersect them with the architectures we are building for 131 | intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)" 132 | # If there are no archs supported by this binary then warn the user 133 | if [[ -z "$intersected_archs" ]]; then 134 | if [[ "$warn_missing_arch" == "true" ]]; then 135 | echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)." 136 | fi 137 | STRIP_BINARY_RETVAL=1 138 | return 139 | fi 140 | stripped="" 141 | for arch in $binary_archs; do 142 | if ! [[ "${ARCHS}" == *"$arch"* ]]; then 143 | # Strip non-valid architectures in-place 144 | lipo -remove "$arch" -output "$binary" "$binary" 145 | stripped="$stripped $arch" 146 | fi 147 | done 148 | if [[ "$stripped" ]]; then 149 | echo "Stripped $binary of architectures:$stripped" 150 | fi 151 | STRIP_BINARY_RETVAL=0 152 | } 153 | 154 | # Copies the bcsymbolmap files of a vendored framework 155 | install_bcsymbolmap() { 156 | local bcsymbolmap_path="$1" 157 | local destination="${BUILT_PRODUCTS_DIR}" 158 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}"" 159 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}" 160 | } 161 | 162 | # Signs a framework with the provided identity 163 | code_sign_if_enabled() { 164 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then 165 | # Use the current code_sign_identity 166 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" 167 | local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'" 168 | 169 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 170 | code_sign_cmd="$code_sign_cmd &" 171 | fi 172 | echo "$code_sign_cmd" 173 | eval "$code_sign_cmd" 174 | fi 175 | } 176 | 177 | if [[ "$CONFIGURATION" == "Debug" ]]; then 178 | install_framework "${BUILT_PRODUCTS_DIR}/CropPickerController/CropPickerController.framework" 179 | install_framework "${BUILT_PRODUCTS_DIR}/CropPickerView/CropPickerView.framework" 180 | fi 181 | if [[ "$CONFIGURATION" == "Release" ]]; then 182 | install_framework "${BUILT_PRODUCTS_DIR}/CropPickerController/CropPickerController.framework" 183 | install_framework "${BUILT_PRODUCTS_DIR}/CropPickerView/CropPickerView.framework" 184 | fi 185 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 186 | wait 187 | fi 188 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-CropPickerController_Example/Pods-CropPickerController_Example-resources.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | set -u 4 | set -o pipefail 5 | 6 | if [ -z ${UNLOCALIZED_RESOURCES_FOLDER_PATH+x} ]; then 7 | # If UNLOCALIZED_RESOURCES_FOLDER_PATH is not set, then there's nowhere for us to copy 8 | # resources to, so exit 0 (signalling the script phase was successful). 9 | exit 0 10 | fi 11 | 12 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 13 | 14 | RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt 15 | > "$RESOURCES_TO_COPY" 16 | 17 | XCASSET_FILES=() 18 | 19 | # This protects against multiple targets copying the same framework dependency at the same time. The solution 20 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html 21 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") 22 | 23 | case "${TARGETED_DEVICE_FAMILY:-}" in 24 | 1,2) 25 | TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" 26 | ;; 27 | 1) 28 | TARGET_DEVICE_ARGS="--target-device iphone" 29 | ;; 30 | 2) 31 | TARGET_DEVICE_ARGS="--target-device ipad" 32 | ;; 33 | 3) 34 | TARGET_DEVICE_ARGS="--target-device tv" 35 | ;; 36 | 4) 37 | TARGET_DEVICE_ARGS="--target-device watch" 38 | ;; 39 | *) 40 | TARGET_DEVICE_ARGS="--target-device mac" 41 | ;; 42 | esac 43 | 44 | install_resource() 45 | { 46 | if [[ "$1" = /* ]] ; then 47 | RESOURCE_PATH="$1" 48 | else 49 | RESOURCE_PATH="${PODS_ROOT}/$1" 50 | fi 51 | if [[ ! -e "$RESOURCE_PATH" ]] ; then 52 | cat << EOM 53 | error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. 54 | EOM 55 | exit 1 56 | fi 57 | case $RESOURCE_PATH in 58 | *.storyboard) 59 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true 60 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} 61 | ;; 62 | *.xib) 63 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true 64 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} 65 | ;; 66 | *.framework) 67 | echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true 68 | mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 69 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true 70 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 71 | ;; 72 | *.xcdatamodel) 73 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" || true 74 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" 75 | ;; 76 | *.xcdatamodeld) 77 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" || true 78 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" 79 | ;; 80 | *.xcmappingmodel) 81 | echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" || true 82 | xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" 83 | ;; 84 | *.xcassets) 85 | ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH" 86 | XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") 87 | ;; 88 | *) 89 | echo "$RESOURCE_PATH" || true 90 | echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" 91 | ;; 92 | esac 93 | } 94 | 95 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 96 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 97 | if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then 98 | mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 99 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 100 | fi 101 | rm -f "$RESOURCES_TO_COPY" 102 | 103 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "${XCASSET_FILES:-}" ] 104 | then 105 | # Find all other xcassets (this unfortunately includes those of path pods and other targets). 106 | OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) 107 | while read line; do 108 | if [[ $line != "${PODS_ROOT}*" ]]; then 109 | XCASSET_FILES+=("$line") 110 | fi 111 | done <<<"$OTHER_XCASSETS" 112 | 113 | if [ -z ${ASSETCATALOG_COMPILER_APPICON_NAME+x} ]; then 114 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 115 | else 116 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" --app-icon "${ASSETCATALOG_COMPILER_APPICON_NAME}" --output-partial-info-plist "${TARGET_TEMP_DIR}/assetcatalog_generated_info_cocoapods.plist" 117 | fi 118 | fi 119 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-CropPickerController_Example/Pods-CropPickerController_Example-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_CropPickerController_ExampleVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_CropPickerController_ExampleVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-CropPickerController_Example/Pods-CropPickerController_Example.debug.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CropPickerController" "${PODS_CONFIGURATION_BUILD_DIR}/CropPickerView" 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CropPickerController/CropPickerController.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CropPickerView/CropPickerView.framework/Headers" 6 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 7 | OTHER_LDFLAGS = $(inherited) -framework "CropPickerController" -framework "CropPickerView" 8 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 9 | PODS_BUILD_DIR = ${BUILD_DIR} 10 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 11 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 12 | PODS_ROOT = ${SRCROOT}/Pods 13 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 14 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 15 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-CropPickerController_Example/Pods-CropPickerController_Example.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_CropPickerController_Example { 2 | umbrella header "Pods-CropPickerController_Example-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-CropPickerController_Example/Pods-CropPickerController_Example.release.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CropPickerController" "${PODS_CONFIGURATION_BUILD_DIR}/CropPickerView" 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CropPickerController/CropPickerController.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CropPickerView/CropPickerView.framework/Headers" 6 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 7 | OTHER_LDFLAGS = $(inherited) -framework "CropPickerController" -framework "CropPickerView" 8 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 9 | PODS_BUILD_DIR = ${BUILD_DIR} 10 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 11 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 12 | PODS_ROOT = ${SRCROOT}/Pods 13 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 14 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 15 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-CropPickerController_Tests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-CropPickerController_Tests/Pods-CropPickerController_Tests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-CropPickerController_Tests/Pods-CropPickerController_Tests-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | Generated by CocoaPods - https://cocoapods.org 4 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-CropPickerController_Tests/Pods-CropPickerController_Tests-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | Generated by CocoaPods - https://cocoapods.org 18 | Title 19 | 20 | Type 21 | PSGroupSpecifier 22 | 23 | 24 | StringsTable 25 | Acknowledgements 26 | Title 27 | Acknowledgements 28 | 29 | 30 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-CropPickerController_Tests/Pods-CropPickerController_Tests-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_CropPickerController_Tests : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_CropPickerController_Tests 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-CropPickerController_Tests/Pods-CropPickerController_Tests-frameworks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | set -u 4 | set -o pipefail 5 | 6 | if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then 7 | # If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy 8 | # frameworks to, so exit 0 (signalling the script phase was successful). 9 | exit 0 10 | fi 11 | 12 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 13 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 14 | 15 | COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}" 16 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" 17 | 18 | # Used as a return value for each invocation of `strip_invalid_archs` function. 19 | STRIP_BINARY_RETVAL=0 20 | 21 | # This protects against multiple targets copying the same framework dependency at the same time. The solution 22 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html 23 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") 24 | 25 | # Copies and strips a vendored framework 26 | install_framework() 27 | { 28 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then 29 | local source="${BUILT_PRODUCTS_DIR}/$1" 30 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then 31 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" 32 | elif [ -r "$1" ]; then 33 | local source="$1" 34 | fi 35 | 36 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 37 | 38 | if [ -L "${source}" ]; then 39 | echo "Symlinked..." 40 | source="$(readlink "${source}")" 41 | fi 42 | 43 | # Use filter instead of exclude so missing patterns don't throw errors. 44 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" 45 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" 46 | 47 | local basename 48 | basename="$(basename -s .framework "$1")" 49 | binary="${destination}/${basename}.framework/${basename}" 50 | if ! [ -r "$binary" ]; then 51 | binary="${destination}/${basename}" 52 | fi 53 | 54 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 55 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then 56 | strip_invalid_archs "$binary" 57 | fi 58 | 59 | # Resign the code if required by the build settings to avoid unstable apps 60 | code_sign_if_enabled "${destination}/$(basename "$1")" 61 | 62 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. 63 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then 64 | local swift_runtime_libs 65 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) 66 | for lib in $swift_runtime_libs; do 67 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" 68 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" 69 | code_sign_if_enabled "${destination}/${lib}" 70 | done 71 | fi 72 | } 73 | 74 | # Copies and strips a vendored dSYM 75 | install_dsym() { 76 | local source="$1" 77 | if [ -r "$source" ]; then 78 | # Copy the dSYM into a the targets temp dir. 79 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\"" 80 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}" 81 | 82 | local basename 83 | basename="$(basename -s .framework.dSYM "$source")" 84 | binary="${DERIVED_FILES_DIR}/${basename}.framework.dSYM/Contents/Resources/DWARF/${basename}" 85 | 86 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 87 | if [[ "$(file "$binary")" == *"Mach-O dSYM companion"* ]]; then 88 | strip_invalid_archs "$binary" 89 | fi 90 | 91 | if [[ $STRIP_BINARY_RETVAL == 1 ]]; then 92 | # Move the stripped file into its final destination. 93 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\"" 94 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.framework.dSYM" "${DWARF_DSYM_FOLDER_PATH}" 95 | else 96 | # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing. 97 | touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.framework.dSYM" 98 | fi 99 | fi 100 | } 101 | 102 | # Signs a framework with the provided identity 103 | code_sign_if_enabled() { 104 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then 105 | # Use the current code_sign_identitiy 106 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" 107 | local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'" 108 | 109 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 110 | code_sign_cmd="$code_sign_cmd &" 111 | fi 112 | echo "$code_sign_cmd" 113 | eval "$code_sign_cmd" 114 | fi 115 | } 116 | 117 | # Strip invalid architectures 118 | strip_invalid_archs() { 119 | binary="$1" 120 | # Get architectures for current target binary 121 | binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)" 122 | # Intersect them with the architectures we are building for 123 | intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)" 124 | # If there are no archs supported by this binary then warn the user 125 | if [[ -z "$intersected_archs" ]]; then 126 | echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)." 127 | STRIP_BINARY_RETVAL=0 128 | return 129 | fi 130 | stripped="" 131 | for arch in $binary_archs; do 132 | if ! [[ "${ARCHS}" == *"$arch"* ]]; then 133 | # Strip non-valid architectures in-place 134 | lipo -remove "$arch" -output "$binary" "$binary" || exit 1 135 | stripped="$stripped $arch" 136 | fi 137 | done 138 | if [[ "$stripped" ]]; then 139 | echo "Stripped $binary of architectures:$stripped" 140 | fi 141 | STRIP_BINARY_RETVAL=1 142 | } 143 | 144 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 145 | wait 146 | fi 147 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-CropPickerController_Tests/Pods-CropPickerController_Tests-resources.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | set -u 4 | set -o pipefail 5 | 6 | if [ -z ${UNLOCALIZED_RESOURCES_FOLDER_PATH+x} ]; then 7 | # If UNLOCALIZED_RESOURCES_FOLDER_PATH is not set, then there's nowhere for us to copy 8 | # resources to, so exit 0 (signalling the script phase was successful). 9 | exit 0 10 | fi 11 | 12 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 13 | 14 | RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt 15 | > "$RESOURCES_TO_COPY" 16 | 17 | XCASSET_FILES=() 18 | 19 | # This protects against multiple targets copying the same framework dependency at the same time. The solution 20 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html 21 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") 22 | 23 | case "${TARGETED_DEVICE_FAMILY:-}" in 24 | 1,2) 25 | TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" 26 | ;; 27 | 1) 28 | TARGET_DEVICE_ARGS="--target-device iphone" 29 | ;; 30 | 2) 31 | TARGET_DEVICE_ARGS="--target-device ipad" 32 | ;; 33 | 3) 34 | TARGET_DEVICE_ARGS="--target-device tv" 35 | ;; 36 | 4) 37 | TARGET_DEVICE_ARGS="--target-device watch" 38 | ;; 39 | *) 40 | TARGET_DEVICE_ARGS="--target-device mac" 41 | ;; 42 | esac 43 | 44 | install_resource() 45 | { 46 | if [[ "$1" = /* ]] ; then 47 | RESOURCE_PATH="$1" 48 | else 49 | RESOURCE_PATH="${PODS_ROOT}/$1" 50 | fi 51 | if [[ ! -e "$RESOURCE_PATH" ]] ; then 52 | cat << EOM 53 | error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. 54 | EOM 55 | exit 1 56 | fi 57 | case $RESOURCE_PATH in 58 | *.storyboard) 59 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true 60 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} 61 | ;; 62 | *.xib) 63 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true 64 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} 65 | ;; 66 | *.framework) 67 | echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true 68 | mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 69 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true 70 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 71 | ;; 72 | *.xcdatamodel) 73 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" || true 74 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" 75 | ;; 76 | *.xcdatamodeld) 77 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" || true 78 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" 79 | ;; 80 | *.xcmappingmodel) 81 | echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" || true 82 | xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" 83 | ;; 84 | *.xcassets) 85 | ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH" 86 | XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") 87 | ;; 88 | *) 89 | echo "$RESOURCE_PATH" || true 90 | echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" 91 | ;; 92 | esac 93 | } 94 | 95 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 96 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 97 | if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then 98 | mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 99 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 100 | fi 101 | rm -f "$RESOURCES_TO_COPY" 102 | 103 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "${XCASSET_FILES:-}" ] 104 | then 105 | # Find all other xcassets (this unfortunately includes those of path pods and other targets). 106 | OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) 107 | while read line; do 108 | if [[ $line != "${PODS_ROOT}*" ]]; then 109 | XCASSET_FILES+=("$line") 110 | fi 111 | done <<<"$OTHER_XCASSETS" 112 | 113 | if [ -z ${ASSETCATALOG_COMPILER_APPICON_NAME+x} ]; then 114 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 115 | else 116 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" --app-icon "${ASSETCATALOG_COMPILER_APPICON_NAME}" --output-partial-info-plist "${TARGET_TEMP_DIR}/assetcatalog_generated_info_cocoapods.plist" 117 | fi 118 | fi 119 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-CropPickerController_Tests/Pods-CropPickerController_Tests-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_CropPickerController_TestsVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_CropPickerController_TestsVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-CropPickerController_Tests/Pods-CropPickerController_Tests.debug.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CropPickerController" "${PODS_CONFIGURATION_BUILD_DIR}/CropPickerView" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CropPickerController/CropPickerController.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CropPickerView/CropPickerView.framework/Headers" 5 | OTHER_LDFLAGS = $(inherited) -framework "CropPickerController" -framework "CropPickerView" 6 | PODS_BUILD_DIR = ${BUILD_DIR} 7 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 8 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 9 | PODS_ROOT = ${SRCROOT}/Pods 10 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 11 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 12 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-CropPickerController_Tests/Pods-CropPickerController_Tests.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_CropPickerController_Tests { 2 | umbrella header "Pods-CropPickerController_Tests-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-CropPickerController_Tests/Pods-CropPickerController_Tests.release.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CropPickerController" "${PODS_CONFIGURATION_BUILD_DIR}/CropPickerView" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CropPickerController/CropPickerController.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CropPickerView/CropPickerView.framework/Headers" 5 | OTHER_LDFLAGS = $(inherited) -framework "CropPickerController" -framework "CropPickerView" 6 | PODS_BUILD_DIR = ${BUILD_DIR} 7 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 8 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 9 | PODS_ROOT = ${SRCROOT}/Pods 10 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 11 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 12 | -------------------------------------------------------------------------------- /Example/Tests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /Example/Tests/Tests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import CropPickerController 3 | 4 | class Tests: XCTestCase { 5 | 6 | override func setUp() { 7 | super.setUp() 8 | // Put setup code here. This method is called before the invocation of each test method in the class. 9 | } 10 | 11 | override func tearDown() { 12 | // Put teardown code here. This method is called after the invocation of each test method in the class. 13 | super.tearDown() 14 | } 15 | 16 | func testExample() { 17 | // This is an example of a functional test case. 18 | XCTAssert(true, "Pass") 19 | } 20 | 21 | func testPerformanceExample() { 22 | // This is an example of a performance test case. 23 | self.measure() { 24 | // Put the code you want to measure the time of here. 25 | } 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018 pikachu987 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CropPickerController 2 | 3 | [![CI Status](https://img.shields.io/travis/pikachu987/CropPickerController.svg?style=flat)](https://travis-ci.org/pikachu987/CropPickerController) 4 | [![Version](https://img.shields.io/cocoapods/v/CropPickerController.svg?style=flat)](https://cocoapods.org/pods/CropPickerController) 5 | [![License](https://img.shields.io/cocoapods/l/CropPickerController.svg?style=flat)](https://cocoapods.org/pods/CropPickerController) 6 | [![Platform](https://img.shields.io/cocoapods/p/CropPickerController.svg?style=flat)](https://cocoapods.org/pods/CropPickerController) 7 | ![](https://img.shields.io/badge/Supported-iOS9%20%7C%20OSX%2010.9-4BC51D.svg?style=flat-square) 8 | ![](https://img.shields.io/badge/Swift-5.0-orange.svg?style=flat) 9 | 10 | ## Introduce 11 | 12 | There is a single image picker controller for cropping and a multi image picker controller for selecting various images. You can select an album and it will be updated automatically when you edit the album. 13 | 14 | ### [CropPickerView](https://github.com/pikachu987/CropPickerView) 15 | 16 | If you want to customize your UIViewController or just display a Crop View, see [CropPickerView](https://github.com/pikachu987/CropPickerView) 17 | 18 |
19 | 20 | ### CropPickerController 21 | 22 | |Single|Complex| 23 | |---|---| 24 | ||| 25 | 26 | 27 | |Camera|Progress| 28 | |---|---| 29 | ||| 30 | 31 | 32 | ## Requirements 33 | 34 | `CropPickerController` written in Swift 5.0. Compatible with iOS 9.0+ 35 | 36 | ## Installation 37 | 38 | CropPickerController is available through [CocoaPods](https://cocoapods.org). To install 39 | it, simply add the following line to your Podfile: 40 | 41 | ```ruby 42 | pod 'CropPickerController' 43 | ``` 44 | 45 | ### Usage 46 | 47 | ![image](./img/info.png) 48 | 49 | ```swift 50 | import CropPickerController 51 | ``` 52 | 53 | ```swift 54 | let cropPickerController = CropPickerController(.single) 55 | // let cropPickerController = CropPickerController(.complex) 56 | cropPickerController.delegate = self 57 | let navigationController = UINavigationController(rootViewController: cropPickerController) 58 | present(navigationController, animated: true, completion: nil) 59 | ``` 60 | 61 | ### Init 62 | 63 | ```Swift 64 | 65 | CropPickerController(.single) 66 | CropPickerController(.single, isCamera: true) 67 | CropPickerController(.complex) 68 | CropPickerController(.complex, isCamera: false) 69 | 70 | ``` 71 | 72 | 73 | ### Property 74 | 75 | BarButtonItem 76 | 77 | ```swift 78 | 79 | cropPickerController.leftBarButtonItem = UIBarButtonItem(title: "Back", style: .plain, target: cropPickerController, action: #selector(cropPickerController.backTap(_:))) 80 | cropPickerController.rightBarButtonItem = UIBarButtonItem(title: "Crop", style: .done, target: cropPickerController, action: #selector(cropPickerController.cropTap(_:))) 81 | 82 | ``` 83 | 84 | color 85 | 86 | ```swift 87 | 88 | cropPickerController.leftBarButtonItem?.tintColor = .black 89 | cropPickerController.rightBarButtonItem?.tintColor = .black 90 | cropPickerController.titleButton.setTitleColor(.black, for: .normal) 91 | 92 | cropPickerController.cameraTintColor = .red 93 | cropPickerController.cameraBackgroundColor = UIColor(white: 0.2, alpha: 1) 94 | 95 | cropPickerController.pictureDimColor = UIColor(red: 242/255, green: 121/255, blue: 141/255, alpha: 0.5) 96 | 97 | cropPickerController.selectBoxTintColor = .black 98 | cropPickerController.selectBoxLayerColor = .gray 99 | cropPickerController.selectBoxBackgroundColor = .gray 100 | 101 | cropPickerController.progressTextColor = .black 102 | cropPickerController.progressColor = .red 103 | cropPickerController.progressTintColor = .blue 104 | cropPickerController.progressBackgroundColor = .white 105 | 106 | cropPickerController.cropLineColor = .blue 107 | cropPickerController.imageBackgroundColor = .white 108 | cropPickerController.scrollBackgroundColor = .white 109 | cropPickerController.cropDimBackgroundColor = UIColor(white: 0, alpha: 0.9) 110 | 111 | ``` 112 | 113 | zoom 114 | 115 | ```swift 116 | 117 | cropPickerController.scrollMinimumZoomScale = 0.1 118 | cropPickerController.scrollMaximumZoomScale = 12 119 | 120 | ``` 121 | 122 | text 123 | 124 | ```Swift 125 | 126 | cropPickerController.permissionGalleryDeniedTitle = "Denied" 127 | cropPickerController.permissionGalleryDeniedMessage = "Denied Gallery" 128 | cropPickerController.permissionCameraDeniedTitle = "Denied" 129 | cropPickerController.permissionCameraDeniedMessage = "Denied Camera" 130 | cropPickerController.permissionActionMoveTitle = "Move~" 131 | cropPickerController.permissionActionCancelTitle = "Cancel!" 132 | 133 | ``` 134 | 135 | ### Selector 136 | 137 | Back and Crop 138 | 139 | ```swift 140 | 141 | #selector(cropPickerController.backTap(_:)) 142 | #selector(cropPickerController.cropTap(_:)) 143 | 144 | ``` 145 | 146 | ### Delegate 147 | 148 | ```swift 149 | 150 | class ViewController: UIViewController{ 151 | override func viewDidLoad() { 152 | super.viewDidLoad() 153 | 154 | let cropPickerController = CropPickerController(.single) 155 | cropPickerController.delegate = self 156 | } 157 | } 158 | 159 | // MARK: CropPickerDelegate 160 | extension ViewController: CropPickerDelegate { 161 | func cropPickerBackAction(_ cropPickerController: CropPickerController) { 162 | 163 | } 164 | func cropPickerCompleteAction(_ cropPickerController: CropPickerController, images: [UIImage]?, error: Error?) { 165 | 166 | } 167 | } 168 | 169 | ``` 170 | 171 | ## Author 172 | 173 | pikachu987, pikachu77769@gmail.com 174 | 175 | ## License 176 | 177 | CropPickerController is available under the MIT license. See the LICENSE file for more info. 178 | -------------------------------------------------------------------------------- /_Pods.xcodeproj: -------------------------------------------------------------------------------- 1 | Example/Pods/Pods.xcodeproj -------------------------------------------------------------------------------- /img/1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pikachu987/CropPickerController/865f98729c15c8ca2d53acfe1b0ba96160b285c6/img/1.gif -------------------------------------------------------------------------------- /img/2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pikachu987/CropPickerController/865f98729c15c8ca2d53acfe1b0ba96160b285c6/img/2.gif -------------------------------------------------------------------------------- /img/3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pikachu987/CropPickerController/865f98729c15c8ca2d53acfe1b0ba96160b285c6/img/3.gif -------------------------------------------------------------------------------- /img/4.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pikachu987/CropPickerController/865f98729c15c8ca2d53acfe1b0ba96160b285c6/img/4.gif -------------------------------------------------------------------------------- /img/info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pikachu987/CropPickerController/865f98729c15c8ca2d53acfe1b0ba96160b285c6/img/info.png --------------------------------------------------------------------------------