├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── Classes ├── SidebarCollectionView │ ├── SidebarCollectionView.swift │ ├── SidebarReusableView.swift │ └── SidebarViewCell.swift ├── SidebarView │ └── SidebarView.swift ├── Supporting-Files │ ├── Constants.swift │ ├── Extensions.swift │ └── Protocols+Declarations.swift └── View-Models │ └── ViewModels.swift ├── Example ├── ModularSidebarView.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── xcshareddata │ │ └── xcschemes │ │ └── ModularSidebarView-Example.xcscheme ├── ModularSidebarView.xcworkspace │ └── contents.xcworkspacedata ├── ModularSidebarView │ ├── AppDelegate.swift │ ├── Base.lproj │ │ ├── LaunchScreen.xib │ │ └── Main.storyboard │ ├── DetailViewController.swift │ ├── Images.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Info.plist │ ├── TestController.swift │ └── ViewController.swift ├── Podfile ├── Podfile.lock ├── Pods │ ├── Local Podspecs │ │ └── ModularSidebarView.podspec.json │ ├── Manifest.lock │ ├── Pods.xcodeproj │ │ └── project.pbxproj │ └── Target Support Files │ │ ├── ModularSidebarView │ │ ├── Info.plist │ │ ├── ModularSidebarView-dummy.m │ │ ├── ModularSidebarView-prefix.pch │ │ ├── ModularSidebarView-umbrella.h │ │ ├── ModularSidebarView.modulemap │ │ └── ModularSidebarView.xcconfig │ │ ├── Pods-ModularSidebarView_Example │ │ ├── Info.plist │ │ ├── Pods-ModularSidebarView_Example-acknowledgements.markdown │ │ ├── Pods-ModularSidebarView_Example-acknowledgements.plist │ │ ├── Pods-ModularSidebarView_Example-dummy.m │ │ ├── Pods-ModularSidebarView_Example-frameworks.sh │ │ ├── Pods-ModularSidebarView_Example-resources.sh │ │ ├── Pods-ModularSidebarView_Example-umbrella.h │ │ ├── Pods-ModularSidebarView_Example.debug.xcconfig │ │ ├── Pods-ModularSidebarView_Example.modulemap │ │ └── Pods-ModularSidebarView_Example.release.xcconfig │ │ └── Pods-ModularSidebarView_Tests │ │ ├── Info.plist │ │ ├── Pods-ModularSidebarView_Tests-acknowledgements.markdown │ │ ├── Pods-ModularSidebarView_Tests-acknowledgements.plist │ │ ├── Pods-ModularSidebarView_Tests-dummy.m │ │ ├── Pods-ModularSidebarView_Tests-frameworks.sh │ │ ├── Pods-ModularSidebarView_Tests-resources.sh │ │ ├── Pods-ModularSidebarView_Tests-umbrella.h │ │ ├── Pods-ModularSidebarView_Tests.debug.xcconfig │ │ ├── Pods-ModularSidebarView_Tests.modulemap │ │ └── Pods-ModularSidebarView_Tests.release.xcconfig └── Tests │ ├── Info.plist │ └── Tests.swift ├── Github Images ├── ModularSidebarView-home-screen_iphonexspacegrey_portrait.png └── ModularSidebarView-sidebarview-screen_iphonexspacegrey_portrait.png ├── LICENSE ├── ModularSidebarView.podspec ├── ModularSidebarView ├── Assets │ └── .gitkeep └── Classes │ └── .gitkeep ├── README.md └── _Pods.xcodeproj /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | 3 | # where the python virtualenv is for the docs 4 | docs/docs 5 | docs/build 6 | 7 | 8 | # Xcode 9 | build/ 10 | ======= 11 | # Xcode 12 | # 13 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 14 | 15 | .DS_Store 16 | 17 | ## User settings 18 | xcuserdata/ 19 | 20 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) 21 | *.xcscmblueprint 22 | *.xccheckout 23 | 24 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) 25 | build/ 26 | DerivedData/ 27 | *.moved-aside 28 | *.pbxuser 29 | !default.pbxuser 30 | *.mode1v3 31 | !default.mode1v3 32 | *.mode2v3 33 | !default.mode2v3 34 | *.perspectivev3 35 | !default.perspectivev3 36 | xcuserdata/ 37 | *.xccheckout 38 | profile 39 | *.moved-aside 40 | DerivedData 41 | *.hmap 42 | *.ipa 43 | 44 | # Bundler 45 | .bundle 46 | 47 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 48 | # Carthage/Checkouts 49 | 50 | Carthage/Build 51 | 52 | # We recommend against adding the Pods directory to your .gitignore. However 53 | # you should judge for yourself, the pros and cons are mentioned at: 54 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 55 | # 56 | # Note: if you ignore the Pods directory, make sure to uncomment 57 | # `pod install` in .travis.yml 58 | # 59 | # Pods/ 60 | ======= 61 | 62 | ## Obj-C/Swift specific 63 | *.hmap 64 | 65 | ## App packaging 66 | *.ipa 67 | *.dSYM.zip 68 | *.dSYM 69 | 70 | ## Playgrounds 71 | timeline.xctimeline 72 | playground.xcworkspace 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | # Swift Package Manager 81 | # 82 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 83 | # Packages/ 84 | # Package.pins 85 | # Package.resolved 86 | # *.xcodeproj 87 | # 88 | # Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata 89 | # hence it is not needed unless you have added a package configuration file to your project 90 | # .swiftpm 91 | 92 | .build/ 93 | 94 | # 95 | # Add this line if you want to avoid checking in source code from the Xcode workspace 96 | # *.xcworkspace 97 | 98 | # Carthage 99 | # 100 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 101 | # Carthage/Checkouts 102 | 103 | Carthage/Build/ 104 | 105 | # Accio dependency management 106 | Dependencies/ 107 | .accio/ 108 | 109 | # fastlane 110 | # 111 | # It is recommended to not store the screenshots in the git repo. 112 | # Instead, use fastlane to re-generate the screenshots whenever they are needed. 113 | # For more information about the recommended setup visit: 114 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 115 | 116 | fastlane/report.xml 117 | fastlane/Preview.html 118 | fastlane/screenshots/**/*.png 119 | fastlane/test_output 120 | 121 | # Code Injection 122 | # 123 | # After new code Injection tools there's a generated folder /iOSInjectionProject 124 | # https://github.com/johnno1962/injectionforxcode 125 | 126 | iOSInjectionProject/ 127 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # references: 2 | # * http://www.objc.io/issue-6/travis-ci.html 3 | # * https://github.com/supermarin/xcpretty#usage 4 | 5 | osx_image: xcode7.3 6 | language: objective-c 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 | - set -o pipefail && xcodebuild test -enableCodeCoverage YES -workspace Example/ModularSidebarView.xcworkspace -scheme ModularSidebarView-Example -sdk iphonesimulator9.3 ONLY_ACTIVE_ARCH=NO | xcpretty 14 | - pod lib lint 15 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | 2 | ## [Version 1.0.0](https://github.com/ChrishonWyllie/ModularSidebarView/releases/tag/1.0.0) 3 | 4 | ### New 5 | * Release version 6 | 7 | ### Improvements 8 | 9 | * Cleaner APIs: 10 | * renamed functions 11 | * deprecated unnecessary initializers 12 | * deprecated unnecessary delegate functions in favor instance variables 13 | * replaced confusing SidebarViewCell titles with View-Models 14 | * replaced CGRect/frame animation and manipulation with NSLayoutConstraints 15 | * Updated README with more relevant information 16 | 17 | ### Bug fixes 18 | N/A 19 | 20 | ## [Version 0.2.20](https://github.com/ChrishonWyllie/ModularSidebarView/releases/tag/0.2.20) 21 | 22 | ### New 23 | N/A 24 | 25 | ### Improvements 26 | * Updated README with more relevant information 27 | 28 | ### Bug fixes 29 | N/A 30 | 31 | ## [Version 0.2.16](https://github.com/ChrishonWyllie/ModularSidebarView/releases/tag/0.2.16) 32 | 33 | ### New 34 | * Created this CHANGELOG file 35 | 36 | ### Improvements 37 | N/A 38 | 39 | ### Bug fixes 40 | N/A 41 | 42 | ## [Version 0.2.11](https://github.com/ChrishonWyllie/ModularSidebarView/releases/tag/0.2.11) 43 | 44 | ### New 45 | N/A 46 | 47 | ### Improvements 48 | * Deprecated cumbersome initialization patterns. Privatized properties. Removed unnecessary static functions 49 | 50 | ### Bug fixes 51 | N/A 52 | 53 | ## [Version 0.2.6](https://github.com/ChrishonWyllie/ModularSidebarView/releases/tag/0.2.6) 54 | 55 | ### New 56 | N/A 57 | 58 | ### Improvements 59 | * Replaced deprecated swift version file 60 | 61 | ### Bug fixes 62 | N/A 63 | 64 | ## [Version 0.2.5](https://github.com/ChrishonWyllie/ModularSidebarView/releases/tag/0.2.5) 65 | 66 | ### New 67 | N/A 68 | 69 | ### Improvements 70 | * Updated to Swift version 5 71 | 72 | ### Bug fixes 73 | N/A 74 | 75 | ## [Version 0.2.4](https://github.com/ChrishonWyllie/ModularSidebarView/releases/tag/0.2.4) 76 | 77 | ### New 78 | N/A 79 | 80 | ### Improvements 81 | N/A 82 | 83 | ### Bug fixes 84 | * Fixed issue where allowsPullToDisplay would interfere with the scrolling UIPanGestureRecognizer of UIScrollViews 85 | 86 | ## [Version 0.2.3](https://github.com/ChrishonWyllie/ModularSidebarView/releases/tag/0.2.3) 87 | 88 | ### New 89 | N/A 90 | 91 | ### Improvements 92 | * Refactored to address recognizing multiple gestures when allowsPullToDisplay is set to true 93 | 94 | ### Bug fixes 95 | N/A 96 | 97 | ## [Version 0.2.2](https://github.com/ChrishonWyllie/ModularSidebarView/releases/tag/0.2.2) 98 | 99 | ### New 100 | N/A 101 | 102 | ### Improvements 103 | N/A 104 | 105 | ### Bug fixes 106 | * Fixed issue where allowing pull to display would keep the UIPanGestureRecognizer active on every UIViewController within the UINavigationController stack. 107 | 108 | ## [Version 0.2.1](https://github.com/ChrishonWyllie/ModularSidebarView/releases/tag/0.2.1) 109 | 110 | ### New 111 | * Added animation to change background alpha when showing and dismissing the SidebarView. 112 | 113 | ### Improvements 114 | N/A 115 | 116 | ### Bug fixes 117 | N/A 118 | 119 | ## [Version 0.2.0](https://github.com/ChrishonWyllie/ModularSidebarView/releases/tag/0.2.0) 120 | 121 | ### New 122 | * Added the option to swipe right to open the SidebarView 123 | 124 | ### Improvements 125 | N/A 126 | 127 | ### Bug fixes 128 | N/A 129 | 130 | ## [Version 0.1.1](https://github.com/ChrishonWyllie/ModularSidebarView/releases/tag/0.1.1) 131 | 132 | ### New 133 | * Added the ability to configure if the SidebarView will "push" the currently displayed UIViewController to the side when displaying 134 | 135 | ### Improvements 136 | N/A 137 | 138 | ### Bug fixes 139 | N/A 140 | 141 | ## [Version 0.1.0](https://github.com/ChrishonWyllie/ModularSidebarView/releases/tag/0.1.0) 142 | 143 | ### New 144 | * First commit 145 | 146 | ### Improvements 147 | N/A 148 | 149 | ### Bug fixes 150 | N/A 151 | -------------------------------------------------------------------------------- /Classes/SidebarCollectionView/SidebarCollectionView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SidebarCollectionView.swift 3 | // ModularSidebarView 4 | // 5 | // Created by Chrishon Wyllie on 12/25/17. 6 | // 7 | 8 | import UIKit 9 | 10 | // MARK: - UICollectionView Header 11 | 12 | internal class SidebarCollectionViewLayout: UICollectionViewFlowLayout { 13 | 14 | override init() { 15 | super.init() 16 | 17 | minimumLineSpacing = 0 18 | minimumInteritemSpacing = 0 19 | } 20 | 21 | required init?(coder: NSCoder) { 22 | fatalError("init(coder:) has not been implemented") 23 | } 24 | 25 | override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool { 26 | return true 27 | } 28 | } 29 | 30 | internal class SidebarCollectionView: UICollectionView { 31 | 32 | init() { 33 | super.init(frame: .zero, collectionViewLayout: SidebarCollectionViewLayout()) 34 | setupInitialState() 35 | } 36 | 37 | override init(frame: CGRect, collectionViewLayout layout: UICollectionViewLayout) { 38 | super.init(frame: frame, collectionViewLayout: layout) 39 | setupInitialState() 40 | } 41 | 42 | required init?(coder: NSCoder) { 43 | fatalError("init(coder:) has not been implemented") 44 | } 45 | 46 | private func setupInitialState() { 47 | translatesAutoresizingMaskIntoConstraints = false 48 | alwaysBounceVertical = true 49 | showsVerticalScrollIndicator = false 50 | } 51 | } 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | class SidebarViewContainer: UIView { 65 | 66 | private var didLayoutSubviews: Bool = false 67 | 68 | override func layoutSubviews() { 69 | super.layoutSubviews() 70 | 71 | if didLayoutSubviews == false { 72 | didLayoutSubviews = true 73 | 74 | if willRoundCorners == true, let corners = cornersToRound { 75 | self.roundCorners(corners: corners, radius: radius) 76 | } 77 | } 78 | } 79 | 80 | private var willRoundCorners: Bool = false 81 | private var cornersToRound: UIRectCorner? 82 | private var radius: CGFloat = 0 83 | 84 | public func prepareToRound(corners: UIRectCorner, withRadius radius: CGFloat) { 85 | if didLayoutSubviews == false { 86 | self.willRoundCorners = true 87 | cornersToRound = corners 88 | self.radius = radius 89 | } else { 90 | self.roundCorners(corners: corners, radius: radius) 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /Classes/SidebarCollectionView/SidebarReusableView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SidebarReusableView.swift 3 | // ModularSidebarView 4 | // 5 | // Created by Chrishon Wyllie on 6/10/20. 6 | // 7 | 8 | import UIKit 9 | 10 | open class SidebarReusableView: UICollectionReusableView, ConfigurableReusableView { 11 | public typealias ReusableViewModelClass = SidebarViewReusableViewModelProtocol 12 | 13 | open func configure(with item: SidebarViewReusableViewModelProtocol, at indexPath: IndexPath) { 14 | 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Classes/SidebarCollectionView/SidebarViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SidebarViewCell.swift 3 | // ModularSidebarView 4 | // 5 | // Created by Chrishon Wyllie on 12/25/17. 6 | // 7 | 8 | import UIKit 9 | 10 | // MARK: UICollectionView Cell 11 | 12 | open class SidebarViewCell: UICollectionViewCell, ConfigurableSidebarViewCell { 13 | public typealias CellModelClass = SidebarViewCellModelProtocol 14 | 15 | open func configure(with item: SidebarViewCellModelProtocol, at indexPath: IndexPath) { 16 | 17 | } 18 | } 19 | 20 | public class TextSidebarViewCell: SidebarViewCell { 21 | 22 | public var optionLabel: UILabel = { 23 | let label = UILabel() 24 | label.translatesAutoresizingMaskIntoConstraints = false 25 | label.font = UIFont.systemFont(ofSize: 18) 26 | label.text = "Option" 27 | return label 28 | }() 29 | 30 | public override init(frame: CGRect) { 31 | super.init(frame: frame) 32 | 33 | addSubview(optionLabel) 34 | 35 | if #available(iOS 9.0, *) { 36 | optionLabel.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true 37 | optionLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 16).isActive = true 38 | } 39 | 40 | } 41 | 42 | public required init?(coder aDecoder: NSCoder) { 43 | fatalError("init(coder:) has not been implemented") 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Classes/SidebarView/SidebarView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SidebarView.swift 3 | // ModularSidebarView 4 | // 5 | // Created by Chrishon Wyllie on 12/25/17. 6 | // 7 | 8 | import UIKit 9 | 10 | public class SidebarView: NSObject { 11 | 12 | // MARK: - Variables and Delegate 13 | 14 | public private(set) var sidebarViewIsShowing: Bool = false 15 | 16 | public var dismissesOnSelection: Bool = true 17 | public var shouldPushRootControllerOnDisplay: Bool = false 18 | 19 | public var allowsPullToDisplay: Bool = false { 20 | didSet { 21 | if allowsPullToDisplay == true && applicationScreenWindow?.gestureRecognizers?.contains(panGesture) == false { 22 | applicationScreenWindow?.visibleViewController()?.view.addGestureRecognizer(panGesture) 23 | } else if allowsPullToDisplay == false { 24 | applicationScreenWindow?.visibleViewController()?.view.removeGestureRecognizer(panGesture) 25 | } 26 | } 27 | } 28 | 29 | public var dimmedBackgroundColor: UIColor = Constants.Colors.defaultDimmedViewBackground { 30 | didSet { 31 | self.backgroundBlurView.backgroundColor = dimmedBackgroundColor 32 | } 33 | } 34 | 35 | public var sidebarCornerRadius: CGFloat = 0 { 36 | didSet { 37 | self.sidebarContainerView.prepareToRound(corners: [.topRight, .bottomRight], withRadius: sidebarCornerRadius) 38 | } 39 | } 40 | 41 | private var backgroundBlurEffectView: UIVisualEffectView? 42 | public var blurBackgroundEffect: UIBlurEffect? { 43 | didSet { 44 | self.initializeBackgroundBlurView(withBlurEffect: blurBackgroundEffect) 45 | } 46 | } 47 | 48 | public var sidebarBackgroundColor: UIColor = Constants.Colors.defaultSidebarCollectionViewBackground { 49 | didSet { 50 | sidebarCollectionView.backgroundColor = sidebarBackgroundColor 51 | } 52 | } 53 | 54 | public var sidebarViewScreenPercentageWidth: CGFloat = Constants.Dimensions.defaultScreenWidthPercentage { 55 | didSet { 56 | guard 57 | sidebarViewScreenPercentageWidth > 0 && 58 | sidebarViewScreenPercentageWidth <= 1.0 59 | else { 60 | fatalError("The width of the SidebarView as a percentage must not be 0 and must be less than or equal to 1") 61 | } 62 | sidebarContainerViewWidthAnchor?.constant = sidebarViewWidthConstant 63 | containerView.layoutIfNeeded() 64 | sidebarCollectionView.collectionViewLayout.invalidateLayout() 65 | } 66 | } 67 | 68 | 69 | 70 | 71 | 72 | private var sidebarViewWidthConstant: CGFloat { 73 | let sidebarViewWidth: CGFloat = Constants.Dimensions.deviceScreenWidth * self.sidebarViewScreenPercentageWidth 74 | return sidebarViewWidth 75 | } 76 | private var isDismissedLeadingConstant: CGFloat { 77 | return -(sidebarViewWidthConstant) 78 | } 79 | private let isDisplayedLeadingConstant: CGFloat = 0 80 | 81 | private var sidebarContainerViewLeadingAnchor: NSLayoutConstraint? 82 | private var sidebarContainerViewWidthAnchor: NSLayoutConstraint? 83 | 84 | private lazy var panGesture: UIPanGestureRecognizer = { 85 | let gesture = UIPanGestureRecognizer(target: self, action: #selector(handlePanGesture(panGesture:))) 86 | gesture.delegate = self 87 | return gesture 88 | }() 89 | 90 | private weak var applicationScreenWindow: UIWindow? 91 | private weak var rootViewController: UIViewController? 92 | 93 | private weak var delegate: SidebarViewDelegate? 94 | 95 | private var sidebarViewOrigin: CGPoint = CGPoint.zero 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | private var sidebarItems: [[SidebarViewCellModelProtocol]] = [[]] 105 | private var sidebarReusableSectionItems: [SidebarViewReusableViewSectionProtocol] = [] 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | // MARK: - UI Elements 118 | 119 | public private(set) lazy var containerView: UIView = { 120 | let v = UIView() 121 | v.translatesAutoresizingMaskIntoConstraints = false 122 | v.isHidden = true 123 | return v 124 | }() 125 | 126 | public private(set) lazy var backgroundBlurView: UIView = { 127 | var frame: CGRect = CGRect.zero 128 | let v = UIView(frame: CGRect.zero) 129 | v.translatesAutoresizingMaskIntoConstraints = false 130 | // By default give it a dimmed background color 131 | // If user wants to add UIBlurEffect, this will be overriden 132 | v.backgroundColor = self.dimmedBackgroundColor 133 | v.isUserInteractionEnabled = true 134 | v.alpha = 0.0 135 | return v 136 | }() 137 | 138 | private var sidebarContainerView: SidebarViewContainer = { 139 | let v = SidebarViewContainer() 140 | v.translatesAutoresizingMaskIntoConstraints = false 141 | v.clipsToBounds = true 142 | return v 143 | }() 144 | 145 | private lazy var sidebarCollectionView: SidebarCollectionView = { 146 | let cv = SidebarCollectionView() 147 | cv.backgroundColor = sidebarBackgroundColor 148 | cv.delegate = self 149 | cv.dataSource = self 150 | return cv 151 | }() 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | // MARK: - Initializers 173 | 174 | public init(delegate: SidebarViewDelegate?) { 175 | super.init() 176 | 177 | self.delegate = delegate 178 | // Add as a subview to window and set delegate and datasource 179 | setupUIElementsWithKeyWindow() 180 | } 181 | 182 | @available(swift, obsoleted: 5.0, message: "This initializer has been deprecated. Use initializer with optional delegate argument and use SidebarView properties instead.") 183 | public init(delegate: SidebarViewDelegate?, dismissesOnSelection: Bool) { 184 | super.init() 185 | 186 | self.delegate = delegate 187 | // Add as a subview to window and set delegate and datasource 188 | setupUIElementsWithKeyWindow() 189 | 190 | self.dismissesOnSelection = dismissesOnSelection 191 | 192 | } 193 | 194 | @available(swift, obsoleted: 5.0, message: "This initializer has been deprecated. Use initializer with optional delegate argument and use SidebarView properties instead.") 195 | public init(delegate: SidebarViewDelegate?, dismissesOnSelection: Bool, pushesRootOnDisplay: Bool) { 196 | super.init() 197 | 198 | self.delegate = delegate 199 | // Add as a subview to window and set delegate and datasource 200 | setupUIElementsWithKeyWindow() 201 | 202 | } 203 | 204 | @available(swift, obsoleted: 5.0, message: "This initializer has been deprecated. Use initializer with optional delegate argument instead.") 205 | public override init() { 206 | super.init() 207 | 208 | setupUIElementsWithKeyWindow() 209 | } 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | // MARK: - Functions 221 | 222 | private func setupUIElementsWithKeyWindow() { 223 | guard let window = UIApplication.shared.keyWindow else { 224 | fatalError("No available keyWindow") 225 | } 226 | 227 | applicationScreenWindow = window 228 | let dismissTapGesture = UITapGestureRecognizer(target: self, action: #selector(performDismissFromBackground(tapGesture:))) 229 | self.backgroundBlurView.addGestureRecognizer(dismissTapGesture) 230 | 231 | window.addSubview(containerView) 232 | containerView.addSubview(backgroundBlurView) 233 | containerView.addSubview(sidebarContainerView) 234 | 235 | sidebarContainerView.addSubview(sidebarCollectionView) 236 | 237 | 238 | containerView.leadingAnchor.constraint(equalTo: window.leadingAnchor).isActive = true 239 | containerView.topAnchor.constraint(equalTo: window.topAnchor).isActive = true 240 | containerView.trailingAnchor.constraint(equalTo: window.trailingAnchor).isActive = true 241 | containerView.bottomAnchor.constraint(equalTo: window.bottomAnchor).isActive = true 242 | 243 | backgroundBlurView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor).isActive = true 244 | backgroundBlurView.topAnchor.constraint(equalTo: containerView.topAnchor).isActive = true 245 | backgroundBlurView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor).isActive = true 246 | backgroundBlurView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor).isActive = true 247 | 248 | sidebarContainerViewLeadingAnchor = sidebarContainerView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: isDismissedLeadingConstant) 249 | sidebarContainerViewLeadingAnchor?.isActive = true 250 | sidebarContainerView.topAnchor.constraint(equalTo: containerView.topAnchor).isActive = true 251 | sidebarContainerView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor).isActive = true 252 | sidebarContainerViewWidthAnchor = sidebarContainerView.widthAnchor.constraint(equalToConstant: sidebarViewWidthConstant) 253 | sidebarContainerViewWidthAnchor?.isActive = true 254 | 255 | sidebarCollectionView.leadingAnchor.constraint(equalTo: sidebarContainerView.leadingAnchor).isActive = true 256 | sidebarCollectionView.topAnchor.constraint(equalTo: sidebarContainerView.topAnchor).isActive = true 257 | sidebarCollectionView.trailingAnchor.constraint(equalTo: sidebarContainerView.trailingAnchor).isActive = true 258 | sidebarCollectionView.bottomAnchor.constraint(equalTo: sidebarContainerView.bottomAnchor).isActive = true 259 | } 260 | 261 | private func initializeBackgroundBlurView(withBlurEffect blurEffect: UIBlurEffect?) { 262 | // Chcek if user provided a blur effect. If not, do nothing 263 | if blurEffect != nil { 264 | if backgroundBlurEffectView != nil { 265 | backgroundBlurEffectView?.removeFromSuperview() 266 | backgroundBlurEffectView = nil 267 | } 268 | backgroundBlurEffectView = UIVisualEffectView(effect: blurEffect) 269 | backgroundBlurEffectView?.translatesAutoresizingMaskIntoConstraints = false 270 | backgroundBlurView.addSubview(backgroundBlurEffectView!) 271 | 272 | backgroundBlurView.backgroundColor = UIColor.clear 273 | 274 | backgroundBlurEffectView?.leadingAnchor.constraint(equalTo: backgroundBlurView.leadingAnchor).isActive = true 275 | backgroundBlurEffectView?.topAnchor.constraint(equalTo: backgroundBlurView.topAnchor).isActive = true 276 | backgroundBlurEffectView?.trailingAnchor.constraint(equalTo: backgroundBlurView.trailingAnchor).isActive = true 277 | backgroundBlurEffectView?.bottomAnchor.constraint(equalTo: backgroundBlurView.bottomAnchor).isActive = true 278 | 279 | if self.backgroundBlurView.frame != .zero { 280 | // Immediately layout the blur effect if changed manually later 281 | backgroundBlurView.layoutIfNeeded() 282 | } 283 | 284 | backgroundBlurEffectView?.autoresizingMask = [.flexibleWidth, .flexibleHeight] 285 | 286 | } 287 | } 288 | 289 | } 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | // MARK: - Animation 304 | 305 | extension SidebarView { 306 | 307 | @available(*, unavailable, renamed: "show") 308 | public func showSidebarView() { 309 | performAnimationForSidebarView(shouldDisplay: true, completion: nil) 310 | } 311 | 312 | public func show() { 313 | performAnimationForSidebarView(shouldDisplay: true, completion: nil) 314 | } 315 | 316 | @objc private func performDismissFromBackground(tapGesture: UITapGestureRecognizer) { 317 | dismiss() 318 | } 319 | 320 | @objc public func dismiss() { 321 | 322 | performAnimationForSidebarView(shouldDisplay: false) { 323 | self.containerView.isHidden = true 324 | } 325 | } 326 | 327 | private func performAnimationForSidebarView(shouldDisplay: Bool, completion: (() -> ())?) { 328 | 329 | containerView.isHidden = false 330 | self.sidebarContainerViewLeadingAnchor?.constant = shouldDisplay ? isDisplayedLeadingConstant : isDismissedLeadingConstant 331 | 332 | let rootViewControllerOriginX: CGFloat = shouldDisplay ? sidebarViewWidthConstant : 0 333 | 334 | UIView.animate(withDuration: Constants.Animation.animationDuration, 335 | delay: Constants.Animation.delay, 336 | usingSpringWithDamping: Constants.Animation.springDamping, 337 | initialSpringVelocity: Constants.Animation.springVelocity, 338 | options: Constants.Animation.options, 339 | animations: { 340 | 341 | self.backgroundBlurView.alpha = shouldDisplay ? 1.0 : 0.0 342 | 343 | self.applicationScreenWindow?.layoutIfNeeded() 344 | 345 | if self.shouldPushRootControllerOnDisplay == true { 346 | 347 | self.applicationScreenWindow?.visibleViewController()?.view.frame = CGRect(x: rootViewControllerOriginX, 348 | y: 0, 349 | width: Constants.Dimensions.deviceScreenWidth, 350 | height: Constants.Dimensions.deviceScreenHeight) 351 | 352 | } 353 | 354 | }, completion: { (_) in 355 | self.sidebarViewIsShowing.toggle() 356 | completion?() 357 | }) 358 | } 359 | 360 | 361 | 362 | 363 | 364 | @objc private func handlePanGesture(panGesture: UIPanGestureRecognizer) { 365 | 366 | // Keep users from swiping even though the SidebarView is already showing 367 | guard sidebarViewIsShowing == false else { return } 368 | 369 | let threshold: CGFloat = Constants.Animation.panGestureScreenWidthThreshold 370 | 371 | if let window = applicationScreenWindow, let rootView = window.visibleViewController()?.view { 372 | 373 | let translation = panGesture.translation(in: rootView) 374 | 375 | 376 | if panGesture.state == .began { 377 | 378 | // Store old origin 379 | 380 | sidebarViewOrigin = self.sidebarCollectionView.frame.origin 381 | 382 | } else if panGesture.state == .ended || panGesture.state == .failed || panGesture.state == .cancelled { 383 | 384 | if translation.x >= rootView.frame.width * threshold { 385 | show() 386 | } else { 387 | dismiss() 388 | } 389 | 390 | } else { 391 | 392 | if translation.x >= rootView.frame.width * threshold { 393 | show() 394 | } else { 395 | let newOrigin: CGPoint = CGPoint(x: sidebarViewOrigin.x + (translation.x * 1.5), 396 | y: sidebarViewOrigin.y) 397 | 398 | // self.sidebarCollectionView.frame.origin = newOrigin 399 | self.sidebarContainerViewLeadingAnchor?.constant = newOrigin.x 400 | 401 | let percentToThreshold: CGFloat = (translation.x) / (rootView.frame.width * threshold) 402 | self.backgroundBlurView.alpha = percentToThreshold 403 | } 404 | } 405 | } 406 | 407 | } 408 | } 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | // MARK: - Models 419 | 420 | extension SidebarView { 421 | 422 | public func insertSidebarView(models: [SidebarViewCellModelProtocol], atIndexPaths indexPaths: [IndexPath]) { 423 | guard models.count == indexPaths.count else { 424 | fatalError() 425 | } 426 | 427 | guard indexPaths.contains(where: { (indexPath) -> Bool in 428 | return indexPath.section < 0 || indexPath.item < 0 429 | }) == false else { 430 | fatalError("ModularSidebarView - IndexPaths must not contain negative values") 431 | } 432 | 433 | models.forEach { (model) in 434 | self.sidebarCollectionView.register(model.cellClass, forCellWithReuseIdentifier: model.cellReuseIdentifier) 435 | } 436 | 437 | let sortedIndexPaths = indexPaths.sorted(by: { $0.section < $1.section }) 438 | 439 | for index in 0.. (self.sidebarItems.count - 1) { 444 | // create new section 445 | 446 | let newSection: [SidebarViewCellModelProtocol] = [itemToInsert] 447 | self.sidebarItems.append(newSection) 448 | } else { 449 | 450 | self.sidebarItems[indexPath.section].append(itemToInsert) 451 | } 452 | } 453 | 454 | sidebarCollectionView.reloadData() 455 | } 456 | 457 | public func insertReusableView(reusableSectionModels: [SidebarViewReusableViewSectionProtocol], atIndices indices: [Int]) { 458 | guard reusableSectionModels.count == reusableSectionModels.count else { 459 | fatalError() 460 | } 461 | 462 | guard indices.contains(where: { (value) -> Bool in 463 | return value < 0 464 | }) == false else { 465 | fatalError("ModularSidebarView - Section indices must not be negative") 466 | } 467 | 468 | reusableSectionModels.forEach { (reusableSectionModel) in 469 | 470 | if let header = reusableSectionModel.headerViewModel { 471 | self.sidebarCollectionView.register(header.reusableViewClass, 472 | forSupplementaryViewOfKind: header.elementType.stringValue, 473 | withReuseIdentifier: header.supplementaryViewReuseIdentifier) 474 | } 475 | 476 | if let footer = reusableSectionModel.footerViewModel { 477 | self.sidebarCollectionView.register(footer.reusableViewClass, 478 | forSupplementaryViewOfKind: footer.elementType.stringValue, 479 | withReuseIdentifier: footer.supplementaryViewReuseIdentifier) 480 | } 481 | 482 | } 483 | 484 | let sortedIndices = indices.sorted() 485 | 486 | for index in 0.. (self.sidebarReusableSectionItems.count - 1) { 490 | // create new section 491 | 492 | self.sidebarReusableSectionItems.append(itemToInsert) 493 | } else { 494 | 495 | self.sidebarReusableSectionItems.insert(itemToInsert, at: index) 496 | } 497 | } 498 | 499 | sidebarCollectionView.reloadData() 500 | } 501 | 502 | } 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | // MARK: - UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout 514 | 515 | extension SidebarView: UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout { 516 | 517 | public func numberOfSections(in collectionView: UICollectionView) -> Int { 518 | return sidebarItems.count 519 | } 520 | 521 | public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 522 | return sidebarItems[section].count 523 | } 524 | 525 | 526 | 527 | 528 | // Configure header 529 | 530 | public func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView { 531 | 532 | let reusableSectionItem = sidebarReusableSectionItems[indexPath.section] 533 | 534 | var reusableItem: SidebarViewReusableViewModelProtocol! 535 | 536 | switch kind { 537 | case UICollectionView.elementKindSectionHeader: 538 | reusableItem = reusableSectionItem.headerViewModel 539 | case UICollectionView.elementKindSectionFooter: 540 | reusableItem = reusableSectionItem.footerViewModel 541 | default: fatalError() 542 | } 543 | 544 | let supplementaryItem = collectionView.dequeueReusableSupplementaryView(ofKind: reusableItem.elementType.stringValue, 545 | withReuseIdentifier: reusableItem.supplementaryViewReuseIdentifier, 546 | for: indexPath) as? SidebarReusableView 547 | 548 | supplementaryItem?.configure(with: reusableItem, at: indexPath) 549 | 550 | return supplementaryItem! 551 | 552 | } 553 | 554 | 555 | public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize { 556 | 557 | if section > (sidebarReusableSectionItems.count - 1) { 558 | return CGSize.zero 559 | } 560 | 561 | if let _ = sidebarReusableSectionItems[section].headerViewModel { 562 | let width: CGFloat = collectionView.frame.width 563 | 564 | if let height = delegate?.sidebarView?(self, heightForHeaderIn: section) { 565 | 566 | return CGSize(width: width, height: height) 567 | } 568 | } 569 | // Default 570 | return CGSize.zero 571 | 572 | } 573 | 574 | public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize { 575 | 576 | if section > (sidebarReusableSectionItems.count - 1) { 577 | return CGSize.zero 578 | } 579 | 580 | if let _ = sidebarReusableSectionItems[section].headerViewModel { 581 | let width: CGFloat = collectionView.frame.width 582 | 583 | if let height = delegate?.sidebarView?(self, heightForFooterIn: section) { 584 | 585 | return CGSize(width: width, height: height) 586 | } 587 | } 588 | // Default 589 | return CGSize.zero 590 | 591 | } 592 | 593 | 594 | 595 | 596 | // Configure Cell 597 | 598 | public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { 599 | 600 | let width: CGFloat = collectionView.frame.width 601 | 602 | if let height = delegate?.sidebarView?(self, heightForItemAt: indexPath) { 603 | 604 | return CGSize(width: width, height: height) 605 | } 606 | // Default 607 | return CGSize(width: width, height: Constants.Dimensions.defaultSidebarCellHeight) 608 | 609 | } 610 | 611 | public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 612 | 613 | let item = self.sidebarItems[indexPath.section][indexPath.item] 614 | 615 | let cell = collectionView.dequeueReusableCell(withReuseIdentifier: item.cellReuseIdentifier, 616 | for: indexPath) as? SidebarViewCell 617 | 618 | cell?.configure(with: item, at: indexPath) 619 | 620 | return cell! 621 | 622 | } 623 | 624 | public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { 625 | delegate?.sidebarView?(self, didSelectItemAt: indexPath) 626 | 627 | if dismissesOnSelection { 628 | dismiss() 629 | } 630 | } 631 | 632 | } 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | // MARK: - UIGestureRecognizerDelegate 647 | 648 | extension SidebarView: UIGestureRecognizerDelegate { 649 | 650 | public func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool { 651 | guard let window = applicationScreenWindow, let controllerView = window.visibleViewController()?.view else { return false } 652 | if let panGesture = gestureRecognizer as? UIPanGestureRecognizer { 653 | let velocity = panGesture.velocity(in: controllerView) 654 | return abs(velocity.x) > abs(velocity.y) 655 | } 656 | return true 657 | } 658 | 659 | } 660 | -------------------------------------------------------------------------------- /Classes/Supporting-Files/Constants.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Constants.swift 3 | // ModularSidebarView 4 | // 5 | // Created by Chrishon Wyllie on 6/10/20. 6 | // 7 | 8 | import UIKit 9 | 10 | internal struct Constants { 11 | 12 | private init() {} 13 | 14 | struct Dimensions { 15 | private init() {} 16 | 17 | static var deviceScreenWidth: CGFloat { 18 | return UIScreen.main.bounds.width 19 | } 20 | 21 | static var deviceScreenHeight: CGFloat { 22 | return UIScreen.main.bounds.height 23 | } 24 | 25 | static var defaultScreenWidthPercentage: CGFloat { 26 | return 0.75 27 | } 28 | 29 | static var defaultSidebarCellHeight: CGFloat { 30 | return 60.0 31 | } 32 | } 33 | 34 | struct Colors { 35 | private init() {} 36 | 37 | static let defaultDimmedViewBackground: UIColor = UIColor(white: 0.0, alpha: 0.5) 38 | static let defaultSidebarCollectionViewBackground: UIColor = UIColor.white 39 | } 40 | 41 | struct Animation { 42 | private init() {} 43 | 44 | static let animationDuration: TimeInterval = 0.5 45 | static let delay: TimeInterval = 0.0 46 | static let springDamping: CGFloat = 1.0 47 | static let springVelocity: CGFloat = 0.5 48 | static let options: UIView.AnimationOptions = [.curveEaseInOut] 49 | 50 | 51 | static let panGestureScreenWidthThreshold: CGFloat = 0.35 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Classes/Supporting-Files/Extensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Extensions.swift 3 | // ModularSidebarView 4 | // 5 | // Created by Chrishon Wyllie on 1/1/18. 6 | // 7 | 8 | import Foundation 9 | 10 | extension UIWindow { 11 | 12 | public func visibleViewController() -> UIViewController? { 13 | if let rootViewController: UIViewController = self.rootViewController { 14 | return UIWindow.getVisibleViewController(from: rootViewController) 15 | } 16 | return nil 17 | } 18 | 19 | public class func getVisibleViewController(from viewController: UIViewController) -> UIViewController { 20 | 21 | if viewController.isKind(of: UINavigationController.self) { 22 | 23 | let navigationController = viewController as? UINavigationController 24 | return self.getVisibleViewController(from: (navigationController?.visibleViewController)!) 25 | 26 | } else if viewController.isKind(of: UITabBarController.self) { 27 | 28 | let tabBarController = viewController as? UITabBarController 29 | return self.getVisibleViewController(from: (tabBarController?.selectedViewController!)!) 30 | 31 | } else { 32 | 33 | if let presentedViewController = viewController.presentedViewController { 34 | 35 | return self.getVisibleViewController(from: presentedViewController.presentedViewController!) 36 | 37 | } else { 38 | 39 | return viewController 40 | } 41 | } 42 | } 43 | } 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | extension UIView { 52 | 53 | public func roundCorners(corners: UIRectCorner, radius: CGFloat) { 54 | if self.layer.mask != nil { 55 | self.layer.mask = nil 56 | superview?.layoutIfNeeded() 57 | } 58 | let path = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius)) 59 | let mask = CAShapeLayer() 60 | mask.path = path.cgPath 61 | self.layer.mask = mask 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Classes/Supporting-Files/Protocols+Declarations.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Protocols+Declarations.swift 3 | // ModularSidebarView 4 | // 5 | // Created by Chrishon Wyllie on 6/10/20. 6 | // 7 | 8 | import UIKit 9 | 10 | 11 | // MARK: - SidebarView CollectionView 12 | 13 | /// Protocol by which view-models that represent SidebarView cells must conform to 14 | public protocol SidebarViewCellModelProtocol { 15 | /// The UICollectionViewCell class that will be displayed in the SidebarView 16 | /// e.g.: UICollectionViewCell.self 17 | var cellClass: AnyClass { get } 18 | 19 | /// reuse identifier of the cell. 20 | /// Must return a String representation of the name of the cellClass 21 | /*: 22 | String(describing: type(of: cellClass)) 23 | */ 24 | var cellReuseIdentifier: String { get } 25 | } 26 | 27 | public protocol SidebarViewReusableViewSectionProtocol: AnyObject { 28 | var headerViewModel: SidebarViewReusableViewModelProtocol? { get } 29 | var footerViewModel: SidebarViewReusableViewModelProtocol? { get } 30 | } 31 | 32 | /// Protocol by which view-models that represent SidebarView supplementary views must conform to 33 | public protocol SidebarViewReusableViewModelProtocol { 34 | /// The UICollectionReusableView class that will be displayed in the SidebarView 35 | /// e.g.: UICollectionReusableView.self 36 | var reusableViewClass: AnyClass { get } 37 | 38 | /// reuse identifier for the supplementary view 39 | /// Must return a String representation of the name of the cellClass 40 | /*: 41 | String(describing: type(of: reusableViewClass)) 42 | */ 43 | var supplementaryViewReuseIdentifier: String { get } 44 | var elementType: SidebarViewReusableViewModel.ElementType { get } 45 | } 46 | 47 | /// Protocol by which UICollectionViewCells will conform to. 48 | /// Provides overridable function to configure the cell with the CellModel 49 | /// This is not intended for users to conform to directly. Instead, subclass 50 | /// the SidebarViewCell and override its configure(with:at:) function 51 | public protocol ConfigurableSidebarViewCell: AnyObject { 52 | associatedtype CellModelClass 53 | func configure(with item: CellModelClass, at indexPath: IndexPath) 54 | } 55 | 56 | /// Protocol by which UICollectionReusableViews will conform to. 57 | /// Provides overridable function to configure the view with the ReusableViewModel 58 | /// This is not intended for users to conform to directly. Instead, subclass the 59 | /// SidebarReusableView and override its configure(with:at:) function 60 | public protocol ConfigurableReusableView: AnyObject { 61 | associatedtype ReusableViewModelClass 62 | func configure(with item: ReusableViewModelClass, at indexPath: IndexPath) 63 | } 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | // MARK: - SidebarViewDelegate 81 | 82 | @objc public protocol SidebarViewDelegate: AnyObject { 83 | 84 | // Use this to provide an action to when a cell is selected. Similar to UITableView or UICollectionView functionality 85 | @objc optional func sidebarView(_ sidebarView: SidebarView, didSelectItemAt indexPath: IndexPath) 86 | 87 | // Configure the height of each header 88 | @objc optional func sidebarView(_ sidebarView: SidebarView, heightForHeaderIn section: Int) -> CGFloat 89 | 90 | @objc optional func sidebarView(_ sidebarView: SidebarView, heightForFooterIn section: Int) -> CGFloat 91 | 92 | // Determine height of each cell 93 | @available(swift, obsoleted: 5.0, renamed: "sidebarView(_:heightForItemAt:)") 94 | @objc optional func sidebarView(heightForItemIn section: Int) -> CGFloat 95 | @objc optional func sidebarView(_ view: SidebarView, heightForItemAt indexPath: IndexPath) -> CGFloat 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 | // MARK: - Deprecated 125 | 126 | @available(swift, obsoleted: 5.0, message: "This has been deprecated. Use SidebarView's sidebarViewScreenPercentageWidth property instead") 127 | // Determine width of SidebarView using percentage of device screen. Default is 0.80 (80 %) of the screen 128 | @objc optional var sidebarViewWidth: CGFloat { get } 129 | 130 | @available(swift, obsoleted: 5.0, message: "This has been deprecated. Use SidebarView's allowsPullToDisplay property instead") 131 | // Allow users to swipe to the right in order to display the SidebarView 132 | @objc optional var allowsPullToDisplay: Bool { get } 133 | 134 | @available(swift, obsoleted: 5.0, message: "This has been deprecated. Use SidebarView's blurBackgroundEffect property instead") 135 | // Determine the style of the "blur" view. Options: .dark, .light, .extraLight 136 | @objc optional var blurBackgroundStyle: UIBlurEffect.Style { get } 137 | 138 | @available(swift, obsoleted: 5.0, message: "This has been deprecated. Use SidebarView's sidebarBackgroundColor property instead") 139 | // Determine background color of the SidebarView 140 | @objc optional var sidebarViewBackgroundColor: UIColor { get } 141 | 142 | @available(swift, obsoleted: 5.0, message: "This has been deprecated. Use SidebarView's shouldPushRootControllerOnDisplay property instead") 143 | // Determine whether the SidebarView will push the underlying rootViewController over when displayed 144 | // or simply Cover it 145 | @objc optional var shouldPushRootViewControllerOnDisplay: Bool { get } 146 | 147 | @available(swift, obsoleted: 5.0, message: "This has been deprecated. Use SidebarView's sidebarCornerRadius property instead") 148 | // Round the topRight and bottomRight corners of the SidebarView 149 | @objc optional func shouldRoundCornersWithRadius() -> CGFloat 150 | 151 | @available(swift, obsoleted: 5.0, message: "This has been deprecated. Use SidebarView's sidebarBackgroundColor property instead") 152 | // Determine color of the "blur" view in the background. Essentially the darkening effect that appears over the unerlying viewcontroller 153 | @objc optional var backgroundColor: UIColor { get } 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | @available(swift, obsoleted: 5.0, message: "This has been deprecated. Provide custom ViewModels instead") 162 | @objc optional func willDisplayHeaders() -> Bool 163 | 164 | @available(swift, obsoleted: 5.0, message: "This has been deprecated. Provide custom ViewModels instead") 165 | func numberOfSections(in sidebarView: SidebarView) -> Int 166 | 167 | @available(swift, obsoleted: 5.0, message: "This has been deprecated. Provide custom ViewModels instead") 168 | func sidebarView(_ sidebarView: SidebarView, numberOfItemsInSection section: Int) -> Int 169 | 170 | @available(swift, obsoleted: 5.0, message: "This has been deprecated. Provide custom ViewModels instead") 171 | // For settings specific colors for each item manually instead of blanket coloring every cell 172 | @objc optional func sidebarView(backgroundColor color: UIColor, forItemAt IndexPath: IndexPath) -> UIColor 173 | 174 | @available(swift, obsoleted: 5.0, message: "This has been deprecated. Provide custom ViewModels instead") 175 | // For creating custom cells. Return your own UICollectionViewCell class to be registered 176 | @objc optional func registerCustomCellForSidebarView() -> AnyClass 177 | 178 | @available(swift, obsoleted: 5.0, message: "This has been deprecated. Provide custom ViewModels instead") 179 | // Provide custom configurations for your custom cell 180 | @objc optional func sidebarView(configureCell cell: UICollectionViewCell, forItemAt indexPath: IndexPath) 181 | 182 | @available(swift, obsoleted: 5.0, message: "This has been deprecated. Provide custom ViewModels instead") 183 | // Determine background color of the SidebarViewCell 184 | @objc optional var sidebarCellBackgroundColor: UIColor { get } 185 | 186 | @available(swift, obsoleted: 5.0, message: "This has been deprecated. Provide custom ViewModels instead") 187 | // Determine the actual title of each UICollectionViewCell 188 | func sidebarView(titlesForItemsIn section: Int) -> [String] 189 | 190 | @available(swift, obsoleted: 5.0, message: "This has been deprecated. Provide custom ViewModels instead") 191 | // Font of UILabel in SidebarViewCell 192 | @objc optional func sidebarView(fontForTitleAt indexPath: IndexPath) -> UIFont? 193 | 194 | @available(swift, obsoleted: 5.0, message: "This has been deprecated. Provide custom ViewModels instead") 195 | // TextColor of UILabel in SidebarViewCell 196 | @objc optional func sidebarView(textColorForTitleAt indexPath: IndexPath) -> UIColor? 197 | 198 | @available(swift, obsoleted: 5.0, message: "This has been deprecated. Provide custom ViewModels instead") 199 | // Provide your own view to be added to the Header in each section of the SidebarView 200 | @objc optional func sidebarView(_ sidebarView: SidebarView, viewForHeaderIn section: Int) -> UIView? 201 | 202 | } 203 | -------------------------------------------------------------------------------- /Classes/View-Models/ViewModels.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewModels.swift 3 | // ModularSidebarView 4 | // 5 | // Created by Chrishon Wyllie on 6/10/20. 6 | // 7 | 8 | import Foundation 9 | 10 | open class SidebarViewCellModel: SidebarViewCellModelProtocol { 11 | public private(set) var cellClass: AnyClass 12 | public var cellReuseIdentifier: String { 13 | return String(describing: type(of: cellClass)) 14 | } 15 | 16 | public init(cellClass: AnyClass) { 17 | self.cellClass = cellClass 18 | } 19 | } 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | open class SidebarViewReusableViewSectionModel: SidebarViewReusableViewSectionProtocol { 31 | public var headerViewModel: SidebarViewReusableViewModelProtocol? 32 | 33 | public var footerViewModel: SidebarViewReusableViewModelProtocol? 34 | 35 | public init(headerViewModel: SidebarViewReusableViewModelProtocol?, footerViewModel: SidebarViewReusableViewModelProtocol?) { 36 | self.headerViewModel = headerViewModel 37 | self.footerViewModel = footerViewModel 38 | } 39 | } 40 | 41 | open class SidebarViewReusableViewModel: SidebarViewReusableViewModelProtocol { 42 | public private(set) var reusableViewClass: AnyClass 43 | 44 | public var supplementaryViewReuseIdentifier: String { 45 | return String(describing: type(of: reusableViewClass)) 46 | } 47 | 48 | public var elementType: SidebarViewReusableViewModel.ElementType 49 | 50 | public enum ElementType { 51 | case header 52 | case footer 53 | 54 | var stringValue: String { 55 | switch self { 56 | case .header: return UICollectionView.elementKindSectionHeader 57 | case .footer: return UICollectionView.elementKindSectionFooter 58 | } 59 | } 60 | } 61 | 62 | public init(reusableViewClass: AnyClass, elementType: SidebarViewReusableViewModel.ElementType) { 63 | self.reusableViewClass = reusableViewClass 64 | self.elementType = elementType 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /Example/ModularSidebarView.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD51AFB9204008FA782 /* AppDelegate.swift */; }; 11 | 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD71AFB9204008FA782 /* ViewController.swift */; }; 12 | 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 607FACD91AFB9204008FA782 /* Main.storyboard */; }; 13 | 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDC1AFB9204008FA782 /* Images.xcassets */; }; 14 | 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */; }; 15 | 607FACEC1AFB9204008FA782 /* Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACEB1AFB9204008FA782 /* Tests.swift */; }; 16 | 66B96E8E1FF9FF9A00A499CB /* DetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66B96E8D1FF9FF9A00A499CB /* DetailViewController.swift */; }; 17 | 66B96E971FFAF03100A499CB /* TestController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66B96E961FFAF03100A499CB /* TestController.swift */; }; 18 | 72F3AD37A42869EFFA01B9D2 /* Pods_ModularSidebarView_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D31CBC1C98CD4E1B3A1E6CE3 /* Pods_ModularSidebarView_Example.framework */; }; 19 | F61C278494D236D211BC52CA /* Pods_ModularSidebarView_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9256189B269D6A57F6E7C251 /* Pods_ModularSidebarView_Tests.framework */; }; 20 | /* End PBXBuildFile section */ 21 | 22 | /* Begin PBXContainerItemProxy section */ 23 | 607FACE61AFB9204008FA782 /* PBXContainerItemProxy */ = { 24 | isa = PBXContainerItemProxy; 25 | containerPortal = 607FACC81AFB9204008FA782 /* Project object */; 26 | proxyType = 1; 27 | remoteGlobalIDString = 607FACCF1AFB9204008FA782; 28 | remoteInfo = ModularSidebarView; 29 | }; 30 | /* End PBXContainerItemProxy section */ 31 | 32 | /* Begin PBXFileReference section */ 33 | 0DD9E1724C0352E04CAA03CE /* Pods-ModularSidebarView_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ModularSidebarView_Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ModularSidebarView_Example/Pods-ModularSidebarView_Example.debug.xcconfig"; sourceTree = ""; }; 34 | 232A6FA942F637F4A26D3D82 /* ModularSidebarView.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = ModularSidebarView.podspec; path = ../ModularSidebarView.podspec; sourceTree = ""; }; 35 | 47BF2C313EBD104289411C86 /* Pods-ModularSidebarView_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ModularSidebarView_Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-ModularSidebarView_Tests/Pods-ModularSidebarView_Tests.release.xcconfig"; sourceTree = ""; }; 36 | 4C3EB57424C36BB606EB7EF7 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = ""; }; 37 | 607FACD01AFB9204008FA782 /* ModularSidebarView_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ModularSidebarView_Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 38 | 607FACD41AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 39 | 607FACD51AFB9204008FA782 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 40 | 607FACD71AFB9204008FA782 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 41 | 607FACDA1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 42 | 607FACDC1AFB9204008FA782 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 43 | 607FACDF1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 44 | 607FACE51AFB9204008FA782 /* ModularSidebarView_Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ModularSidebarView_Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 45 | 607FACEA1AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 46 | 607FACEB1AFB9204008FA782 /* Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tests.swift; sourceTree = ""; }; 47 | 66B96E8D1FF9FF9A00A499CB /* DetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailViewController.swift; sourceTree = ""; }; 48 | 66B96E961FFAF03100A499CB /* TestController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestController.swift; sourceTree = ""; }; 49 | 8DD651D8EF28211892AF3888 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; 50 | 9256189B269D6A57F6E7C251 /* Pods_ModularSidebarView_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ModularSidebarView_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 51 | C0CD6633861F63DD75965C2D /* Pods-ModularSidebarView_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ModularSidebarView_Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-ModularSidebarView_Example/Pods-ModularSidebarView_Example.release.xcconfig"; sourceTree = ""; }; 52 | C807A29E105A5436F0FF6D8A /* Pods-ModularSidebarView_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ModularSidebarView_Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ModularSidebarView_Tests/Pods-ModularSidebarView_Tests.debug.xcconfig"; sourceTree = ""; }; 53 | D31CBC1C98CD4E1B3A1E6CE3 /* Pods_ModularSidebarView_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ModularSidebarView_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 54 | /* End PBXFileReference section */ 55 | 56 | /* Begin PBXFrameworksBuildPhase section */ 57 | 607FACCD1AFB9204008FA782 /* Frameworks */ = { 58 | isa = PBXFrameworksBuildPhase; 59 | buildActionMask = 2147483647; 60 | files = ( 61 | 72F3AD37A42869EFFA01B9D2 /* Pods_ModularSidebarView_Example.framework in Frameworks */, 62 | ); 63 | runOnlyForDeploymentPostprocessing = 0; 64 | }; 65 | 607FACE21AFB9204008FA782 /* Frameworks */ = { 66 | isa = PBXFrameworksBuildPhase; 67 | buildActionMask = 2147483647; 68 | files = ( 69 | F61C278494D236D211BC52CA /* Pods_ModularSidebarView_Tests.framework in Frameworks */, 70 | ); 71 | runOnlyForDeploymentPostprocessing = 0; 72 | }; 73 | /* End PBXFrameworksBuildPhase section */ 74 | 75 | /* Begin PBXGroup section */ 76 | 607FACC71AFB9204008FA782 = { 77 | isa = PBXGroup; 78 | children = ( 79 | 607FACF51AFB993E008FA782 /* Podspec Metadata */, 80 | 607FACD21AFB9204008FA782 /* Example for ModularSidebarView */, 81 | 607FACE81AFB9204008FA782 /* Tests */, 82 | 607FACD11AFB9204008FA782 /* Products */, 83 | A53AA1F99D2A57B404B87B27 /* Pods */, 84 | E9C8F8671019ACB70CB5C2AA /* Frameworks */, 85 | ); 86 | sourceTree = ""; 87 | }; 88 | 607FACD11AFB9204008FA782 /* Products */ = { 89 | isa = PBXGroup; 90 | children = ( 91 | 607FACD01AFB9204008FA782 /* ModularSidebarView_Example.app */, 92 | 607FACE51AFB9204008FA782 /* ModularSidebarView_Tests.xctest */, 93 | ); 94 | name = Products; 95 | sourceTree = ""; 96 | }; 97 | 607FACD21AFB9204008FA782 /* Example for ModularSidebarView */ = { 98 | isa = PBXGroup; 99 | children = ( 100 | 607FACD51AFB9204008FA782 /* AppDelegate.swift */, 101 | 607FACD71AFB9204008FA782 /* ViewController.swift */, 102 | 66B96E8D1FF9FF9A00A499CB /* DetailViewController.swift */, 103 | 66B96E961FFAF03100A499CB /* TestController.swift */, 104 | 607FACD91AFB9204008FA782 /* Main.storyboard */, 105 | 607FACDC1AFB9204008FA782 /* Images.xcassets */, 106 | 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */, 107 | 607FACD31AFB9204008FA782 /* Supporting Files */, 108 | ); 109 | name = "Example for ModularSidebarView"; 110 | path = ModularSidebarView; 111 | sourceTree = ""; 112 | }; 113 | 607FACD31AFB9204008FA782 /* Supporting Files */ = { 114 | isa = PBXGroup; 115 | children = ( 116 | 607FACD41AFB9204008FA782 /* Info.plist */, 117 | ); 118 | name = "Supporting Files"; 119 | sourceTree = ""; 120 | }; 121 | 607FACE81AFB9204008FA782 /* Tests */ = { 122 | isa = PBXGroup; 123 | children = ( 124 | 607FACEB1AFB9204008FA782 /* Tests.swift */, 125 | 607FACE91AFB9204008FA782 /* Supporting Files */, 126 | ); 127 | path = Tests; 128 | sourceTree = ""; 129 | }; 130 | 607FACE91AFB9204008FA782 /* Supporting Files */ = { 131 | isa = PBXGroup; 132 | children = ( 133 | 607FACEA1AFB9204008FA782 /* Info.plist */, 134 | ); 135 | name = "Supporting Files"; 136 | sourceTree = ""; 137 | }; 138 | 607FACF51AFB993E008FA782 /* Podspec Metadata */ = { 139 | isa = PBXGroup; 140 | children = ( 141 | 232A6FA942F637F4A26D3D82 /* ModularSidebarView.podspec */, 142 | 8DD651D8EF28211892AF3888 /* README.md */, 143 | 4C3EB57424C36BB606EB7EF7 /* LICENSE */, 144 | ); 145 | name = "Podspec Metadata"; 146 | sourceTree = ""; 147 | }; 148 | A53AA1F99D2A57B404B87B27 /* Pods */ = { 149 | isa = PBXGroup; 150 | children = ( 151 | 0DD9E1724C0352E04CAA03CE /* Pods-ModularSidebarView_Example.debug.xcconfig */, 152 | C0CD6633861F63DD75965C2D /* Pods-ModularSidebarView_Example.release.xcconfig */, 153 | C807A29E105A5436F0FF6D8A /* Pods-ModularSidebarView_Tests.debug.xcconfig */, 154 | 47BF2C313EBD104289411C86 /* Pods-ModularSidebarView_Tests.release.xcconfig */, 155 | ); 156 | name = Pods; 157 | sourceTree = ""; 158 | }; 159 | E9C8F8671019ACB70CB5C2AA /* Frameworks */ = { 160 | isa = PBXGroup; 161 | children = ( 162 | D31CBC1C98CD4E1B3A1E6CE3 /* Pods_ModularSidebarView_Example.framework */, 163 | 9256189B269D6A57F6E7C251 /* Pods_ModularSidebarView_Tests.framework */, 164 | ); 165 | name = Frameworks; 166 | sourceTree = ""; 167 | }; 168 | /* End PBXGroup section */ 169 | 170 | /* Begin PBXNativeTarget section */ 171 | 607FACCF1AFB9204008FA782 /* ModularSidebarView_Example */ = { 172 | isa = PBXNativeTarget; 173 | buildConfigurationList = 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "ModularSidebarView_Example" */; 174 | buildPhases = ( 175 | 0C74E0950A1CB6BFCBAC2420 /* [CP] Check Pods Manifest.lock */, 176 | 607FACCC1AFB9204008FA782 /* Sources */, 177 | 607FACCD1AFB9204008FA782 /* Frameworks */, 178 | 607FACCE1AFB9204008FA782 /* Resources */, 179 | 526D22727437973000719199 /* [CP] Embed Pods Frameworks */, 180 | 3DA575EF92925CC11B60A20A /* [CP] Copy Pods Resources */, 181 | ); 182 | buildRules = ( 183 | ); 184 | dependencies = ( 185 | ); 186 | name = ModularSidebarView_Example; 187 | productName = ModularSidebarView; 188 | productReference = 607FACD01AFB9204008FA782 /* ModularSidebarView_Example.app */; 189 | productType = "com.apple.product-type.application"; 190 | }; 191 | 607FACE41AFB9204008FA782 /* ModularSidebarView_Tests */ = { 192 | isa = PBXNativeTarget; 193 | buildConfigurationList = 607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "ModularSidebarView_Tests" */; 194 | buildPhases = ( 195 | FDC8CF6FBD43BD70ECB0544B /* [CP] Check Pods Manifest.lock */, 196 | 607FACE11AFB9204008FA782 /* Sources */, 197 | 607FACE21AFB9204008FA782 /* Frameworks */, 198 | 607FACE31AFB9204008FA782 /* Resources */, 199 | 62C759DEFAEFC89FE2EE6A88 /* [CP] Embed Pods Frameworks */, 200 | CE280CEA5994BA1A69D1F292 /* [CP] Copy Pods Resources */, 201 | ); 202 | buildRules = ( 203 | ); 204 | dependencies = ( 205 | 607FACE71AFB9204008FA782 /* PBXTargetDependency */, 206 | ); 207 | name = ModularSidebarView_Tests; 208 | productName = Tests; 209 | productReference = 607FACE51AFB9204008FA782 /* ModularSidebarView_Tests.xctest */; 210 | productType = "com.apple.product-type.bundle.unit-test"; 211 | }; 212 | /* End PBXNativeTarget section */ 213 | 214 | /* Begin PBXProject section */ 215 | 607FACC81AFB9204008FA782 /* Project object */ = { 216 | isa = PBXProject; 217 | attributes = { 218 | LastSwiftUpdateCheck = 0830; 219 | LastUpgradeCheck = 1130; 220 | ORGANIZATIONNAME = CocoaPods; 221 | TargetAttributes = { 222 | 607FACCF1AFB9204008FA782 = { 223 | CreatedOnToolsVersion = 6.3.1; 224 | DevelopmentTeam = UL42AV8U5L; 225 | LastSwiftMigration = 1130; 226 | }; 227 | 607FACE41AFB9204008FA782 = { 228 | CreatedOnToolsVersion = 6.3.1; 229 | DevelopmentTeam = UL42AV8U5L; 230 | LastSwiftMigration = 1130; 231 | TestTargetID = 607FACCF1AFB9204008FA782; 232 | }; 233 | }; 234 | }; 235 | buildConfigurationList = 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "ModularSidebarView" */; 236 | compatibilityVersion = "Xcode 3.2"; 237 | developmentRegion = en; 238 | hasScannedForEncodings = 0; 239 | knownRegions = ( 240 | en, 241 | Base, 242 | ); 243 | mainGroup = 607FACC71AFB9204008FA782; 244 | productRefGroup = 607FACD11AFB9204008FA782 /* Products */; 245 | projectDirPath = ""; 246 | projectRoot = ""; 247 | targets = ( 248 | 607FACCF1AFB9204008FA782 /* ModularSidebarView_Example */, 249 | 607FACE41AFB9204008FA782 /* ModularSidebarView_Tests */, 250 | ); 251 | }; 252 | /* End PBXProject section */ 253 | 254 | /* Begin PBXResourcesBuildPhase section */ 255 | 607FACCE1AFB9204008FA782 /* Resources */ = { 256 | isa = PBXResourcesBuildPhase; 257 | buildActionMask = 2147483647; 258 | files = ( 259 | 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */, 260 | 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */, 261 | 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */, 262 | ); 263 | runOnlyForDeploymentPostprocessing = 0; 264 | }; 265 | 607FACE31AFB9204008FA782 /* Resources */ = { 266 | isa = PBXResourcesBuildPhase; 267 | buildActionMask = 2147483647; 268 | files = ( 269 | ); 270 | runOnlyForDeploymentPostprocessing = 0; 271 | }; 272 | /* End PBXResourcesBuildPhase section */ 273 | 274 | /* Begin PBXShellScriptBuildPhase section */ 275 | 0C74E0950A1CB6BFCBAC2420 /* [CP] Check Pods Manifest.lock */ = { 276 | isa = PBXShellScriptBuildPhase; 277 | buildActionMask = 2147483647; 278 | files = ( 279 | ); 280 | inputPaths = ( 281 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 282 | "${PODS_ROOT}/Manifest.lock", 283 | ); 284 | name = "[CP] Check Pods Manifest.lock"; 285 | outputPaths = ( 286 | "$(DERIVED_FILE_DIR)/Pods-ModularSidebarView_Example-checkManifestLockResult.txt", 287 | ); 288 | runOnlyForDeploymentPostprocessing = 0; 289 | shellPath = /bin/sh; 290 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 291 | showEnvVarsInLog = 0; 292 | }; 293 | 3DA575EF92925CC11B60A20A /* [CP] Copy Pods Resources */ = { 294 | isa = PBXShellScriptBuildPhase; 295 | buildActionMask = 2147483647; 296 | files = ( 297 | ); 298 | inputPaths = ( 299 | ); 300 | name = "[CP] Copy Pods Resources"; 301 | outputPaths = ( 302 | ); 303 | runOnlyForDeploymentPostprocessing = 0; 304 | shellPath = /bin/sh; 305 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ModularSidebarView_Example/Pods-ModularSidebarView_Example-resources.sh\"\n"; 306 | showEnvVarsInLog = 0; 307 | }; 308 | 526D22727437973000719199 /* [CP] Embed Pods Frameworks */ = { 309 | isa = PBXShellScriptBuildPhase; 310 | buildActionMask = 2147483647; 311 | files = ( 312 | ); 313 | inputPaths = ( 314 | "${SRCROOT}/Pods/Target Support Files/Pods-ModularSidebarView_Example/Pods-ModularSidebarView_Example-frameworks.sh", 315 | "${BUILT_PRODUCTS_DIR}/ModularSidebarView/ModularSidebarView.framework", 316 | ); 317 | name = "[CP] Embed Pods Frameworks"; 318 | outputPaths = ( 319 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ModularSidebarView.framework", 320 | ); 321 | runOnlyForDeploymentPostprocessing = 0; 322 | shellPath = /bin/sh; 323 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ModularSidebarView_Example/Pods-ModularSidebarView_Example-frameworks.sh\"\n"; 324 | showEnvVarsInLog = 0; 325 | }; 326 | 62C759DEFAEFC89FE2EE6A88 /* [CP] Embed Pods Frameworks */ = { 327 | isa = PBXShellScriptBuildPhase; 328 | buildActionMask = 2147483647; 329 | files = ( 330 | ); 331 | inputPaths = ( 332 | ); 333 | name = "[CP] Embed Pods Frameworks"; 334 | outputPaths = ( 335 | ); 336 | runOnlyForDeploymentPostprocessing = 0; 337 | shellPath = /bin/sh; 338 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ModularSidebarView_Tests/Pods-ModularSidebarView_Tests-frameworks.sh\"\n"; 339 | showEnvVarsInLog = 0; 340 | }; 341 | CE280CEA5994BA1A69D1F292 /* [CP] Copy Pods Resources */ = { 342 | isa = PBXShellScriptBuildPhase; 343 | buildActionMask = 2147483647; 344 | files = ( 345 | ); 346 | inputPaths = ( 347 | ); 348 | name = "[CP] Copy Pods Resources"; 349 | outputPaths = ( 350 | ); 351 | runOnlyForDeploymentPostprocessing = 0; 352 | shellPath = /bin/sh; 353 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ModularSidebarView_Tests/Pods-ModularSidebarView_Tests-resources.sh\"\n"; 354 | showEnvVarsInLog = 0; 355 | }; 356 | FDC8CF6FBD43BD70ECB0544B /* [CP] Check Pods Manifest.lock */ = { 357 | isa = PBXShellScriptBuildPhase; 358 | buildActionMask = 2147483647; 359 | files = ( 360 | ); 361 | inputPaths = ( 362 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 363 | "${PODS_ROOT}/Manifest.lock", 364 | ); 365 | name = "[CP] Check Pods Manifest.lock"; 366 | outputPaths = ( 367 | "$(DERIVED_FILE_DIR)/Pods-ModularSidebarView_Tests-checkManifestLockResult.txt", 368 | ); 369 | runOnlyForDeploymentPostprocessing = 0; 370 | shellPath = /bin/sh; 371 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 372 | showEnvVarsInLog = 0; 373 | }; 374 | /* End PBXShellScriptBuildPhase section */ 375 | 376 | /* Begin PBXSourcesBuildPhase section */ 377 | 607FACCC1AFB9204008FA782 /* Sources */ = { 378 | isa = PBXSourcesBuildPhase; 379 | buildActionMask = 2147483647; 380 | files = ( 381 | 66B96E8E1FF9FF9A00A499CB /* DetailViewController.swift in Sources */, 382 | 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */, 383 | 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */, 384 | 66B96E971FFAF03100A499CB /* TestController.swift in Sources */, 385 | ); 386 | runOnlyForDeploymentPostprocessing = 0; 387 | }; 388 | 607FACE11AFB9204008FA782 /* Sources */ = { 389 | isa = PBXSourcesBuildPhase; 390 | buildActionMask = 2147483647; 391 | files = ( 392 | 607FACEC1AFB9204008FA782 /* Tests.swift in Sources */, 393 | ); 394 | runOnlyForDeploymentPostprocessing = 0; 395 | }; 396 | /* End PBXSourcesBuildPhase section */ 397 | 398 | /* Begin PBXTargetDependency section */ 399 | 607FACE71AFB9204008FA782 /* PBXTargetDependency */ = { 400 | isa = PBXTargetDependency; 401 | target = 607FACCF1AFB9204008FA782 /* ModularSidebarView_Example */; 402 | targetProxy = 607FACE61AFB9204008FA782 /* PBXContainerItemProxy */; 403 | }; 404 | /* End PBXTargetDependency section */ 405 | 406 | /* Begin PBXVariantGroup section */ 407 | 607FACD91AFB9204008FA782 /* Main.storyboard */ = { 408 | isa = PBXVariantGroup; 409 | children = ( 410 | 607FACDA1AFB9204008FA782 /* Base */, 411 | ); 412 | name = Main.storyboard; 413 | sourceTree = ""; 414 | }; 415 | 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */ = { 416 | isa = PBXVariantGroup; 417 | children = ( 418 | 607FACDF1AFB9204008FA782 /* Base */, 419 | ); 420 | name = LaunchScreen.xib; 421 | sourceTree = ""; 422 | }; 423 | /* End PBXVariantGroup section */ 424 | 425 | /* Begin XCBuildConfiguration section */ 426 | 607FACED1AFB9204008FA782 /* Debug */ = { 427 | isa = XCBuildConfiguration; 428 | buildSettings = { 429 | ALWAYS_SEARCH_USER_PATHS = NO; 430 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 431 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 432 | CLANG_CXX_LIBRARY = "libc++"; 433 | CLANG_ENABLE_MODULES = YES; 434 | CLANG_ENABLE_OBJC_ARC = YES; 435 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 436 | CLANG_WARN_BOOL_CONVERSION = YES; 437 | CLANG_WARN_COMMA = YES; 438 | CLANG_WARN_CONSTANT_CONVERSION = YES; 439 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 440 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 441 | CLANG_WARN_EMPTY_BODY = YES; 442 | CLANG_WARN_ENUM_CONVERSION = YES; 443 | CLANG_WARN_INFINITE_RECURSION = YES; 444 | CLANG_WARN_INT_CONVERSION = YES; 445 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 446 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 447 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 448 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 449 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 450 | CLANG_WARN_STRICT_PROTOTYPES = YES; 451 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 452 | CLANG_WARN_UNREACHABLE_CODE = YES; 453 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 454 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 455 | COPY_PHASE_STRIP = NO; 456 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 457 | ENABLE_STRICT_OBJC_MSGSEND = YES; 458 | ENABLE_TESTABILITY = YES; 459 | GCC_C_LANGUAGE_STANDARD = gnu99; 460 | GCC_DYNAMIC_NO_PIC = NO; 461 | GCC_NO_COMMON_BLOCKS = YES; 462 | GCC_OPTIMIZATION_LEVEL = 0; 463 | GCC_PREPROCESSOR_DEFINITIONS = ( 464 | "DEBUG=1", 465 | "$(inherited)", 466 | ); 467 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 468 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 469 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 470 | GCC_WARN_UNDECLARED_SELECTOR = YES; 471 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 472 | GCC_WARN_UNUSED_FUNCTION = YES; 473 | GCC_WARN_UNUSED_VARIABLE = YES; 474 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 475 | MTL_ENABLE_DEBUG_INFO = YES; 476 | ONLY_ACTIVE_ARCH = YES; 477 | SDKROOT = iphoneos; 478 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 479 | SWIFT_VERSION = 4.0; 480 | }; 481 | name = Debug; 482 | }; 483 | 607FACEE1AFB9204008FA782 /* Release */ = { 484 | isa = XCBuildConfiguration; 485 | buildSettings = { 486 | ALWAYS_SEARCH_USER_PATHS = NO; 487 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 488 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 489 | CLANG_CXX_LIBRARY = "libc++"; 490 | CLANG_ENABLE_MODULES = YES; 491 | CLANG_ENABLE_OBJC_ARC = YES; 492 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 493 | CLANG_WARN_BOOL_CONVERSION = YES; 494 | CLANG_WARN_COMMA = YES; 495 | CLANG_WARN_CONSTANT_CONVERSION = YES; 496 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 497 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 498 | CLANG_WARN_EMPTY_BODY = YES; 499 | CLANG_WARN_ENUM_CONVERSION = YES; 500 | CLANG_WARN_INFINITE_RECURSION = YES; 501 | CLANG_WARN_INT_CONVERSION = YES; 502 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 503 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 504 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 505 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 506 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 507 | CLANG_WARN_STRICT_PROTOTYPES = YES; 508 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 509 | CLANG_WARN_UNREACHABLE_CODE = YES; 510 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 511 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 512 | COPY_PHASE_STRIP = NO; 513 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 514 | ENABLE_NS_ASSERTIONS = NO; 515 | ENABLE_STRICT_OBJC_MSGSEND = YES; 516 | GCC_C_LANGUAGE_STANDARD = gnu99; 517 | GCC_NO_COMMON_BLOCKS = YES; 518 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 519 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 520 | GCC_WARN_UNDECLARED_SELECTOR = YES; 521 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 522 | GCC_WARN_UNUSED_FUNCTION = YES; 523 | GCC_WARN_UNUSED_VARIABLE = YES; 524 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 525 | MTL_ENABLE_DEBUG_INFO = NO; 526 | SDKROOT = iphoneos; 527 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 528 | SWIFT_VERSION = 4.0; 529 | VALIDATE_PRODUCT = YES; 530 | }; 531 | name = Release; 532 | }; 533 | 607FACF01AFB9204008FA782 /* Debug */ = { 534 | isa = XCBuildConfiguration; 535 | baseConfigurationReference = 0DD9E1724C0352E04CAA03CE /* Pods-ModularSidebarView_Example.debug.xcconfig */; 536 | buildSettings = { 537 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 538 | DEVELOPMENT_TEAM = UL42AV8U5L; 539 | INFOPLIST_FILE = ModularSidebarView/Info.plist; 540 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 541 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 542 | MODULE_NAME = ExampleApp; 543 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)"; 544 | PRODUCT_NAME = "$(TARGET_NAME)"; 545 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 546 | SWIFT_VERSION = 5.0; 547 | }; 548 | name = Debug; 549 | }; 550 | 607FACF11AFB9204008FA782 /* Release */ = { 551 | isa = XCBuildConfiguration; 552 | baseConfigurationReference = C0CD6633861F63DD75965C2D /* Pods-ModularSidebarView_Example.release.xcconfig */; 553 | buildSettings = { 554 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 555 | DEVELOPMENT_TEAM = UL42AV8U5L; 556 | INFOPLIST_FILE = ModularSidebarView/Info.plist; 557 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 558 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 559 | MODULE_NAME = ExampleApp; 560 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)"; 561 | PRODUCT_NAME = "$(TARGET_NAME)"; 562 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 563 | SWIFT_VERSION = 5.0; 564 | }; 565 | name = Release; 566 | }; 567 | 607FACF31AFB9204008FA782 /* Debug */ = { 568 | isa = XCBuildConfiguration; 569 | baseConfigurationReference = C807A29E105A5436F0FF6D8A /* Pods-ModularSidebarView_Tests.debug.xcconfig */; 570 | buildSettings = { 571 | DEVELOPMENT_TEAM = UL42AV8U5L; 572 | FRAMEWORK_SEARCH_PATHS = ( 573 | "$(SDKROOT)/Developer/Library/Frameworks", 574 | "$(inherited)", 575 | ); 576 | GCC_PREPROCESSOR_DEFINITIONS = ( 577 | "DEBUG=1", 578 | "$(inherited)", 579 | ); 580 | INFOPLIST_FILE = Tests/Info.plist; 581 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 582 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)"; 583 | PRODUCT_NAME = "$(TARGET_NAME)"; 584 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 585 | SWIFT_VERSION = 5.0; 586 | }; 587 | name = Debug; 588 | }; 589 | 607FACF41AFB9204008FA782 /* Release */ = { 590 | isa = XCBuildConfiguration; 591 | baseConfigurationReference = 47BF2C313EBD104289411C86 /* Pods-ModularSidebarView_Tests.release.xcconfig */; 592 | buildSettings = { 593 | DEVELOPMENT_TEAM = UL42AV8U5L; 594 | FRAMEWORK_SEARCH_PATHS = ( 595 | "$(SDKROOT)/Developer/Library/Frameworks", 596 | "$(inherited)", 597 | ); 598 | INFOPLIST_FILE = Tests/Info.plist; 599 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 600 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)"; 601 | PRODUCT_NAME = "$(TARGET_NAME)"; 602 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 603 | SWIFT_VERSION = 5.0; 604 | }; 605 | name = Release; 606 | }; 607 | /* End XCBuildConfiguration section */ 608 | 609 | /* Begin XCConfigurationList section */ 610 | 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "ModularSidebarView" */ = { 611 | isa = XCConfigurationList; 612 | buildConfigurations = ( 613 | 607FACED1AFB9204008FA782 /* Debug */, 614 | 607FACEE1AFB9204008FA782 /* Release */, 615 | ); 616 | defaultConfigurationIsVisible = 0; 617 | defaultConfigurationName = Release; 618 | }; 619 | 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "ModularSidebarView_Example" */ = { 620 | isa = XCConfigurationList; 621 | buildConfigurations = ( 622 | 607FACF01AFB9204008FA782 /* Debug */, 623 | 607FACF11AFB9204008FA782 /* Release */, 624 | ); 625 | defaultConfigurationIsVisible = 0; 626 | defaultConfigurationName = Release; 627 | }; 628 | 607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "ModularSidebarView_Tests" */ = { 629 | isa = XCConfigurationList; 630 | buildConfigurations = ( 631 | 607FACF31AFB9204008FA782 /* Debug */, 632 | 607FACF41AFB9204008FA782 /* Release */, 633 | ); 634 | defaultConfigurationIsVisible = 0; 635 | defaultConfigurationName = Release; 636 | }; 637 | /* End XCConfigurationList section */ 638 | }; 639 | rootObject = 607FACC81AFB9204008FA782 /* Project object */; 640 | } 641 | -------------------------------------------------------------------------------- /Example/ModularSidebarView.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/ModularSidebarView.xcodeproj/xcshareddata/xcschemes/ModularSidebarView-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/ModularSidebarView.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Example/ModularSidebarView/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // ModularSidebarView 4 | // 5 | // Created by ChrishonWyllie on 12/25/2017. 6 | // Copyright (c) 2017 ChrishonWyllie. 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]?) -> Bool { 18 | // Override point for customization after application launch. 19 | 20 | navigateToController() 21 | 22 | return true 23 | } 24 | 25 | private func navigateToController() { 26 | window = UIWindow(frame: UIScreen.main.bounds) 27 | let controller = ViewController() 28 | let navigationController = UINavigationController(rootViewController: controller) 29 | window?.rootViewController = navigationController 30 | window?.makeKeyAndVisible() 31 | } 32 | 33 | func applicationWillResignActive(_ application: UIApplication) { 34 | // 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. 35 | // 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. 36 | } 37 | 38 | func applicationDidEnterBackground(_ application: UIApplication) { 39 | // 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. 40 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 41 | } 42 | 43 | func applicationWillEnterForeground(_ application: UIApplication) { 44 | // 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. 45 | } 46 | 47 | func applicationDidBecomeActive(_ application: UIApplication) { 48 | // 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. 49 | } 50 | 51 | func applicationWillTerminate(_ application: UIApplication) { 52 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 53 | } 54 | 55 | 56 | } 57 | 58 | -------------------------------------------------------------------------------- /Example/ModularSidebarView/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /Example/ModularSidebarView/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Example/ModularSidebarView/DetailViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DetailViewController.swift 3 | // ModularSidebarView_Example 4 | // 5 | // Created by Chrishon Wyllie on 1/1/18. 6 | // Copyright © 2018 CocoaPods. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class DetailViewController: UIViewController { 12 | 13 | public var passedInfoString: String? { 14 | didSet { 15 | label.text = passedInfoString 16 | } 17 | } 18 | 19 | public var label: UILabel = { 20 | let lbl = UILabel() 21 | lbl.translatesAutoresizingMaskIntoConstraints = false 22 | lbl.textColor = UIColor(red: 0.12, green: 0.12, blue: 0.12, alpha: 1.0) 23 | lbl.font = UIFont.init(name: "Arial", size: 36) 24 | lbl.textAlignment = .center 25 | lbl.numberOfLines = 0 26 | return lbl 27 | }() 28 | 29 | override func viewDidLoad() { 30 | super.viewDidLoad() 31 | 32 | // Do any additional setup after loading the view. 33 | 34 | view.backgroundColor = .white 35 | 36 | view.addSubview(label) 37 | 38 | label.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16).isActive = true 39 | label.topAnchor.constraint(equalTo: view.topAnchor, constant: 16).isActive = true 40 | label.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -16).isActive = true 41 | label.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -16).isActive = true 42 | 43 | } 44 | 45 | override func didReceiveMemoryWarning() { 46 | super.didReceiveMemoryWarning() 47 | // Dispose of any resources that can be recreated. 48 | } 49 | 50 | 51 | /* 52 | // MARK: - Navigation 53 | 54 | // In a storyboard-based application, you will often want to do a little preparation before navigation 55 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 56 | // Get the new view controller using segue.destinationViewController. 57 | // Pass the selected object to the new view controller. 58 | } 59 | */ 60 | 61 | } 62 | -------------------------------------------------------------------------------- /Example/ModularSidebarView/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Example/ModularSidebarView/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 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /Example/ModularSidebarView/TestController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TestController.swift 3 | // ModularSidebarView_Example 4 | // 5 | // Created by Chrishon Wyllie on 1/1/18. 6 | // Copyright © 2018 CocoaPods. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import ModularSidebarView 11 | 12 | class TestController: UITableViewController { 13 | 14 | let testData: [String] = ["test one", 15 | "test two", 16 | "test three", 17 | "test four", 18 | "test five", 19 | "test six", 20 | "test seven"] 21 | 22 | let sectionOneImageNames: [String] = ["some_image_one", "some_image_two", "some_image_three", "some_image_four", "some_image_five"] 23 | let sectionOneOptionTitles: [String] = ["Home", "Account", "Transactions", "Help", "Some option"] 24 | 25 | let sectionTwoImageNames: [String] = ["some_image_one", "some_image_two"] 26 | let sectionTwoOptionTitles: [String] = ["Settings", "Log out"] 27 | 28 | // For if you want allowSwipeToDisplay 29 | private var sidebarView: SidebarView? 30 | 31 | lazy var sidebarButton: UIBarButtonItem = { 32 | let btn = UIBarButtonItem(title: "Side", style: .done, target: self, action: #selector(openSidebarView(_:))) 33 | return btn 34 | }() 35 | 36 | @objc private func openSidebarView(_ sender: Any) { 37 | sidebarView?.show() 38 | } 39 | 40 | override func viewDidLoad() { 41 | super.viewDidLoad() 42 | // Do any additional setup after loading the view, typically from a nib. 43 | 44 | sidebarView = SidebarView(delegate: self) 45 | sidebarView?.sidebarViewScreenPercentageWidth = 0.5 46 | 47 | self.navigationItem.leftBarButtonItem = sidebarButton 48 | 49 | self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell") 50 | 51 | setupSidebarViewItems() 52 | } 53 | 54 | override func didReceiveMemoryWarning() { 55 | super.didReceiveMemoryWarning() 56 | // Dispose of any resources that can be recreated. 57 | } 58 | 59 | // MARK: - Table view data source 60 | 61 | override func numberOfSections(in tableView: UITableView) -> Int { 62 | return 1 63 | } 64 | 65 | override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 66 | return testData.count 67 | } 68 | 69 | override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { 70 | return 240 71 | } 72 | 73 | override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 74 | 75 | let cell = tableView.dequeueReusableCell(withIdentifier: "cell") 76 | 77 | let someTestString = testData[indexPath.row] 78 | 79 | cell?.textLabel?.text = someTestString 80 | 81 | return cell! 82 | 83 | } 84 | 85 | private func setupSidebarViewItems() { 86 | let sectionOneIndexPaths = Array(0.. SidebarViewCellModel in 88 | return CustomSidebarCellModel(image: nil, title: title) 89 | } 90 | 91 | let sectionTwoIndexPaths = Array(0.. SidebarViewCellModel in 93 | return CustomSidebarCellModel(image: nil, title: title) 94 | } 95 | 96 | let items = (sectionOneItems + sectionTwoItems) 97 | let indexPaths = (sectionOneIndexPaths + sectionTwoIndexPaths) 98 | 99 | sidebarView?.insertSidebarView(models: items, atIndexPaths: indexPaths) 100 | 101 | 102 | let reusableSectionItems: [SidebarViewReusableViewSectionModel] = [ 103 | 104 | SidebarViewReusableViewSectionModel(headerViewModel: CustomSidebarSectionHeaderModel(), 105 | footerViewModel: CustomSidebarSectionFooterModel()), 106 | SidebarViewReusableViewSectionModel(headerViewModel: CustomSidebarSectionHeaderModel(), 107 | footerViewModel: CustomSidebarSectionFooterModel()) 108 | ] 109 | 110 | let indices = [0, 1] 111 | 112 | sidebarView?.insertReusableView(reusableSectionModels: reusableSectionItems, atIndices: indices) 113 | 114 | } 115 | } 116 | 117 | 118 | extension TestController: SidebarViewDelegate { 119 | 120 | // Configure SidebarView 121 | 122 | func sidebarView(_ sidebarView: SidebarView, didSelectItemAt indexPath: IndexPath) { 123 | var infoToPass: String 124 | let detailViewController = DetailViewController() 125 | switch indexPath.section { 126 | case 0: 127 | print(sectionOneOptionTitles[indexPath.item]) 128 | infoToPass = sectionOneOptionTitles[indexPath.item] 129 | default: 130 | print(sectionTwoOptionTitles[indexPath.item]) 131 | infoToPass = sectionTwoOptionTitles[indexPath.item] 132 | } 133 | detailViewController.passedInfoString = infoToPass 134 | self.navigationController?.pushViewController(detailViewController, animated: true) 135 | } 136 | 137 | func sidebarView(_ sidebarView: SidebarView, heightForHeaderIn section: Int) -> CGFloat { 138 | return section == 0 ? 200 : 1 139 | } 140 | 141 | func sidebarView(_ view: SidebarView, heightForItemAt indexPath: IndexPath) -> CGFloat { 142 | 143 | switch indexPath.section { 144 | case 0: 145 | return 80 146 | default: 147 | return 40 148 | } 149 | } 150 | } 151 | 152 | -------------------------------------------------------------------------------- /Example/ModularSidebarView/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // ModularSidebarView 4 | // 5 | // Created by ChrishonWyllie on 12/25/2017. 6 | // Copyright (c) 2017 ChrishonWyllie. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import ModularSidebarView 11 | 12 | class ViewController: UIViewController { 13 | 14 | private let cellReuseIdentifier = "Cell" 15 | private lazy var tableView: UITableView = { 16 | let tbv = UITableView() 17 | tbv.translatesAutoresizingMaskIntoConstraints = false 18 | tbv.register(UITableViewCell.self, forCellReuseIdentifier: cellReuseIdentifier) 19 | tbv.delegate = self 20 | tbv.dataSource = self 21 | return tbv 22 | }() 23 | 24 | let testData: [String] = ["test one", 25 | "test two", 26 | "test three", 27 | "test four", 28 | "test five", 29 | "test six", 30 | "test seven"] 31 | 32 | let sectionOneImageNames: [String] = ["some_image_one", "some_image_two", "some_image_three", "some_image_four", "some_image_five", "", "", ""] 33 | let sectionOneOptionTitles: [String] = ["Home", "Account", "Transactions", "Help", "Some option", "bleh", "bleh", "bleh"] 34 | 35 | let sectionTwoImageNames: [String] = ["some_image_one", "some_image_two"] 36 | let sectionTwoOptionTitles: [String] = ["Settings", "Log out"] 37 | 38 | lazy var sidebarButton: UIBarButtonItem = { 39 | let btn = UIBarButtonItem(title: "Side", style: .done, target: self, action: #selector(openSidebarView(_:))) 40 | return btn 41 | }() 42 | 43 | 44 | private lazy var newControllerButton: UIBarButtonItem = { 45 | let btn = UIBarButtonItem(title: "New", style: .done, target: self, action: #selector(pushTestController(_:))) 46 | return btn 47 | }() 48 | 49 | @objc private func pushTestController(_ sender: Any) { 50 | let navController = UINavigationController(rootViewController: TestController()) 51 | self.present(navController, animated: true, completion: nil) 52 | } 53 | 54 | 55 | // For if you want allowSwipeToDisplay 56 | private lazy var sidebarView: SidebarView = { 57 | let sbv = SidebarView(delegate: self) 58 | sbv.sidebarBackgroundColor = UIColor.groupTableViewBackground 59 | sbv.blurBackgroundEffect = UIBlurEffect(style: UIBlurEffect.Style.dark) 60 | sbv.dismissesOnSelection = true 61 | sbv.allowsPullToDisplay = true 62 | sbv.shouldPushRootControllerOnDisplay = true 63 | sbv.sidebarCornerRadius = 25.0 64 | sbv.sidebarViewScreenPercentageWidth = 0.7 65 | return sbv 66 | }() 67 | 68 | @objc private func openSidebarView(_ sender: Any) { 69 | sidebarView.show() 70 | } 71 | 72 | 73 | 74 | override func viewDidLoad() { 75 | super.viewDidLoad() 76 | // Do any additional setup after loading the view, typically from a nib. 77 | 78 | view.addSubview(tableView) 79 | 80 | tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true 81 | tableView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true 82 | tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true 83 | tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true 84 | 85 | self.navigationItem.leftBarButtonItem = sidebarButton 86 | self.navigationItem.rightBarButtonItem = newControllerButton 87 | 88 | setupSidebarViewItems() 89 | 90 | } 91 | 92 | override func didReceiveMemoryWarning() { 93 | super.didReceiveMemoryWarning() 94 | // Dispose of any resources that can be recreated. 95 | } 96 | 97 | 98 | private func setupSidebarViewItems() { 99 | let sectionOneIndexPaths = Array(0.. SidebarViewCellModel in 101 | return CustomSidebarCellModel(image: nil, title: title) 102 | } 103 | 104 | let sectionTwoIndexPaths = Array(0.. SidebarViewCellModel in 106 | return CustomSidebarCellModel(image: nil, title: title) 107 | } 108 | 109 | let items = (sectionOneItems + sectionTwoItems) 110 | let indexPaths = (sectionOneIndexPaths + sectionTwoIndexPaths) 111 | 112 | sidebarView.insertSidebarView(models: items, atIndexPaths: indexPaths) 113 | 114 | 115 | let reusableSectionItems: [SidebarViewReusableViewSectionModel] = [ 116 | 117 | SidebarViewReusableViewSectionModel(headerViewModel: CustomSidebarSectionHeaderModel(), 118 | footerViewModel: CustomSidebarSectionFooterModel()), 119 | SidebarViewReusableViewSectionModel(headerViewModel: CustomSidebarSectionHeaderModel(), 120 | footerViewModel: CustomSidebarSectionFooterModel()) 121 | ] 122 | 123 | let indices = [0, 1] 124 | 125 | sidebarView.insertReusableView(reusableSectionModels: reusableSectionItems, atIndices: indices) 126 | 127 | } 128 | } 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | // MARK: - UITableViewDelegate and UITableViewDataSource 142 | extension ViewController: UITableViewDelegate, UITableViewDataSource { 143 | 144 | func numberOfSections(in tableView: UITableView) -> Int { 145 | return 1 146 | } 147 | 148 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 149 | return testData.count 150 | } 151 | 152 | func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { 153 | return 240 154 | } 155 | 156 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 157 | 158 | let cell = tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier) 159 | 160 | let someTestString = testData[indexPath.row] 161 | 162 | cell?.textLabel?.text = someTestString 163 | 164 | return cell! 165 | 166 | } 167 | 168 | } 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | // MARK: - SidebarViewDelegate 186 | 187 | extension ViewController: SidebarViewDelegate { 188 | 189 | // Configure SidebarView 190 | 191 | func sidebarView(_ sidebarView: SidebarView, didSelectItemAt indexPath: IndexPath) { 192 | var infoToPass: String 193 | let detailViewController = DetailViewController() 194 | switch indexPath.section { 195 | case 0: 196 | print(sectionOneOptionTitles[indexPath.item]) 197 | infoToPass = sectionOneOptionTitles[indexPath.item] 198 | default: 199 | print(sectionTwoOptionTitles[indexPath.item]) 200 | infoToPass = sectionTwoOptionTitles[indexPath.item] 201 | } 202 | detailViewController.passedInfoString = infoToPass 203 | self.navigationController?.pushViewController(detailViewController, animated: true) 204 | } 205 | 206 | func sidebarView(_ sidebarView: SidebarView, heightForHeaderIn section: Int) -> CGFloat { 207 | return section == 0 ? 200 : 100 208 | } 209 | 210 | func sidebarView(_ sidebarView: SidebarView, heightForFooterIn section: Int) -> CGFloat { 211 | return 200.0 212 | } 213 | 214 | func sidebarView(_ view: SidebarView, heightForItemAt indexPath: IndexPath) -> CGFloat { 215 | 216 | switch indexPath.section { 217 | case 0: 218 | return 80 219 | default: 220 | return 40 221 | } 222 | } 223 | } 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | // MARK: - Test models and SidebarView UI elements 240 | 241 | class CustomSidebarSectionHeaderModel: SidebarViewReusableViewModel { 242 | 243 | init() { 244 | super.init(reusableViewClass: CustomSidebarSectionHeader.self, elementType: .header) 245 | } 246 | } 247 | 248 | class CustomSidebarSectionFooterModel: SidebarViewReusableViewModel { 249 | 250 | init() { 251 | super.init(reusableViewClass: CustomSidebarSectionHeader.self, elementType: .footer) 252 | } 253 | } 254 | 255 | class CustomSidebarSectionHeader: SidebarReusableView { 256 | 257 | override func configure(with item: SidebarViewReusableViewModelProtocol, at indexPath: IndexPath) { 258 | 259 | } 260 | 261 | var customImageView: UIImageView = { 262 | let imageView = UIImageView() 263 | imageView.translatesAutoresizingMaskIntoConstraints = false 264 | imageView.clipsToBounds = true 265 | imageView.layer.borderColor = UIColor.darkGray.cgColor 266 | imageView.contentMode = .scaleAspectFill 267 | imageView.backgroundColor = .black 268 | return imageView 269 | }() 270 | 271 | var customOptionLabel: UILabel = { 272 | let label = UILabel() 273 | label.translatesAutoresizingMaskIntoConstraints = false 274 | label.font = UIFont.boldSystemFont(ofSize: 20) 275 | label.text = "Option" 276 | return label 277 | }() 278 | 279 | override init(frame: CGRect) { 280 | super.init(frame: frame) 281 | 282 | addSubview(customImageView) 283 | addSubview(customOptionLabel) 284 | 285 | self.backgroundColor = [UIColor.red, .orange, .yellow, .green, .blue, .purple].randomElement() 286 | 287 | customImageView.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true 288 | customImageView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 16).isActive = true 289 | customImageView.heightAnchor.constraint(equalToConstant: 40).isActive = true 290 | customImageView.widthAnchor.constraint(equalToConstant: 40).isActive = true 291 | customImageView.layer.cornerRadius = 20 292 | 293 | customOptionLabel.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true 294 | customOptionLabel.leadingAnchor.constraint(equalTo: customImageView.trailingAnchor, constant: 16).isActive = true 295 | 296 | } 297 | 298 | required init?(coder aDecoder: NSCoder) { 299 | fatalError("init(coder:) has not been implemented") 300 | } 301 | } 302 | 303 | class CustomSidebarCellModel: SidebarViewCellModel { 304 | 305 | var image: UIImage? 306 | var title: String 307 | 308 | init(image: UIImage?, title: String) { 309 | self.image = image 310 | self.title = title 311 | super.init(cellClass: CustomSidebarCell.self) 312 | } 313 | } 314 | 315 | 316 | class CustomSidebarCell: SidebarViewCell { 317 | 318 | override func configure(with item: SidebarViewCellModelProtocol, at indexPath: IndexPath) { 319 | super.configure(with: item, at: indexPath) 320 | guard let item = item as? CustomSidebarCellModel else { fatalError() } 321 | 322 | self.customOptionLabel.text = item.title 323 | } 324 | 325 | var customImageView: UIImageView = { 326 | let imageView = UIImageView() 327 | imageView.translatesAutoresizingMaskIntoConstraints = false 328 | imageView.clipsToBounds = true 329 | imageView.layer.borderColor = UIColor.darkGray.cgColor 330 | imageView.contentMode = .scaleAspectFill 331 | imageView.backgroundColor = .red 332 | return imageView 333 | }() 334 | 335 | var customOptionLabel: UILabel = { 336 | let label = UILabel() 337 | label.translatesAutoresizingMaskIntoConstraints = false 338 | label.font = UIFont.boldSystemFont(ofSize: 20) 339 | label.text = "Option" 340 | return label 341 | }() 342 | 343 | override init(frame: CGRect) { 344 | super.init(frame: frame) 345 | 346 | addSubview(customImageView) 347 | addSubview(customOptionLabel) 348 | 349 | self.backgroundColor = UIColor.darkGray// [UIColor.red, .orange, .yellow, .green, .blue, .purple].randomElement() 350 | 351 | customImageView.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true 352 | customImageView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 16).isActive = true 353 | customImageView.heightAnchor.constraint(equalToConstant: 40).isActive = true 354 | customImageView.widthAnchor.constraint(equalToConstant: 40).isActive = true 355 | customImageView.layer.cornerRadius = 20 356 | 357 | customOptionLabel.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true 358 | customOptionLabel.leadingAnchor.constraint(equalTo: customImageView.trailingAnchor, constant: 16).isActive = true 359 | 360 | } 361 | 362 | required init?(coder aDecoder: NSCoder) { 363 | fatalError("init(coder:) has not been implemented") 364 | } 365 | 366 | } 367 | -------------------------------------------------------------------------------- /Example/Podfile: -------------------------------------------------------------------------------- 1 | use_frameworks! 2 | 3 | target 'ModularSidebarView_Example' do 4 | pod 'ModularSidebarView', :path => '../' 5 | 6 | target 'ModularSidebarView_Tests' do 7 | inherit! :search_paths 8 | 9 | 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /Example/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - ModularSidebarView (0.1.0) 3 | 4 | DEPENDENCIES: 5 | - ModularSidebarView (from `../`) 6 | 7 | EXTERNAL SOURCES: 8 | ModularSidebarView: 9 | :path: ../ 10 | 11 | SPEC CHECKSUMS: 12 | ModularSidebarView: 81a813a2101300a0b540762044ba3e5ec3e70edd 13 | 14 | PODFILE CHECKSUM: f202f407263ae7edd5fafb313def6575fc2f568b 15 | 16 | COCOAPODS: 1.3.1 17 | -------------------------------------------------------------------------------- /Example/Pods/Local Podspecs/ModularSidebarView.podspec.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ModularSidebarView", 3 | "version": "0.1.0", 4 | "summary": "A short description of ModularSidebarView.", 5 | "description": "TODO: Add long description of the pod here.", 6 | "homepage": "https://github.com/ChrishonWyllie/ModularSidebarView", 7 | "license": { 8 | "type": "MIT", 9 | "file": "LICENSE" 10 | }, 11 | "authors": { 12 | "ChrishonWyllie": "chrishon595@yahoo.com" 13 | }, 14 | "source": { 15 | "git": "https://github.com/ChrishonWyllie/ModularSidebarView.git", 16 | "tag": "0.1.0" 17 | }, 18 | "platforms": { 19 | "ios": "8.0" 20 | }, 21 | "source_files": "ModularSidebarView/Classes/**/*" 22 | } 23 | -------------------------------------------------------------------------------- /Example/Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - ModularSidebarView (0.1.0) 3 | 4 | DEPENDENCIES: 5 | - ModularSidebarView (from `../`) 6 | 7 | EXTERNAL SOURCES: 8 | ModularSidebarView: 9 | :path: ../ 10 | 11 | SPEC CHECKSUMS: 12 | ModularSidebarView: 81a813a2101300a0b540762044ba3e5ec3e70edd 13 | 14 | PODFILE CHECKSUM: f202f407263ae7edd5fafb313def6575fc2f568b 15 | 16 | COCOAPODS: 1.3.1 17 | -------------------------------------------------------------------------------- /Example/Pods/Pods.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 117A844653C6A25BD6EEC5B6E39C1973 /* Pods-ModularSidebarView_Example-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = EAC449C80070BEE6538C80E8E22FCED0 /* Pods-ModularSidebarView_Example-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; 11 | 39E19789E7D0F5EE65A87725F3164784 /* Pods-ModularSidebarView_Example-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D4A24DD5A51E409CA343F187A7ED817 /* Pods-ModularSidebarView_Example-dummy.m */; }; 12 | 66838FE01FF1E7AE005EF162 /* SidebarViewDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66838FDF1FF1E7AE005EF162 /* SidebarViewDelegate.swift */; }; 13 | 66838FE21FF1E7E9005EF162 /* SidebarCollectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66838FE11FF1E7E9005EF162 /* SidebarCollectionView.swift */; }; 14 | 66838FE41FF1E832005EF162 /* SidebarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66838FE31FF1E832005EF162 /* SidebarView.swift */; }; 15 | 66838FE61FF1E8CD005EF162 /* SidebarHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66838FE51FF1E8CD005EF162 /* SidebarHeaderView.swift */; }; 16 | 66838FE81FF1E8F5005EF162 /* SidebarViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66838FE71FF1E8F5005EF162 /* SidebarViewCell.swift */; }; 17 | 66838FE91FF1F342005EF162 /* SidebarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66838FE31FF1E832005EF162 /* SidebarView.swift */; }; 18 | 669CCC924A4914B5F717B63B7C5E72EB /* ModularSidebarView-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 53227C886BE8B7F3BEE93EA3FF030384 /* ModularSidebarView-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; 19 | 66B96E931FFAA15200A499CB /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66B96E901FFA067E00A499CB /* Extensions.swift */; }; 20 | 66B96E941FFAA15400A499CB /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66B96E901FFA067E00A499CB /* Extensions.swift */; }; 21 | 66B96E951FFAA15B00A499CB /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66B96E901FFA067E00A499CB /* Extensions.swift */; }; 22 | 66C584CA1FF201560081DDA2 /* SidebarViewDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66838FDF1FF1E7AE005EF162 /* SidebarViewDelegate.swift */; }; 23 | 66C584CB1FF201610081DDA2 /* SidebarViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66838FE71FF1E8F5005EF162 /* SidebarViewCell.swift */; }; 24 | 66C584CC1FF201640081DDA2 /* SidebarHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66838FE51FF1E8CD005EF162 /* SidebarHeaderView.swift */; }; 25 | 66C584CD1FF201670081DDA2 /* SidebarCollectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66838FE11FF1E7E9005EF162 /* SidebarCollectionView.swift */; }; 26 | 8115BFE24A04AD62B0E31104FE57BC50 /* ModularSidebarView-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 4418DFFCEA1BF3D4BB61F208C0F8BFC1 /* ModularSidebarView-dummy.m */; }; 27 | 87EE3C32816D24EF13344593913D8094 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6604A7D69453B4569E4E4827FB9155A9 /* Foundation.framework */; }; 28 | A5DB928AEBE7AB5132446671E3811710 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6604A7D69453B4569E4E4827FB9155A9 /* Foundation.framework */; }; 29 | AF7153783A7CF857A90BDB3E99AED132 /* Pods-ModularSidebarView_Tests-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 6235CAC4D0F6064A145A0B1C19C0769E /* Pods-ModularSidebarView_Tests-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; 30 | B368A5130068ECA930B3096C7862DD97 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6604A7D69453B4569E4E4827FB9155A9 /* Foundation.framework */; }; 31 | F44C865920E2A30E22D1B1AD01FF4D27 /* Pods-ModularSidebarView_Tests-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B91ABBA128456B3A095CCBE3B88A28B /* Pods-ModularSidebarView_Tests-dummy.m */; }; 32 | /* End PBXBuildFile section */ 33 | 34 | /* Begin PBXContainerItemProxy section */ 35 | 2BC148EACE1B860C2F87B49EAD464276 /* PBXContainerItemProxy */ = { 36 | isa = PBXContainerItemProxy; 37 | containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; 38 | proxyType = 1; 39 | remoteGlobalIDString = B17F237B497DC20F15330427C8188D42; 40 | remoteInfo = ModularSidebarView; 41 | }; 42 | /* End PBXContainerItemProxy section */ 43 | 44 | /* Begin PBXFileReference section */ 45 | 0930F3BF4B610F32ECDE2279A75191BE /* Pods-ModularSidebarView_Tests-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-ModularSidebarView_Tests-resources.sh"; sourceTree = ""; }; 46 | 187AE1CC22275BD0A4E1449F4AF86018 /* ModularSidebarView.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = ModularSidebarView.xcconfig; sourceTree = ""; }; 47 | 211C74BB5E9B5BFEC5D68A882D02EF2D /* Pods-ModularSidebarView_Tests-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-ModularSidebarView_Tests-frameworks.sh"; sourceTree = ""; }; 48 | 2D7113FB92C751E421C16468C6AA3573 /* Pods-ModularSidebarView_Example-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-ModularSidebarView_Example-resources.sh"; sourceTree = ""; }; 49 | 3B51A7B84243C46CEFE2FFD2F12008E9 /* Pods-ModularSidebarView_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-ModularSidebarView_Example.debug.xcconfig"; sourceTree = ""; }; 50 | 3C9B0C66011F950CFDD13C8A674E65C7 /* Pods-ModularSidebarView_Example-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-ModularSidebarView_Example-frameworks.sh"; sourceTree = ""; }; 51 | 40D7AFA7C17BDADEF4CF6A061E6E52D7 /* Pods-ModularSidebarView_Tests-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-ModularSidebarView_Tests-acknowledgements.markdown"; sourceTree = ""; }; 52 | 4418DFFCEA1BF3D4BB61F208C0F8BFC1 /* ModularSidebarView-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "ModularSidebarView-dummy.m"; sourceTree = ""; }; 53 | 44B3139F18C01983F7D99A6E5B3042F8 /* Pods-ModularSidebarView_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-ModularSidebarView_Example.release.xcconfig"; sourceTree = ""; }; 54 | 4B91ABBA128456B3A095CCBE3B88A28B /* Pods-ModularSidebarView_Tests-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-ModularSidebarView_Tests-dummy.m"; sourceTree = ""; }; 55 | 5000F1CDD7938D3D6EF148DEBF164B09 /* ModularSidebarView.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ModularSidebarView.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 56 | 53227C886BE8B7F3BEE93EA3FF030384 /* ModularSidebarView-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "ModularSidebarView-umbrella.h"; sourceTree = ""; }; 57 | 6235CAC4D0F6064A145A0B1C19C0769E /* Pods-ModularSidebarView_Tests-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-ModularSidebarView_Tests-umbrella.h"; sourceTree = ""; }; 58 | 6604A7D69453B4569E4E4827FB9155A9 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.3.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; 59 | 66838FDF1FF1E7AE005EF162 /* SidebarViewDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarViewDelegate.swift; sourceTree = ""; }; 60 | 66838FE11FF1E7E9005EF162 /* SidebarCollectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarCollectionView.swift; sourceTree = ""; }; 61 | 66838FE31FF1E832005EF162 /* SidebarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarView.swift; sourceTree = ""; }; 62 | 66838FE51FF1E8CD005EF162 /* SidebarHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarHeaderView.swift; sourceTree = ""; }; 63 | 66838FE71FF1E8F5005EF162 /* SidebarViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarViewCell.swift; sourceTree = ""; }; 64 | 66B96E901FFA067E00A499CB /* Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = ""; }; 65 | 69C29727965631CE0BE7C1410FAE3798 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 66 | 72C79CBB89560020C6E260B1B6779B06 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 67 | 7D4A24DD5A51E409CA343F187A7ED817 /* Pods-ModularSidebarView_Example-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-ModularSidebarView_Example-dummy.m"; sourceTree = ""; }; 68 | 8697E312C5E3D38097917AA1074993B2 /* Pods-ModularSidebarView_Example-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-ModularSidebarView_Example-acknowledgements.markdown"; sourceTree = ""; }; 69 | 8CAED5FCB5E66C6DF86A367CDDB52F91 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 70 | 93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 71 | 99402248610FB10B105BA2CCFF856011 /* Pods-ModularSidebarView_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-ModularSidebarView_Tests.debug.xcconfig"; sourceTree = ""; }; 72 | 99DB1993DCB7B0A231916C9974EFDF1E /* ModularSidebarView-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "ModularSidebarView-prefix.pch"; sourceTree = ""; }; 73 | A5188D01E3CC33F9C5B918DCC9AD9C35 /* Pods_ModularSidebarView_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ModularSidebarView_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 74 | A6563862DD70074FCA023B0D11CCC4C1 /* Pods_ModularSidebarView_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ModularSidebarView_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 75 | A6D07454F23D9B6D8B74DC8AEEFC2699 /* Pods-ModularSidebarView_Example.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = "Pods-ModularSidebarView_Example.modulemap"; sourceTree = ""; }; 76 | AD7C2529AFC3DA71E445DE683542EDA7 /* ModularSidebarView.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = ModularSidebarView.modulemap; sourceTree = ""; }; 77 | DA60F435FF276DA96F22ED4FABC7F840 /* Pods-ModularSidebarView_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-ModularSidebarView_Tests.release.xcconfig"; sourceTree = ""; }; 78 | DB75DEE2C2BB6427D876DF2B0A9E2DBC /* Pods-ModularSidebarView_Tests.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = "Pods-ModularSidebarView_Tests.modulemap"; sourceTree = ""; }; 79 | E1BD375B9606DA5E4E5DEFAF422D34D4 /* Pods-ModularSidebarView_Example-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-ModularSidebarView_Example-acknowledgements.plist"; sourceTree = ""; }; 80 | E6C843FCB43D3C9F8DA84C1AE04950F3 /* Pods-ModularSidebarView_Tests-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-ModularSidebarView_Tests-acknowledgements.plist"; sourceTree = ""; }; 81 | EAC449C80070BEE6538C80E8E22FCED0 /* Pods-ModularSidebarView_Example-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-ModularSidebarView_Example-umbrella.h"; sourceTree = ""; }; 82 | /* End PBXFileReference section */ 83 | 84 | /* Begin PBXFrameworksBuildPhase section */ 85 | 2E5E9100EA1352527361142DF20836A8 /* Frameworks */ = { 86 | isa = PBXFrameworksBuildPhase; 87 | buildActionMask = 2147483647; 88 | files = ( 89 | B368A5130068ECA930B3096C7862DD97 /* Foundation.framework in Frameworks */, 90 | ); 91 | runOnlyForDeploymentPostprocessing = 0; 92 | }; 93 | 9C3F7FC51B7F3CEC5879676CE8FB93DA /* Frameworks */ = { 94 | isa = PBXFrameworksBuildPhase; 95 | buildActionMask = 2147483647; 96 | files = ( 97 | 87EE3C32816D24EF13344593913D8094 /* Foundation.framework in Frameworks */, 98 | ); 99 | runOnlyForDeploymentPostprocessing = 0; 100 | }; 101 | FCA33C8C7EC04FC49CC54DED3487FEDA /* Frameworks */ = { 102 | isa = PBXFrameworksBuildPhase; 103 | buildActionMask = 2147483647; 104 | files = ( 105 | A5DB928AEBE7AB5132446671E3811710 /* Foundation.framework in Frameworks */, 106 | ); 107 | runOnlyForDeploymentPostprocessing = 0; 108 | }; 109 | /* End PBXFrameworksBuildPhase section */ 110 | 111 | /* Begin PBXGroup section */ 112 | 21B3E5EBAE6D7B7FC43E3CB11C8B3A2C /* Products */ = { 113 | isa = PBXGroup; 114 | children = ( 115 | 5000F1CDD7938D3D6EF148DEBF164B09 /* ModularSidebarView.framework */, 116 | A5188D01E3CC33F9C5B918DCC9AD9C35 /* Pods_ModularSidebarView_Example.framework */, 117 | A6563862DD70074FCA023B0D11CCC4C1 /* Pods_ModularSidebarView_Tests.framework */, 118 | ); 119 | name = Products; 120 | sourceTree = ""; 121 | }; 122 | 31B86A4AB42B9D6C6CCCA95B9020754C /* Development Pods */ = { 123 | isa = PBXGroup; 124 | children = ( 125 | 966996EAC02C036A3CACD25650E111FC /* ModularSidebarView */, 126 | ); 127 | name = "Development Pods"; 128 | sourceTree = ""; 129 | }; 130 | 66838FDB1FF1E6FE005EF162 /* Classes */ = { 131 | isa = PBXGroup; 132 | children = ( 133 | 66B96E8F1FFA063D00A499CB /* Extensions */, 134 | 66838FDD1FF1E73A005EF162 /* SidebarCollectionView */, 135 | 66838FDC1FF1E732005EF162 /* SidebarView */, 136 | 66838FDE1FF1E746005EF162 /* SidebarViewDelegate */, 137 | ); 138 | path = Classes; 139 | sourceTree = ""; 140 | }; 141 | 66838FDC1FF1E732005EF162 /* SidebarView */ = { 142 | isa = PBXGroup; 143 | children = ( 144 | 66838FE31FF1E832005EF162 /* SidebarView.swift */, 145 | ); 146 | path = SidebarView; 147 | sourceTree = ""; 148 | }; 149 | 66838FDD1FF1E73A005EF162 /* SidebarCollectionView */ = { 150 | isa = PBXGroup; 151 | children = ( 152 | 66838FE11FF1E7E9005EF162 /* SidebarCollectionView.swift */, 153 | 66838FE51FF1E8CD005EF162 /* SidebarHeaderView.swift */, 154 | 66838FE71FF1E8F5005EF162 /* SidebarViewCell.swift */, 155 | ); 156 | path = SidebarCollectionView; 157 | sourceTree = ""; 158 | }; 159 | 66838FDE1FF1E746005EF162 /* SidebarViewDelegate */ = { 160 | isa = PBXGroup; 161 | children = ( 162 | 66838FDF1FF1E7AE005EF162 /* SidebarViewDelegate.swift */, 163 | ); 164 | path = SidebarViewDelegate; 165 | sourceTree = ""; 166 | }; 167 | 66B96E8F1FFA063D00A499CB /* Extensions */ = { 168 | isa = PBXGroup; 169 | children = ( 170 | 66B96E901FFA067E00A499CB /* Extensions.swift */, 171 | ); 172 | path = Extensions; 173 | sourceTree = ""; 174 | }; 175 | 775F17AEEDF64FABCA4360F2FAF68CFE /* Targets Support Files */ = { 176 | isa = PBXGroup; 177 | children = ( 178 | A772A7798EE8CFF5619005EFD11569B7 /* Pods-ModularSidebarView_Example */, 179 | DCBDC3AA0C00914093EDB343519A7E32 /* Pods-ModularSidebarView_Tests */, 180 | ); 181 | name = "Targets Support Files"; 182 | sourceTree = ""; 183 | }; 184 | 7DB346D0F39D3F0E887471402A8071AB = { 185 | isa = PBXGroup; 186 | children = ( 187 | 93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */, 188 | 31B86A4AB42B9D6C6CCCA95B9020754C /* Development Pods */, 189 | BC3CA7F9E30CC8F7E2DD044DD34432FC /* Frameworks */, 190 | 21B3E5EBAE6D7B7FC43E3CB11C8B3A2C /* Products */, 191 | 775F17AEEDF64FABCA4360F2FAF68CFE /* Targets Support Files */, 192 | ); 193 | sourceTree = ""; 194 | }; 195 | 966996EAC02C036A3CACD25650E111FC /* ModularSidebarView */ = { 196 | isa = PBXGroup; 197 | children = ( 198 | 66838FDB1FF1E6FE005EF162 /* Classes */, 199 | D47B072F6AAB1DFD7FA5D80B6FDA2268 /* Support Files */, 200 | ); 201 | name = ModularSidebarView; 202 | path = ../..; 203 | sourceTree = ""; 204 | }; 205 | A772A7798EE8CFF5619005EFD11569B7 /* Pods-ModularSidebarView_Example */ = { 206 | isa = PBXGroup; 207 | children = ( 208 | 8CAED5FCB5E66C6DF86A367CDDB52F91 /* Info.plist */, 209 | A6D07454F23D9B6D8B74DC8AEEFC2699 /* Pods-ModularSidebarView_Example.modulemap */, 210 | 8697E312C5E3D38097917AA1074993B2 /* Pods-ModularSidebarView_Example-acknowledgements.markdown */, 211 | E1BD375B9606DA5E4E5DEFAF422D34D4 /* Pods-ModularSidebarView_Example-acknowledgements.plist */, 212 | 7D4A24DD5A51E409CA343F187A7ED817 /* Pods-ModularSidebarView_Example-dummy.m */, 213 | 3C9B0C66011F950CFDD13C8A674E65C7 /* Pods-ModularSidebarView_Example-frameworks.sh */, 214 | 2D7113FB92C751E421C16468C6AA3573 /* Pods-ModularSidebarView_Example-resources.sh */, 215 | EAC449C80070BEE6538C80E8E22FCED0 /* Pods-ModularSidebarView_Example-umbrella.h */, 216 | 3B51A7B84243C46CEFE2FFD2F12008E9 /* Pods-ModularSidebarView_Example.debug.xcconfig */, 217 | 44B3139F18C01983F7D99A6E5B3042F8 /* Pods-ModularSidebarView_Example.release.xcconfig */, 218 | ); 219 | name = "Pods-ModularSidebarView_Example"; 220 | path = "Target Support Files/Pods-ModularSidebarView_Example"; 221 | sourceTree = ""; 222 | }; 223 | BC3CA7F9E30CC8F7E2DD044DD34432FC /* Frameworks */ = { 224 | isa = PBXGroup; 225 | children = ( 226 | D35AF013A5F0BAD4F32504907A52519E /* iOS */, 227 | ); 228 | name = Frameworks; 229 | sourceTree = ""; 230 | }; 231 | D35AF013A5F0BAD4F32504907A52519E /* iOS */ = { 232 | isa = PBXGroup; 233 | children = ( 234 | 6604A7D69453B4569E4E4827FB9155A9 /* Foundation.framework */, 235 | ); 236 | name = iOS; 237 | sourceTree = ""; 238 | }; 239 | D47B072F6AAB1DFD7FA5D80B6FDA2268 /* Support Files */ = { 240 | isa = PBXGroup; 241 | children = ( 242 | 69C29727965631CE0BE7C1410FAE3798 /* Info.plist */, 243 | AD7C2529AFC3DA71E445DE683542EDA7 /* ModularSidebarView.modulemap */, 244 | 187AE1CC22275BD0A4E1449F4AF86018 /* ModularSidebarView.xcconfig */, 245 | 4418DFFCEA1BF3D4BB61F208C0F8BFC1 /* ModularSidebarView-dummy.m */, 246 | 99DB1993DCB7B0A231916C9974EFDF1E /* ModularSidebarView-prefix.pch */, 247 | 53227C886BE8B7F3BEE93EA3FF030384 /* ModularSidebarView-umbrella.h */, 248 | ); 249 | name = "Support Files"; 250 | path = "Example/Pods/Target Support Files/ModularSidebarView"; 251 | sourceTree = ""; 252 | }; 253 | DCBDC3AA0C00914093EDB343519A7E32 /* Pods-ModularSidebarView_Tests */ = { 254 | isa = PBXGroup; 255 | children = ( 256 | 72C79CBB89560020C6E260B1B6779B06 /* Info.plist */, 257 | DB75DEE2C2BB6427D876DF2B0A9E2DBC /* Pods-ModularSidebarView_Tests.modulemap */, 258 | 40D7AFA7C17BDADEF4CF6A061E6E52D7 /* Pods-ModularSidebarView_Tests-acknowledgements.markdown */, 259 | E6C843FCB43D3C9F8DA84C1AE04950F3 /* Pods-ModularSidebarView_Tests-acknowledgements.plist */, 260 | 4B91ABBA128456B3A095CCBE3B88A28B /* Pods-ModularSidebarView_Tests-dummy.m */, 261 | 211C74BB5E9B5BFEC5D68A882D02EF2D /* Pods-ModularSidebarView_Tests-frameworks.sh */, 262 | 0930F3BF4B610F32ECDE2279A75191BE /* Pods-ModularSidebarView_Tests-resources.sh */, 263 | 6235CAC4D0F6064A145A0B1C19C0769E /* Pods-ModularSidebarView_Tests-umbrella.h */, 264 | 99402248610FB10B105BA2CCFF856011 /* Pods-ModularSidebarView_Tests.debug.xcconfig */, 265 | DA60F435FF276DA96F22ED4FABC7F840 /* Pods-ModularSidebarView_Tests.release.xcconfig */, 266 | ); 267 | name = "Pods-ModularSidebarView_Tests"; 268 | path = "Target Support Files/Pods-ModularSidebarView_Tests"; 269 | sourceTree = ""; 270 | }; 271 | /* End PBXGroup section */ 272 | 273 | /* Begin PBXHeadersBuildPhase section */ 274 | 2CFF1FBBA6BA15E72630F57D3A0CA131 /* Headers */ = { 275 | isa = PBXHeadersBuildPhase; 276 | buildActionMask = 2147483647; 277 | files = ( 278 | 669CCC924A4914B5F717B63B7C5E72EB /* ModularSidebarView-umbrella.h in Headers */, 279 | ); 280 | runOnlyForDeploymentPostprocessing = 0; 281 | }; 282 | 8C5B7F52CC49D097EF41BB9D40FA8E47 /* Headers */ = { 283 | isa = PBXHeadersBuildPhase; 284 | buildActionMask = 2147483647; 285 | files = ( 286 | 117A844653C6A25BD6EEC5B6E39C1973 /* Pods-ModularSidebarView_Example-umbrella.h in Headers */, 287 | ); 288 | runOnlyForDeploymentPostprocessing = 0; 289 | }; 290 | B027F703917E8D23ECE226D8C446A853 /* Headers */ = { 291 | isa = PBXHeadersBuildPhase; 292 | buildActionMask = 2147483647; 293 | files = ( 294 | AF7153783A7CF857A90BDB3E99AED132 /* Pods-ModularSidebarView_Tests-umbrella.h in Headers */, 295 | ); 296 | runOnlyForDeploymentPostprocessing = 0; 297 | }; 298 | /* End PBXHeadersBuildPhase section */ 299 | 300 | /* Begin PBXNativeTarget section */ 301 | 7D640F4A93E0C35A182F3E2DA42BD136 /* Pods-ModularSidebarView_Tests */ = { 302 | isa = PBXNativeTarget; 303 | buildConfigurationList = 777390C0E156B6815BCE470D4EB7EBE6 /* Build configuration list for PBXNativeTarget "Pods-ModularSidebarView_Tests" */; 304 | buildPhases = ( 305 | 85E7A6C51DD8199DAD8E2986C8939CD8 /* Sources */, 306 | FCA33C8C7EC04FC49CC54DED3487FEDA /* Frameworks */, 307 | B027F703917E8D23ECE226D8C446A853 /* Headers */, 308 | ); 309 | buildRules = ( 310 | ); 311 | dependencies = ( 312 | ); 313 | name = "Pods-ModularSidebarView_Tests"; 314 | productName = "Pods-ModularSidebarView_Tests"; 315 | productReference = A6563862DD70074FCA023B0D11CCC4C1 /* Pods_ModularSidebarView_Tests.framework */; 316 | productType = "com.apple.product-type.framework"; 317 | }; 318 | AD280FF64ED3E8163A2BAD7666048E80 /* Pods-ModularSidebarView_Example */ = { 319 | isa = PBXNativeTarget; 320 | buildConfigurationList = B054D93DDAFFC854CA78A069D3278493 /* Build configuration list for PBXNativeTarget "Pods-ModularSidebarView_Example" */; 321 | buildPhases = ( 322 | 6D87CF36843295259495DDCE8EDFBB87 /* Sources */, 323 | 9C3F7FC51B7F3CEC5879676CE8FB93DA /* Frameworks */, 324 | 8C5B7F52CC49D097EF41BB9D40FA8E47 /* Headers */, 325 | ); 326 | buildRules = ( 327 | ); 328 | dependencies = ( 329 | 27A44AD6F1F2CB210811768E2B3B29FD /* PBXTargetDependency */, 330 | ); 331 | name = "Pods-ModularSidebarView_Example"; 332 | productName = "Pods-ModularSidebarView_Example"; 333 | productReference = A5188D01E3CC33F9C5B918DCC9AD9C35 /* Pods_ModularSidebarView_Example.framework */; 334 | productType = "com.apple.product-type.framework"; 335 | }; 336 | B17F237B497DC20F15330427C8188D42 /* ModularSidebarView */ = { 337 | isa = PBXNativeTarget; 338 | buildConfigurationList = F521FF3F8E51BE93E2F4B7968F0BE4B5 /* Build configuration list for PBXNativeTarget "ModularSidebarView" */; 339 | buildPhases = ( 340 | 13B173E7362728C137EBAEA6806EB508 /* Sources */, 341 | 2E5E9100EA1352527361142DF20836A8 /* Frameworks */, 342 | 2CFF1FBBA6BA15E72630F57D3A0CA131 /* Headers */, 343 | ); 344 | buildRules = ( 345 | ); 346 | dependencies = ( 347 | ); 348 | name = ModularSidebarView; 349 | productName = ModularSidebarView; 350 | productReference = 5000F1CDD7938D3D6EF148DEBF164B09 /* ModularSidebarView.framework */; 351 | productType = "com.apple.product-type.framework"; 352 | }; 353 | /* End PBXNativeTarget section */ 354 | 355 | /* Begin PBXProject section */ 356 | D41D8CD98F00B204E9800998ECF8427E /* Project object */ = { 357 | isa = PBXProject; 358 | attributes = { 359 | LastSwiftUpdateCheck = 0830; 360 | LastUpgradeCheck = 1130; 361 | TargetAttributes = { 362 | 7D640F4A93E0C35A182F3E2DA42BD136 = { 363 | LastSwiftMigration = 1130; 364 | }; 365 | AD280FF64ED3E8163A2BAD7666048E80 = { 366 | LastSwiftMigration = 1130; 367 | }; 368 | B17F237B497DC20F15330427C8188D42 = { 369 | LastSwiftMigration = 1130; 370 | }; 371 | }; 372 | }; 373 | buildConfigurationList = 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */; 374 | compatibilityVersion = "Xcode 3.2"; 375 | developmentRegion = en; 376 | hasScannedForEncodings = 0; 377 | knownRegions = ( 378 | en, 379 | Base, 380 | ); 381 | mainGroup = 7DB346D0F39D3F0E887471402A8071AB; 382 | productRefGroup = 21B3E5EBAE6D7B7FC43E3CB11C8B3A2C /* Products */; 383 | projectDirPath = ""; 384 | projectRoot = ""; 385 | targets = ( 386 | B17F237B497DC20F15330427C8188D42 /* ModularSidebarView */, 387 | AD280FF64ED3E8163A2BAD7666048E80 /* Pods-ModularSidebarView_Example */, 388 | 7D640F4A93E0C35A182F3E2DA42BD136 /* Pods-ModularSidebarView_Tests */, 389 | ); 390 | }; 391 | /* End PBXProject section */ 392 | 393 | /* Begin PBXSourcesBuildPhase section */ 394 | 13B173E7362728C137EBAEA6806EB508 /* Sources */ = { 395 | isa = PBXSourcesBuildPhase; 396 | buildActionMask = 2147483647; 397 | files = ( 398 | 66838FE01FF1E7AE005EF162 /* SidebarViewDelegate.swift in Sources */, 399 | 66838FE41FF1E832005EF162 /* SidebarView.swift in Sources */, 400 | 66838FE21FF1E7E9005EF162 /* SidebarCollectionView.swift in Sources */, 401 | 66838FE81FF1E8F5005EF162 /* SidebarViewCell.swift in Sources */, 402 | 66838FE61FF1E8CD005EF162 /* SidebarHeaderView.swift in Sources */, 403 | 8115BFE24A04AD62B0E31104FE57BC50 /* ModularSidebarView-dummy.m in Sources */, 404 | 66B96E951FFAA15B00A499CB /* Extensions.swift in Sources */, 405 | ); 406 | runOnlyForDeploymentPostprocessing = 0; 407 | }; 408 | 6D87CF36843295259495DDCE8EDFBB87 /* Sources */ = { 409 | isa = PBXSourcesBuildPhase; 410 | buildActionMask = 2147483647; 411 | files = ( 412 | 39E19789E7D0F5EE65A87725F3164784 /* Pods-ModularSidebarView_Example-dummy.m in Sources */, 413 | 66C584CD1FF201670081DDA2 /* SidebarCollectionView.swift in Sources */, 414 | 66C584CB1FF201610081DDA2 /* SidebarViewCell.swift in Sources */, 415 | 66C584CA1FF201560081DDA2 /* SidebarViewDelegate.swift in Sources */, 416 | 66C584CC1FF201640081DDA2 /* SidebarHeaderView.swift in Sources */, 417 | 66838FE91FF1F342005EF162 /* SidebarView.swift in Sources */, 418 | 66B96E931FFAA15200A499CB /* Extensions.swift in Sources */, 419 | ); 420 | runOnlyForDeploymentPostprocessing = 0; 421 | }; 422 | 85E7A6C51DD8199DAD8E2986C8939CD8 /* Sources */ = { 423 | isa = PBXSourcesBuildPhase; 424 | buildActionMask = 2147483647; 425 | files = ( 426 | F44C865920E2A30E22D1B1AD01FF4D27 /* Pods-ModularSidebarView_Tests-dummy.m in Sources */, 427 | 66B96E941FFAA15400A499CB /* Extensions.swift in Sources */, 428 | ); 429 | runOnlyForDeploymentPostprocessing = 0; 430 | }; 431 | /* End PBXSourcesBuildPhase section */ 432 | 433 | /* Begin PBXTargetDependency section */ 434 | 27A44AD6F1F2CB210811768E2B3B29FD /* PBXTargetDependency */ = { 435 | isa = PBXTargetDependency; 436 | name = ModularSidebarView; 437 | target = B17F237B497DC20F15330427C8188D42 /* ModularSidebarView */; 438 | targetProxy = 2BC148EACE1B860C2F87B49EAD464276 /* PBXContainerItemProxy */; 439 | }; 440 | /* End PBXTargetDependency section */ 441 | 442 | /* Begin XCBuildConfiguration section */ 443 | 1A62A9B5C9C58E23DFDE292099B44E67 /* Debug */ = { 444 | isa = XCBuildConfiguration; 445 | baseConfigurationReference = 3B51A7B84243C46CEFE2FFD2F12008E9 /* Pods-ModularSidebarView_Example.debug.xcconfig */; 446 | buildSettings = { 447 | CODE_SIGN_IDENTITY = ""; 448 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 449 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 450 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 451 | CURRENT_PROJECT_VERSION = 1; 452 | DEFINES_MODULE = YES; 453 | DYLIB_COMPATIBILITY_VERSION = 1; 454 | DYLIB_CURRENT_VERSION = 1; 455 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 456 | INFOPLIST_FILE = "Target Support Files/Pods-ModularSidebarView_Example/Info.plist"; 457 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 458 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 459 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 460 | MACH_O_TYPE = staticlib; 461 | MODULEMAP_FILE = "Target Support Files/Pods-ModularSidebarView_Example/Pods-ModularSidebarView_Example.modulemap"; 462 | OTHER_LDFLAGS = ""; 463 | OTHER_LIBTOOLFLAGS = ""; 464 | PODS_ROOT = "$(SRCROOT)"; 465 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; 466 | PRODUCT_NAME = Pods_ModularSidebarView_Example; 467 | SDKROOT = iphoneos; 468 | SKIP_INSTALL = YES; 469 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 470 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 471 | SWIFT_VERSION = 5.0; 472 | TARGETED_DEVICE_FAMILY = "1,2"; 473 | VERSIONING_SYSTEM = "apple-generic"; 474 | VERSION_INFO_PREFIX = ""; 475 | }; 476 | name = Debug; 477 | }; 478 | 33DA7F43A1D2FA3C74A8C8FC246E1FA6 /* Debug */ = { 479 | isa = XCBuildConfiguration; 480 | buildSettings = { 481 | ALWAYS_SEARCH_USER_PATHS = NO; 482 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 483 | CLANG_ANALYZER_NONNULL = YES; 484 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 485 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 486 | CLANG_CXX_LIBRARY = "libc++"; 487 | CLANG_ENABLE_MODULES = YES; 488 | CLANG_ENABLE_OBJC_ARC = YES; 489 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 490 | CLANG_WARN_BOOL_CONVERSION = YES; 491 | CLANG_WARN_COMMA = YES; 492 | CLANG_WARN_CONSTANT_CONVERSION = YES; 493 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 494 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 495 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 496 | CLANG_WARN_EMPTY_BODY = YES; 497 | CLANG_WARN_ENUM_CONVERSION = YES; 498 | CLANG_WARN_INFINITE_RECURSION = YES; 499 | CLANG_WARN_INT_CONVERSION = YES; 500 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 501 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 502 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 503 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 504 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 505 | CLANG_WARN_STRICT_PROTOTYPES = YES; 506 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 507 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 508 | CLANG_WARN_UNREACHABLE_CODE = YES; 509 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 510 | CODE_SIGNING_REQUIRED = NO; 511 | COPY_PHASE_STRIP = NO; 512 | DEBUG_INFORMATION_FORMAT = dwarf; 513 | ENABLE_STRICT_OBJC_MSGSEND = YES; 514 | ENABLE_TESTABILITY = YES; 515 | GCC_C_LANGUAGE_STANDARD = gnu11; 516 | GCC_DYNAMIC_NO_PIC = NO; 517 | GCC_NO_COMMON_BLOCKS = YES; 518 | GCC_OPTIMIZATION_LEVEL = 0; 519 | GCC_PREPROCESSOR_DEFINITIONS = ( 520 | "POD_CONFIGURATION_DEBUG=1", 521 | "DEBUG=1", 522 | "$(inherited)", 523 | ); 524 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 525 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 526 | GCC_WARN_UNDECLARED_SELECTOR = YES; 527 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 528 | GCC_WARN_UNUSED_FUNCTION = YES; 529 | GCC_WARN_UNUSED_VARIABLE = YES; 530 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 531 | MTL_ENABLE_DEBUG_INFO = YES; 532 | ONLY_ACTIVE_ARCH = YES; 533 | PRODUCT_NAME = "$(TARGET_NAME)"; 534 | PROVISIONING_PROFILE_SPECIFIER = NO_SIGNING/; 535 | STRIP_INSTALLED_PRODUCT = NO; 536 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 537 | SWIFT_VERSION = 4.0; 538 | SYMROOT = "${SRCROOT}/../build"; 539 | }; 540 | name = Debug; 541 | }; 542 | 731DC216E1A58545B559F6E0A2418060 /* Release */ = { 543 | isa = XCBuildConfiguration; 544 | buildSettings = { 545 | ALWAYS_SEARCH_USER_PATHS = NO; 546 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 547 | CLANG_ANALYZER_NONNULL = YES; 548 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 549 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 550 | CLANG_CXX_LIBRARY = "libc++"; 551 | CLANG_ENABLE_MODULES = YES; 552 | CLANG_ENABLE_OBJC_ARC = YES; 553 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 554 | CLANG_WARN_BOOL_CONVERSION = YES; 555 | CLANG_WARN_COMMA = YES; 556 | CLANG_WARN_CONSTANT_CONVERSION = YES; 557 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 558 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 559 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 560 | CLANG_WARN_EMPTY_BODY = YES; 561 | CLANG_WARN_ENUM_CONVERSION = YES; 562 | CLANG_WARN_INFINITE_RECURSION = YES; 563 | CLANG_WARN_INT_CONVERSION = YES; 564 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 565 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 566 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 567 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 568 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 569 | CLANG_WARN_STRICT_PROTOTYPES = YES; 570 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 571 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 572 | CLANG_WARN_UNREACHABLE_CODE = YES; 573 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 574 | CODE_SIGNING_REQUIRED = NO; 575 | COPY_PHASE_STRIP = NO; 576 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 577 | ENABLE_NS_ASSERTIONS = NO; 578 | ENABLE_STRICT_OBJC_MSGSEND = YES; 579 | GCC_C_LANGUAGE_STANDARD = gnu11; 580 | GCC_NO_COMMON_BLOCKS = YES; 581 | GCC_PREPROCESSOR_DEFINITIONS = ( 582 | "POD_CONFIGURATION_RELEASE=1", 583 | "$(inherited)", 584 | ); 585 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 586 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 587 | GCC_WARN_UNDECLARED_SELECTOR = YES; 588 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 589 | GCC_WARN_UNUSED_FUNCTION = YES; 590 | GCC_WARN_UNUSED_VARIABLE = YES; 591 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 592 | MTL_ENABLE_DEBUG_INFO = NO; 593 | PRODUCT_NAME = "$(TARGET_NAME)"; 594 | PROVISIONING_PROFILE_SPECIFIER = NO_SIGNING/; 595 | STRIP_INSTALLED_PRODUCT = NO; 596 | SWIFT_COMPILATION_MODE = wholemodule; 597 | SWIFT_VERSION = 4.0; 598 | SYMROOT = "${SRCROOT}/../build"; 599 | }; 600 | name = Release; 601 | }; 602 | 7693BB9692A3EACF5937FCB7EE7B833B /* Release */ = { 603 | isa = XCBuildConfiguration; 604 | baseConfigurationReference = 44B3139F18C01983F7D99A6E5B3042F8 /* Pods-ModularSidebarView_Example.release.xcconfig */; 605 | buildSettings = { 606 | CODE_SIGN_IDENTITY = ""; 607 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 608 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 609 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 610 | CURRENT_PROJECT_VERSION = 1; 611 | DEFINES_MODULE = YES; 612 | DYLIB_COMPATIBILITY_VERSION = 1; 613 | DYLIB_CURRENT_VERSION = 1; 614 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 615 | INFOPLIST_FILE = "Target Support Files/Pods-ModularSidebarView_Example/Info.plist"; 616 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 617 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 618 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 619 | MACH_O_TYPE = staticlib; 620 | MODULEMAP_FILE = "Target Support Files/Pods-ModularSidebarView_Example/Pods-ModularSidebarView_Example.modulemap"; 621 | OTHER_LDFLAGS = ""; 622 | OTHER_LIBTOOLFLAGS = ""; 623 | PODS_ROOT = "$(SRCROOT)"; 624 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; 625 | PRODUCT_NAME = Pods_ModularSidebarView_Example; 626 | SDKROOT = iphoneos; 627 | SKIP_INSTALL = YES; 628 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 629 | SWIFT_VERSION = 5.0; 630 | TARGETED_DEVICE_FAMILY = "1,2"; 631 | VALIDATE_PRODUCT = YES; 632 | VERSIONING_SYSTEM = "apple-generic"; 633 | VERSION_INFO_PREFIX = ""; 634 | }; 635 | name = Release; 636 | }; 637 | 9E102AC72208C3DE8E3808527777ED94 /* Debug */ = { 638 | isa = XCBuildConfiguration; 639 | baseConfigurationReference = 187AE1CC22275BD0A4E1449F4AF86018 /* ModularSidebarView.xcconfig */; 640 | buildSettings = { 641 | CLANG_ENABLE_MODULES = YES; 642 | CODE_SIGN_IDENTITY = ""; 643 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 644 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 645 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 646 | CURRENT_PROJECT_VERSION = 1; 647 | DEFINES_MODULE = YES; 648 | DEVELOPMENT_TEAM = ""; 649 | DYLIB_COMPATIBILITY_VERSION = 1; 650 | DYLIB_CURRENT_VERSION = 1; 651 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 652 | GCC_PREFIX_HEADER = "Target Support Files/ModularSidebarView/ModularSidebarView-prefix.pch"; 653 | INFOPLIST_FILE = "Target Support Files/ModularSidebarView/Info.plist"; 654 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 655 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 656 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 657 | MODULEMAP_FILE = "Target Support Files/ModularSidebarView/ModularSidebarView.modulemap"; 658 | PRODUCT_NAME = ModularSidebarView; 659 | SDKROOT = iphoneos; 660 | SKIP_INSTALL = YES; 661 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; 662 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 663 | SWIFT_VERSION = 5.0; 664 | TARGETED_DEVICE_FAMILY = "1,2"; 665 | VERSIONING_SYSTEM = "apple-generic"; 666 | VERSION_INFO_PREFIX = ""; 667 | }; 668 | name = Debug; 669 | }; 670 | A036B3A949FB70D9C4BCF8EBD0484D95 /* Release */ = { 671 | isa = XCBuildConfiguration; 672 | baseConfigurationReference = DA60F435FF276DA96F22ED4FABC7F840 /* Pods-ModularSidebarView_Tests.release.xcconfig */; 673 | buildSettings = { 674 | CODE_SIGN_IDENTITY = ""; 675 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 676 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 677 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 678 | CURRENT_PROJECT_VERSION = 1; 679 | DEFINES_MODULE = YES; 680 | DYLIB_COMPATIBILITY_VERSION = 1; 681 | DYLIB_CURRENT_VERSION = 1; 682 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 683 | INFOPLIST_FILE = "Target Support Files/Pods-ModularSidebarView_Tests/Info.plist"; 684 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 685 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 686 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 687 | MACH_O_TYPE = staticlib; 688 | MODULEMAP_FILE = "Target Support Files/Pods-ModularSidebarView_Tests/Pods-ModularSidebarView_Tests.modulemap"; 689 | OTHER_LDFLAGS = ""; 690 | OTHER_LIBTOOLFLAGS = ""; 691 | PODS_ROOT = "$(SRCROOT)"; 692 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; 693 | PRODUCT_NAME = Pods_ModularSidebarView_Tests; 694 | SDKROOT = iphoneos; 695 | SKIP_INSTALL = YES; 696 | SWIFT_VERSION = 5.0; 697 | TARGETED_DEVICE_FAMILY = "1,2"; 698 | VALIDATE_PRODUCT = YES; 699 | VERSIONING_SYSTEM = "apple-generic"; 700 | VERSION_INFO_PREFIX = ""; 701 | }; 702 | name = Release; 703 | }; 704 | C60FEC7D6321C57D28C7923C1B548F85 /* Debug */ = { 705 | isa = XCBuildConfiguration; 706 | baseConfigurationReference = 99402248610FB10B105BA2CCFF856011 /* Pods-ModularSidebarView_Tests.debug.xcconfig */; 707 | buildSettings = { 708 | CODE_SIGN_IDENTITY = ""; 709 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 710 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 711 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 712 | CURRENT_PROJECT_VERSION = 1; 713 | DEFINES_MODULE = YES; 714 | DYLIB_COMPATIBILITY_VERSION = 1; 715 | DYLIB_CURRENT_VERSION = 1; 716 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 717 | INFOPLIST_FILE = "Target Support Files/Pods-ModularSidebarView_Tests/Info.plist"; 718 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 719 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 720 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 721 | MACH_O_TYPE = staticlib; 722 | MODULEMAP_FILE = "Target Support Files/Pods-ModularSidebarView_Tests/Pods-ModularSidebarView_Tests.modulemap"; 723 | OTHER_LDFLAGS = ""; 724 | OTHER_LIBTOOLFLAGS = ""; 725 | PODS_ROOT = "$(SRCROOT)"; 726 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; 727 | PRODUCT_NAME = Pods_ModularSidebarView_Tests; 728 | SDKROOT = iphoneos; 729 | SKIP_INSTALL = YES; 730 | SWIFT_VERSION = 5.0; 731 | TARGETED_DEVICE_FAMILY = "1,2"; 732 | VERSIONING_SYSTEM = "apple-generic"; 733 | VERSION_INFO_PREFIX = ""; 734 | }; 735 | name = Debug; 736 | }; 737 | D01D9DD26887F2D7B38AD7D6855A0AA8 /* Release */ = { 738 | isa = XCBuildConfiguration; 739 | baseConfigurationReference = 187AE1CC22275BD0A4E1449F4AF86018 /* ModularSidebarView.xcconfig */; 740 | buildSettings = { 741 | CLANG_ENABLE_MODULES = YES; 742 | CODE_SIGN_IDENTITY = ""; 743 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 744 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 745 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 746 | CURRENT_PROJECT_VERSION = 1; 747 | DEFINES_MODULE = YES; 748 | DEVELOPMENT_TEAM = ""; 749 | DYLIB_COMPATIBILITY_VERSION = 1; 750 | DYLIB_CURRENT_VERSION = 1; 751 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 752 | GCC_PREFIX_HEADER = "Target Support Files/ModularSidebarView/ModularSidebarView-prefix.pch"; 753 | INFOPLIST_FILE = "Target Support Files/ModularSidebarView/Info.plist"; 754 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 755 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 756 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 757 | MODULEMAP_FILE = "Target Support Files/ModularSidebarView/ModularSidebarView.modulemap"; 758 | PRODUCT_NAME = ModularSidebarView; 759 | SDKROOT = iphoneos; 760 | SKIP_INSTALL = YES; 761 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; 762 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 763 | SWIFT_VERSION = 5.0; 764 | TARGETED_DEVICE_FAMILY = "1,2"; 765 | VALIDATE_PRODUCT = YES; 766 | VERSIONING_SYSTEM = "apple-generic"; 767 | VERSION_INFO_PREFIX = ""; 768 | }; 769 | name = Release; 770 | }; 771 | /* End XCBuildConfiguration section */ 772 | 773 | /* Begin XCConfigurationList section */ 774 | 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */ = { 775 | isa = XCConfigurationList; 776 | buildConfigurations = ( 777 | 33DA7F43A1D2FA3C74A8C8FC246E1FA6 /* Debug */, 778 | 731DC216E1A58545B559F6E0A2418060 /* Release */, 779 | ); 780 | defaultConfigurationIsVisible = 0; 781 | defaultConfigurationName = Release; 782 | }; 783 | 777390C0E156B6815BCE470D4EB7EBE6 /* Build configuration list for PBXNativeTarget "Pods-ModularSidebarView_Tests" */ = { 784 | isa = XCConfigurationList; 785 | buildConfigurations = ( 786 | C60FEC7D6321C57D28C7923C1B548F85 /* Debug */, 787 | A036B3A949FB70D9C4BCF8EBD0484D95 /* Release */, 788 | ); 789 | defaultConfigurationIsVisible = 0; 790 | defaultConfigurationName = Release; 791 | }; 792 | B054D93DDAFFC854CA78A069D3278493 /* Build configuration list for PBXNativeTarget "Pods-ModularSidebarView_Example" */ = { 793 | isa = XCConfigurationList; 794 | buildConfigurations = ( 795 | 1A62A9B5C9C58E23DFDE292099B44E67 /* Debug */, 796 | 7693BB9692A3EACF5937FCB7EE7B833B /* Release */, 797 | ); 798 | defaultConfigurationIsVisible = 0; 799 | defaultConfigurationName = Release; 800 | }; 801 | F521FF3F8E51BE93E2F4B7968F0BE4B5 /* Build configuration list for PBXNativeTarget "ModularSidebarView" */ = { 802 | isa = XCConfigurationList; 803 | buildConfigurations = ( 804 | 9E102AC72208C3DE8E3808527777ED94 /* Debug */, 805 | D01D9DD26887F2D7B38AD7D6855A0AA8 /* Release */, 806 | ); 807 | defaultConfigurationIsVisible = 0; 808 | defaultConfigurationName = Release; 809 | }; 810 | /* End XCConfigurationList section */ 811 | }; 812 | rootObject = D41D8CD98F00B204E9800998ECF8427E /* Project object */; 813 | } 814 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/ModularSidebarView/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.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/ModularSidebarView/ModularSidebarView-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_ModularSidebarView : NSObject 3 | @end 4 | @implementation PodsDummy_ModularSidebarView 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/ModularSidebarView/ModularSidebarView-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/ModularSidebarView/ModularSidebarView-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 ModularSidebarViewVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char ModularSidebarViewVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/ModularSidebarView/ModularSidebarView.modulemap: -------------------------------------------------------------------------------- 1 | framework module ModularSidebarView { 2 | umbrella header "ModularSidebarView-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/ModularSidebarView/ModularSidebarView.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = $PODS_CONFIGURATION_BUILD_DIR/ModularSidebarView 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public" 4 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 5 | PODS_BUILD_DIR = $BUILD_DIR 6 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_ROOT = ${SRCROOT} 8 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../.. 9 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 10 | SKIP_INSTALL = YES 11 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-ModularSidebarView_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-ModularSidebarView_Example/Pods-ModularSidebarView_Example-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## ModularSidebarView 5 | 6 | Copyright (c) 2017 ChrishonWyllie 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in 16 | all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | THE SOFTWARE. 25 | 26 | Generated by CocoaPods - https://cocoapods.org 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-ModularSidebarView_Example/Pods-ModularSidebarView_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) 2017 ChrishonWyllie <chrishon595@yahoo.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 | ModularSidebarView 41 | Type 42 | PSGroupSpecifier 43 | 44 | 45 | FooterText 46 | Generated by CocoaPods - https://cocoapods.org 47 | Title 48 | 49 | Type 50 | PSGroupSpecifier 51 | 52 | 53 | StringsTable 54 | Acknowledgements 55 | Title 56 | Acknowledgements 57 | 58 | 59 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-ModularSidebarView_Example/Pods-ModularSidebarView_Example-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_ModularSidebarView_Example : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_ModularSidebarView_Example 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-ModularSidebarView_Example/Pods-ModularSidebarView_Example-frameworks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 5 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 6 | 7 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" 8 | 9 | # This protects against multiple targets copying the same framework dependency at the same time. The solution 10 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html 11 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") 12 | 13 | install_framework() 14 | { 15 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then 16 | local source="${BUILT_PRODUCTS_DIR}/$1" 17 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then 18 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" 19 | elif [ -r "$1" ]; then 20 | local source="$1" 21 | fi 22 | 23 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 24 | 25 | if [ -L "${source}" ]; then 26 | echo "Symlinked..." 27 | source="$(readlink "${source}")" 28 | fi 29 | 30 | # Use filter instead of exclude so missing patterns don't throw errors. 31 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" 32 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" 33 | 34 | local basename 35 | basename="$(basename -s .framework "$1")" 36 | binary="${destination}/${basename}.framework/${basename}" 37 | if ! [ -r "$binary" ]; then 38 | binary="${destination}/${basename}" 39 | fi 40 | 41 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 42 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then 43 | strip_invalid_archs "$binary" 44 | fi 45 | 46 | # Resign the code if required by the build settings to avoid unstable apps 47 | code_sign_if_enabled "${destination}/$(basename "$1")" 48 | 49 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. 50 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then 51 | local swift_runtime_libs 52 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) 53 | for lib in $swift_runtime_libs; do 54 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" 55 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" 56 | code_sign_if_enabled "${destination}/${lib}" 57 | done 58 | fi 59 | } 60 | 61 | # Copies the dSYM of a vendored framework 62 | install_dsym() { 63 | local source="$1" 64 | if [ -r "$source" ]; then 65 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DWARF_DSYM_FOLDER_PATH}\"" 66 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DWARF_DSYM_FOLDER_PATH}" 67 | fi 68 | } 69 | 70 | # Signs a framework with the provided identity 71 | code_sign_if_enabled() { 72 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then 73 | # Use the current code_sign_identitiy 74 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" 75 | local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements '$1'" 76 | 77 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 78 | code_sign_cmd="$code_sign_cmd &" 79 | fi 80 | echo "$code_sign_cmd" 81 | eval "$code_sign_cmd" 82 | fi 83 | } 84 | 85 | # Strip invalid architectures 86 | strip_invalid_archs() { 87 | binary="$1" 88 | # Get architectures for current file 89 | archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)" 90 | stripped="" 91 | for arch in $archs; do 92 | if ! [[ "${ARCHS}" == *"$arch"* ]]; then 93 | # Strip non-valid architectures in-place 94 | lipo -remove "$arch" -output "$binary" "$binary" || exit 1 95 | stripped="$stripped $arch" 96 | fi 97 | done 98 | if [[ "$stripped" ]]; then 99 | echo "Stripped $binary of architectures:$stripped" 100 | fi 101 | } 102 | 103 | 104 | if [[ "$CONFIGURATION" == "Debug" ]]; then 105 | install_framework "${BUILT_PRODUCTS_DIR}/ModularSidebarView/ModularSidebarView.framework" 106 | fi 107 | if [[ "$CONFIGURATION" == "Release" ]]; then 108 | install_framework "${BUILT_PRODUCTS_DIR}/ModularSidebarView/ModularSidebarView.framework" 109 | fi 110 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 111 | wait 112 | fi 113 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-ModularSidebarView_Example/Pods-ModularSidebarView_Example-resources.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 5 | 6 | RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt 7 | > "$RESOURCES_TO_COPY" 8 | 9 | XCASSET_FILES=() 10 | 11 | # This protects against multiple targets copying the same framework dependency at the same time. The solution 12 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html 13 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") 14 | 15 | case "${TARGETED_DEVICE_FAMILY}" in 16 | 1,2) 17 | TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" 18 | ;; 19 | 1) 20 | TARGET_DEVICE_ARGS="--target-device iphone" 21 | ;; 22 | 2) 23 | TARGET_DEVICE_ARGS="--target-device ipad" 24 | ;; 25 | 3) 26 | TARGET_DEVICE_ARGS="--target-device tv" 27 | ;; 28 | 4) 29 | TARGET_DEVICE_ARGS="--target-device watch" 30 | ;; 31 | *) 32 | TARGET_DEVICE_ARGS="--target-device mac" 33 | ;; 34 | esac 35 | 36 | install_resource() 37 | { 38 | if [[ "$1" = /* ]] ; then 39 | RESOURCE_PATH="$1" 40 | else 41 | RESOURCE_PATH="${PODS_ROOT}/$1" 42 | fi 43 | if [[ ! -e "$RESOURCE_PATH" ]] ; then 44 | cat << EOM 45 | error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. 46 | EOM 47 | exit 1 48 | fi 49 | case $RESOURCE_PATH in 50 | *.storyboard) 51 | 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 52 | 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} 53 | ;; 54 | *.xib) 55 | 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 56 | 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} 57 | ;; 58 | *.framework) 59 | echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true 60 | mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 61 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true 62 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 63 | ;; 64 | *.xcdatamodel) 65 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" || true 66 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" 67 | ;; 68 | *.xcdatamodeld) 69 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" || true 70 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" 71 | ;; 72 | *.xcmappingmodel) 73 | echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" || true 74 | xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" 75 | ;; 76 | *.xcassets) 77 | ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH" 78 | XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") 79 | ;; 80 | *) 81 | echo "$RESOURCE_PATH" || true 82 | echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" 83 | ;; 84 | esac 85 | } 86 | 87 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 88 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 89 | if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then 90 | mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 91 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 92 | fi 93 | rm -f "$RESOURCES_TO_COPY" 94 | 95 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ] 96 | then 97 | # Find all other xcassets (this unfortunately includes those of path pods and other targets). 98 | OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) 99 | while read line; do 100 | if [[ $line != "${PODS_ROOT}*" ]]; then 101 | XCASSET_FILES+=("$line") 102 | fi 103 | done <<<"$OTHER_XCASSETS" 104 | 105 | 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}" 106 | fi 107 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-ModularSidebarView_Example/Pods-ModularSidebarView_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_ModularSidebarView_ExampleVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_ModularSidebarView_ExampleVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-ModularSidebarView_Example/Pods-ModularSidebarView_Example.debug.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/ModularSidebarView" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 5 | OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/ModularSidebarView/ModularSidebarView.framework/Headers" 6 | OTHER_LDFLAGS = $(inherited) -framework "ModularSidebarView" 7 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 8 | PODS_BUILD_DIR = $BUILD_DIR 9 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 11 | PODS_ROOT = ${SRCROOT}/Pods 12 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-ModularSidebarView_Example/Pods-ModularSidebarView_Example.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_ModularSidebarView_Example { 2 | umbrella header "Pods-ModularSidebarView_Example-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-ModularSidebarView_Example/Pods-ModularSidebarView_Example.release.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/ModularSidebarView" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 5 | OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/ModularSidebarView/ModularSidebarView.framework/Headers" 6 | OTHER_LDFLAGS = $(inherited) -framework "ModularSidebarView" 7 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 8 | PODS_BUILD_DIR = $BUILD_DIR 9 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 11 | PODS_ROOT = ${SRCROOT}/Pods 12 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-ModularSidebarView_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-ModularSidebarView_Tests/Pods-ModularSidebarView_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-ModularSidebarView_Tests/Pods-ModularSidebarView_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-ModularSidebarView_Tests/Pods-ModularSidebarView_Tests-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_ModularSidebarView_Tests : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_ModularSidebarView_Tests 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-ModularSidebarView_Tests/Pods-ModularSidebarView_Tests-frameworks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 5 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 6 | 7 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" 8 | 9 | # This protects against multiple targets copying the same framework dependency at the same time. The solution 10 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html 11 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") 12 | 13 | install_framework() 14 | { 15 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then 16 | local source="${BUILT_PRODUCTS_DIR}/$1" 17 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then 18 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" 19 | elif [ -r "$1" ]; then 20 | local source="$1" 21 | fi 22 | 23 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 24 | 25 | if [ -L "${source}" ]; then 26 | echo "Symlinked..." 27 | source="$(readlink "${source}")" 28 | fi 29 | 30 | # Use filter instead of exclude so missing patterns don't throw errors. 31 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" 32 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" 33 | 34 | local basename 35 | basename="$(basename -s .framework "$1")" 36 | binary="${destination}/${basename}.framework/${basename}" 37 | if ! [ -r "$binary" ]; then 38 | binary="${destination}/${basename}" 39 | fi 40 | 41 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 42 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then 43 | strip_invalid_archs "$binary" 44 | fi 45 | 46 | # Resign the code if required by the build settings to avoid unstable apps 47 | code_sign_if_enabled "${destination}/$(basename "$1")" 48 | 49 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. 50 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then 51 | local swift_runtime_libs 52 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) 53 | for lib in $swift_runtime_libs; do 54 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" 55 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" 56 | code_sign_if_enabled "${destination}/${lib}" 57 | done 58 | fi 59 | } 60 | 61 | # Copies the dSYM of a vendored framework 62 | install_dsym() { 63 | local source="$1" 64 | if [ -r "$source" ]; then 65 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DWARF_DSYM_FOLDER_PATH}\"" 66 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DWARF_DSYM_FOLDER_PATH}" 67 | fi 68 | } 69 | 70 | # Signs a framework with the provided identity 71 | code_sign_if_enabled() { 72 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then 73 | # Use the current code_sign_identitiy 74 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" 75 | local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements '$1'" 76 | 77 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 78 | code_sign_cmd="$code_sign_cmd &" 79 | fi 80 | echo "$code_sign_cmd" 81 | eval "$code_sign_cmd" 82 | fi 83 | } 84 | 85 | # Strip invalid architectures 86 | strip_invalid_archs() { 87 | binary="$1" 88 | # Get architectures for current file 89 | archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)" 90 | stripped="" 91 | for arch in $archs; do 92 | if ! [[ "${ARCHS}" == *"$arch"* ]]; then 93 | # Strip non-valid architectures in-place 94 | lipo -remove "$arch" -output "$binary" "$binary" || exit 1 95 | stripped="$stripped $arch" 96 | fi 97 | done 98 | if [[ "$stripped" ]]; then 99 | echo "Stripped $binary of architectures:$stripped" 100 | fi 101 | } 102 | 103 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 104 | wait 105 | fi 106 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-ModularSidebarView_Tests/Pods-ModularSidebarView_Tests-resources.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 5 | 6 | RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt 7 | > "$RESOURCES_TO_COPY" 8 | 9 | XCASSET_FILES=() 10 | 11 | # This protects against multiple targets copying the same framework dependency at the same time. The solution 12 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html 13 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") 14 | 15 | case "${TARGETED_DEVICE_FAMILY}" in 16 | 1,2) 17 | TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" 18 | ;; 19 | 1) 20 | TARGET_DEVICE_ARGS="--target-device iphone" 21 | ;; 22 | 2) 23 | TARGET_DEVICE_ARGS="--target-device ipad" 24 | ;; 25 | 3) 26 | TARGET_DEVICE_ARGS="--target-device tv" 27 | ;; 28 | 4) 29 | TARGET_DEVICE_ARGS="--target-device watch" 30 | ;; 31 | *) 32 | TARGET_DEVICE_ARGS="--target-device mac" 33 | ;; 34 | esac 35 | 36 | install_resource() 37 | { 38 | if [[ "$1" = /* ]] ; then 39 | RESOURCE_PATH="$1" 40 | else 41 | RESOURCE_PATH="${PODS_ROOT}/$1" 42 | fi 43 | if [[ ! -e "$RESOURCE_PATH" ]] ; then 44 | cat << EOM 45 | error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. 46 | EOM 47 | exit 1 48 | fi 49 | case $RESOURCE_PATH in 50 | *.storyboard) 51 | 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 52 | 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} 53 | ;; 54 | *.xib) 55 | 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 56 | 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} 57 | ;; 58 | *.framework) 59 | echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true 60 | mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 61 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true 62 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 63 | ;; 64 | *.xcdatamodel) 65 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" || true 66 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" 67 | ;; 68 | *.xcdatamodeld) 69 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" || true 70 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" 71 | ;; 72 | *.xcmappingmodel) 73 | echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" || true 74 | xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" 75 | ;; 76 | *.xcassets) 77 | ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH" 78 | XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") 79 | ;; 80 | *) 81 | echo "$RESOURCE_PATH" || true 82 | echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" 83 | ;; 84 | esac 85 | } 86 | 87 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 88 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 89 | if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then 90 | mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 91 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 92 | fi 93 | rm -f "$RESOURCES_TO_COPY" 94 | 95 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ] 96 | then 97 | # Find all other xcassets (this unfortunately includes those of path pods and other targets). 98 | OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) 99 | while read line; do 100 | if [[ $line != "${PODS_ROOT}*" ]]; then 101 | XCASSET_FILES+=("$line") 102 | fi 103 | done <<<"$OTHER_XCASSETS" 104 | 105 | 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}" 106 | fi 107 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-ModularSidebarView_Tests/Pods-ModularSidebarView_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_ModularSidebarView_TestsVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_ModularSidebarView_TestsVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-ModularSidebarView_Tests/Pods-ModularSidebarView_Tests.debug.xcconfig: -------------------------------------------------------------------------------- 1 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/ModularSidebarView" 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 4 | OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/ModularSidebarView/ModularSidebarView.framework/Headers" 5 | PODS_BUILD_DIR = $BUILD_DIR 6 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 8 | PODS_ROOT = ${SRCROOT}/Pods 9 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-ModularSidebarView_Tests/Pods-ModularSidebarView_Tests.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_ModularSidebarView_Tests { 2 | umbrella header "Pods-ModularSidebarView_Tests-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-ModularSidebarView_Tests/Pods-ModularSidebarView_Tests.release.xcconfig: -------------------------------------------------------------------------------- 1 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/ModularSidebarView" 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 4 | OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/ModularSidebarView/ModularSidebarView.framework/Headers" 5 | PODS_BUILD_DIR = $BUILD_DIR 6 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 8 | PODS_ROOT = ${SRCROOT}/Pods 9 | -------------------------------------------------------------------------------- /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 UIKit 2 | import XCTest 3 | import ModularSidebarView 4 | 5 | class Tests: XCTestCase { 6 | 7 | override func setUp() { 8 | super.setUp() 9 | // Put setup code here. This method is called before the invocation of each test method in the class. 10 | } 11 | 12 | override func tearDown() { 13 | // Put teardown code here. This method is called after the invocation of each test method in the class. 14 | super.tearDown() 15 | } 16 | 17 | func testExample() { 18 | // This is an example of a functional test case. 19 | XCTAssert(true, "Pass") 20 | } 21 | 22 | func testPerformanceExample() { 23 | // This is an example of a performance test case. 24 | self.measure() { 25 | // Put the code you want to measure the time of here. 26 | } 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /Github Images/ModularSidebarView-home-screen_iphonexspacegrey_portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChrishonWyllie/ModularSidebarView/15e4bd113c6f14bd758fd0b6f94bf58f9fd1a3da/Github Images/ModularSidebarView-home-screen_iphonexspacegrey_portrait.png -------------------------------------------------------------------------------- /Github Images/ModularSidebarView-sidebarview-screen_iphonexspacegrey_portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChrishonWyllie/ModularSidebarView/15e4bd113c6f14bd758fd0b6f94bf58f9fd1a3da/Github Images/ModularSidebarView-sidebarview-screen_iphonexspacegrey_portrait.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017 ChrishonWyllie 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 | -------------------------------------------------------------------------------- /ModularSidebarView.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod lib lint ModularSidebarView.podspec' to ensure this is a 3 | # valid spec before submitting. 4 | # 5 | # Any lines starting with a # are optional, but their use is encouraged 6 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | s.name = 'ModularSidebarView' 11 | s.version = '1.0.0' 12 | s.summary = 'A customizable side bar view.' 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 | A customizable menu for displaying options on the side of the screen. This can substitute the usual navigation bar items and tool bar items. 22 | DESC 23 | 24 | s.homepage = 'https://github.com/ChrishonWyllie/ModularSidebarView' 25 | # s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2' 26 | s.license = { :type => 'MIT', :file => 'LICENSE' } 27 | s.author = { 'ChrishonWyllie' => 'chrishon595@yahoo.com' } 28 | s.source = { :git => 'https://github.com/ChrishonWyllie/ModularSidebarView.git', :tag => s.version.to_s } 29 | # s.social_media_url = 'https://twitter.com/' 30 | s.swift_versions = ['4.0', '4.1', '4.2', '5.0', '5.1'] 31 | 32 | s.ios.deployment_target = '12.0' 33 | 34 | s.source_files = 'Classes/**/*' 35 | 36 | # s.resource_bundles = { 37 | # 'ModularSidebarView' => ['ModularSidebarView/Assets/*.png'] 38 | # } 39 | 40 | # s.public_header_files = 'Pod/Classes/**/*.h' 41 | s.frameworks = 'UIKit' 42 | # s.dependency 'AFNetworking', '~> 2.3' 43 | end 44 | -------------------------------------------------------------------------------- /ModularSidebarView/Assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChrishonWyllie/ModularSidebarView/15e4bd113c6f14bd758fd0b6f94bf58f9fd1a3da/ModularSidebarView/Assets/.gitkeep -------------------------------------------------------------------------------- /ModularSidebarView/Classes/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChrishonWyllie/ModularSidebarView/15e4bd113c6f14bd758fd0b6f94bf58f9fd1a3da/ModularSidebarView/Classes/.gitkeep -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ModularSidebarView 2 | 3 | [![CI Status](http://img.shields.io/travis/ChrishonWyllie/ModularSidebarView.svg?style=flat)](https://travis-ci.org/ChrishonWyllie/ModularSidebarView) 4 | [![Version](https://img.shields.io/cocoapods/v/ModularSidebarView.svg?style=flat)](http://cocoapods.org/pods/ModularSidebarView) 5 | [![License](https://img.shields.io/cocoapods/l/ModularSidebarView.svg?style=flat)](http://cocoapods.org/pods/ModularSidebarView) 6 | [![Platform](https://img.shields.io/cocoapods/p/ModularSidebarView.svg?style=flat)](http://cocoapods.org/pods/ModularSidebarView) 7 | 8 |

9 | ModularSidebarView is a customizable menu for displaying options on the side of the screen for iOS. It is meant to act as a substitute to the usual UINavigation bar items and tool bar items. 10 |

11 | 12 |
13 |
14 |
15 | 16 | 17 |
18 | 19 | ## Usage 20 | 21 | 22 |

Displaying the SidebarView

23 | 24 |

First, initialize the SideBarView

25 | 26 | ```swift 27 | private lazy var sidebarView: SidebarView = { 28 | let sbv = SidebarView(delegate: self) 29 | // Make desired configurations 30 | return sbv 31 | }() 32 | ``` 33 | 34 |
35 |
36 | 37 | 38 | 39 |

Then create some sort of UIButton, UIBarButtonItem or any view with userInteraction enabled. Create the selector and function however you choose.

40 | 41 | ```swift 42 | // It is NOT required to a use a UIBarButtonItem to display the SidebarView. 43 | // Provide your own implementation for triggering the SidebarView to show. 44 | private lazy var sidebarButton: UIBarButtonItem = { 45 | let btn = UIBarButtonItem(title: "Sidebar", 46 | style: .done, 47 | target: self, 48 | action: #selector(openSidebarView(_:))) 49 | return btn 50 | }() 51 | 52 | // Here, we call the "showSidebarView()" function to display the SidebarView 53 | @objc private func openSidebarView(_ sender: Any) { 54 | sidebarView.show() 55 | } 56 | 57 | override func viewDidLoad() { 58 | super.viewDidLoad() 59 | // Do any additional setup after loading the view, typically from a nib. 60 | 61 | // ... Other UI setup 62 | 63 | // Place the sidebarButton in the navigationBar if desired. 64 | self.navigationItem.leftBarButtonItem = sidebarButton 65 | } 66 | ``` 67 | 68 | 69 |

Dismissing the SidebarView

70 | 71 | ```swift 72 | 73 | private func dismissSidebarView() { 74 | sidebarView.dismiss() 75 | } 76 | 77 | ``` 78 |
    79 |
  • Simply tap the background view

  • 80 |
  • Or pressing one of the options in the SidebarView will also dismiss on selection if dismissesOnSelection set to TRUE

  • 81 |
82 | 83 | 84 | 85 | 86 | ## Adding items to the SidebarView 87 |

The SidebarView uses a View-Model approach to laying out items.

88 |

You may subclass the default provided classes or conform to the underlying protocol for more customization

89 | 90 | ### Step 1: Creating View-Models 91 | #### Subclassing the `SidebarViewCellModel`, `SidebarViewReusableViewSectionModel` and `SidebarViewReusableViewModel` 92 | 93 | ```swift 94 | 95 | // SidebarViewCellModel is the View-Model that represents a SidebarView cell 96 | // CustomSidebarCellModel is a custom subclass. You may provide your own subclass 97 | class CustomSidebarCellModel: SidebarViewCellModel { 98 | 99 | var image: UIImage? 100 | var title: String 101 | 102 | init(image: UIImage?, title: String) { 103 | self.image = image 104 | self.title = title 105 | 106 | // This is very imporant. Provide the cell class you wish for this model to display 107 | // This must be a UICollectionViewCell 108 | super.init(cellClass: CustomSidebarCell.self) 109 | } 110 | } 111 | ``` 112 | ```swift 113 | 114 | // At heart, SidebarView is a UICollectionView. 115 | // As such, may render both a header and footer supplementaryView for each section. 116 | // The SidebarViewReusableViewSectionModel provides a container for both the header and footer in each section. 117 | 118 | SidebarViewReusableViewSectionModel(headerViewModel: SidebarViewReusableViewModelProtocol?, footerViewModel: SidebarViewReusableViewModelProtocol?) 119 | 120 | // You create your own header and footer supplementary view-models that conform to SidebarViewReusableViewModelProtocol or subclass the default SidebarViewReusableViewModel: 121 | 122 | class CustomHeaderModel: SidebarViewReusableViewModel { 123 | 124 | init() { 125 | super.init(reusableViewClass: CustomSidebarSectionHeader.self, elementType: .header) 126 | } 127 | } 128 | 129 | class CustomFooterModel: SidebarViewReusableViewModel { 130 | 131 | init() { 132 | super.init(reusableViewClass: CustomSidebarSectionHeader.self, elementType: .footer) 133 | } 134 | } 135 | ``` 136 | 137 | ### Step 2: Creating Views (Cells and ReusableViews) 138 | #### Subclassing the `SidebarViewCell` and `SidebarReusableView` 139 | 140 | ```swift 141 | 142 | class CustomSidebarCell: SidebarViewCell { 143 | 144 | // Important to override this function to configure the cells as desired 145 | override func configure(with item: SidebarViewCellModelProtocol, at indexPath: IndexPath) { 146 | super.configure(with: item, at: indexPath) 147 | guard let customViewModel = item as? CustomSidebarCellModel else { 148 | return 149 | } 150 | 151 | // configure the cell with your custom View-Model data 152 | self.imageView.image = customViewModel.image 153 | 154 | self.titleLabel.text = customViewModel.title 155 | } 156 | } 157 | 158 | class CustomSidebarSectionHeader: SidebarReusableView { 159 | 160 | // Important to override this function to configure the view as desired 161 | override func configure(with item: SidebarViewReusableViewModelProtocol, at indexPath: IndexPath) { 162 | super.configure(with: item, at: indexPath) 163 | guard let customViewModel = item as? CustomHeaderModel else { 164 | return 165 | } 166 | 167 | // configure the cell with your custom header View-Model data 168 | 169 | } 170 | } 171 | 172 | ``` 173 | 174 | ### Step 3: Inserting the View-Models into the SidebarView 175 | #### Use these two functions to insert Cell and ReusableView View-Models at desired indexPaths 176 | 177 | ```swift 178 | 179 | func insertSidebarView(models: [SidebarViewCellModelProtocol], atIndexPaths indexPaths: [IndexPath]) 180 | 181 | func insertReusableView(reusableSectionModels: [SidebarViewReusableViewSectionProtocol], atIndices indices: [Int]) 182 | ``` 183 | 184 |

Example

185 | 186 | ```swift 187 | override func viewDidLoad() { 188 | super.viewDidLoad() 189 | // Do any additional setup after loading the view, typically from a nib. 190 | 191 | setupSidebarViewItems() 192 | 193 | } 194 | 195 | private func setupSidebarViewItems() { 196 | 197 | // Create Cell View-Models 198 | 199 | let sectionOneIndexPaths: [IndexPath = // ... Construct array of IndexPaths for section 0 200 | let sectionOneItems: [SidebarViewCellModelProtocol] = // ... Construct array of View-Models for section 0 201 | 202 | let sectionTwoIndexPaths: [IndexPath = // ... Construct array of IndexPaths for section 1 203 | let sectionTwoItems: [SidebarViewCellModelProtocol] = // ... Construct array of View-Models for section 1 204 | 205 | let completeListOfItems: [SidebarViewCellModelProtocol] = (sectionOneItems + sectionTwoItems) 206 | let completeListOfIndexPaths = (sectionOneIndexPaths + sectionTwoIndexPaths) 207 | 208 | sidebarView.insertSidebarView(models: completeListOfItems, atIndexPaths: completeListOfIndexPaths) 209 | 210 | 211 | 212 | 213 | // Create ReusableView View-Models 214 | 215 | let reusableSectionItems: [SidebarViewReusableViewSectionModel] = // ... Construct array of ReusableView Section View-Models 216 | let sectionIndices: [Int] = // ... Construct of section indices (positive integers) 217 | 218 | sidebarView.insertReusableView(reusableSectionModels: reusableSectionItems, atIndices: sectionIndices) 219 | 220 | } 221 | 222 | ``` 223 | 224 | 225 |
226 | 227 |

Extending the SidebarViewDelegate

228 | 229 |

You may extend the class:

230 | 231 | ```swift 232 | class ViewController: SidebarViewDelegate { 233 | 234 | func sidebarView(_ sidebarView: SidebarView, didSelectItemAt indexPath: IndexPath) { 235 | 236 | // Provide custom action/functionality when tapping a SidebarView cell at each indexPath 237 | 238 | } 239 | 240 | func sidebarView(_ sidebarView: SidebarView, heightForHeaderIn section: Int) -> CGFloat { 241 | 242 | // Provide height for supplementary header reusableView at each section 243 | 244 | } 245 | 246 | func sidebarView(_ sidebarView: SidebarView, heightForFooterIn section: Int) -> CGFloat { 247 | 248 | // Provide height for supplementary footer reusableView at each section 249 | 250 | } 251 | 252 | func sidebarView(_ view: SidebarView, heightForItemAt indexPath: IndexPath) -> CGFloat { 253 | 254 | // Provide heights for items at each IndexPath 255 | 256 | } 257 | } 258 | ``` 259 | 260 | 261 | 262 | 263 | 264 | ## Example 265 | 266 | To run the example project, clone the repo, and run `pod install` from the Example directory first. 267 | 268 | ## Requirements 269 | 270 | ## Installation 271 | 272 | ModularSidebarView is available through [CocoaPods](http://cocoapods.org). To install 273 | it, simply add the following line to your Podfile: 274 | 275 | ```ruby 276 | pod 'ModularSidebarView' 277 | ``` 278 | 279 | ## Author 280 | 281 | ChrishonWyllie, chrishon595@yahoo.com 282 | 283 | ## License 284 | 285 | ModularSidebarView is available under the MIT license. See the LICENSE file for more info. 286 | 287 | -------------------------------------------------------------------------------- /_Pods.xcodeproj: -------------------------------------------------------------------------------- 1 | Example/Pods/Pods.xcodeproj --------------------------------------------------------------------------------