├── .swift-version ├── LICENSE ├── README.md ├── SwiftMultiSelect.podspec ├── SwiftMultiSelect ├── 0.1.0 │ └── SwiftMultiSelect.podspec ├── 0.1.3 │ └── SwiftMultiSelect.podspec ├── 0.1.5 │ └── SwiftMultiSelect.podspec ├── 0.1.6 │ └── SwiftMultiSelect.podspec ├── 0.2.1 │ └── SwiftMultiSelect.podspec ├── 0.2.2 │ └── SwiftMultiSelect.podspec ├── 0.2.3 │ └── SwiftMultiSelect.podspec ├── Assets │ └── Assets.xcassets │ │ ├── Contents.json │ │ ├── remove.imageset │ │ ├── Contents.json │ │ ├── remove.png │ │ ├── remove@2x.png │ │ └── remove@3x.png │ │ └── user_blank.imageset │ │ ├── Contents.json │ │ ├── user_blank.png │ │ └── user_blank@2x.png ├── ContactsLibrary.swift ├── CustomCollectionCell.swift ├── CustomTableCell.swift ├── Info.plist ├── MultiSelectionCollectionView.swift ├── MultiSelectionTableView.swift ├── MultiSelectionViewController.swift ├── SwiftMultiSelect.h └── SwiftMultiSelect.swift └── SwiftMultiSelectExample ├── Podfile ├── Podfile.lock ├── Pods ├── Local Podspecs │ └── SwiftMultiSelect.podspec.json ├── Manifest.lock ├── Pods.xcodeproj │ ├── project.pbxproj │ └── xcuserdata │ │ └── frind.xcuserdatad │ │ └── xcschemes │ │ ├── Pods-SwiftMultiSelectExample.xcscheme │ │ ├── SwiftMultiSelect.xcscheme │ │ └── xcschememanagement.plist └── Target Support Files │ ├── Pods-SwiftMultiSelectExample │ ├── Info.plist │ ├── Pods-SwiftMultiSelectExample-acknowledgements.markdown │ ├── Pods-SwiftMultiSelectExample-acknowledgements.plist │ ├── Pods-SwiftMultiSelectExample-dummy.m │ ├── Pods-SwiftMultiSelectExample-frameworks.sh │ ├── Pods-SwiftMultiSelectExample-resources.sh │ ├── Pods-SwiftMultiSelectExample-umbrella.h │ ├── Pods-SwiftMultiSelectExample.debug.xcconfig │ ├── Pods-SwiftMultiSelectExample.modulemap │ └── Pods-SwiftMultiSelectExample.release.xcconfig │ └── SwiftMultiSelect │ ├── Info.plist │ ├── SwiftMultiSelect-dummy.m │ ├── SwiftMultiSelect-prefix.pch │ ├── SwiftMultiSelect-umbrella.h │ ├── SwiftMultiSelect.modulemap │ └── SwiftMultiSelect.xcconfig ├── SwiftMultiSelectExample.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── frind.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── frind.xcuserdatad │ └── xcschemes │ ├── SwiftMultiSelectExample.xcscheme │ └── xcschememanagement.plist ├── SwiftMultiSelectExample.xcworkspace ├── contents.xcworkspacedata └── xcuserdata │ └── frind.xcuserdatad │ └── UserInterfaceState.xcuserstate └── SwiftMultiSelectExample ├── AppDelegate.swift ├── Assets.xcassets ├── AppIcon.appiconset │ ├── Contents.json │ ├── iPhone_App_iOS7-10_60pt@2x.png │ ├── iPhone_App_iOS7-10_60pt@3x.png │ ├── iPhone_Notifications_iOS7-10_20pt@2x.png │ ├── iPhone_Notifications_iOS7-10_20pt@3x.png │ ├── iPhone_Settings_iOS5-10_29pt@2x.png │ ├── iPhone_Settings_iOS5-10_29pt@3x.png │ ├── iPhone_Spotlight_iOS7-10_40pt@2x.png │ └── iPhone_Spotlight_iOS7-10_40pt@3x.png └── logo.imageset │ ├── Contents.json │ ├── logomulti-1.png │ ├── logomulti-2.png │ └── logomulti.png ├── Base.lproj ├── LaunchScreen.storyboard └── Main.storyboard ├── Info.plist └── ViewController.swift /.swift-version: -------------------------------------------------------------------------------- 1 | 3.0 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Luca Becchetti 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SwiftMultiSelect - A tableview with graphical multi selection (contacts from PhoneBook or items from custom lists) 2 |

3 | SwiftMultiSelect 4 |

5 | 6 | [![Version](https://img.shields.io/badge/pod-0.2.4-blue.svg)](https://cocoapods.org/pods/InAppNotify) [![License](https://img.shields.io/github/license/mashape/apistatus.svg)](https://cocoapods.org/pods/InAppNotify) [![Platform](https://img.shields.io/badge/platform-ios-lightgrey.svg)](https://cocoapods.org/pods/InAppNotify) [![Swift3](https://img.shields.io/badge/swift3-compatible-brightgreen.svg)](https://cocoapods.org/pods/InAppNotify) 7 | 8 | During develop of my apps, i usually needed to select more than one element from a tableview, but i don't like the native ios integration, i think is not graphically clear, so, i created this library. Choose SwiftMultiSelect for your next project, I'll be happy to give you a little help! 9 | 10 |

★★ Star our github repository to help us!, or ☕ pay me a coffee ★★

11 |

Created by Luca Becchetti

12 | 13 | ## Screenshots 14 | 15 |

16 | 17 | 18 |

19 | 20 | 21 | We support **portrait** and **landscape** orientation: 22 | 23 | 24 | ![simulator screen shot 28 lug 2017 11 32 34](https://user-images.githubusercontent.com/16253548/28711623-79df6d68-7388-11e7-9f81-e36c07c326d3.png) 25 | 26 | ## Demo 27 | 28 | Try our demo on [appetize.io](https://appetize.io/embed/4zz7rwje6npp03d8u8d8a75q6g?device=iphone7&scale=100&orientation=portrait&osVersion=10.3) 29 | 30 | ## Requirements 31 | 32 | - iOS 9+ 33 | - swift 3.0 34 | - Access for Contacts 35 | 36 | ## Main features 37 | Here's a highlight of the main features you can find in SwiftMultiSelect: 38 | 39 | * **Access PhoneBook or custom lists** Select contacts from phone book or from a custom lists 40 | * **Fast and smooth scrolling**. 41 | * **Multiple orientation** We support `portrait` and `landscape` orientation 42 | * **Fully customizable**. You can customize all programmatically 43 | 44 | ## You also may like 45 | 46 | Do you like `SwiftMultiSelect`? I'm also working on several other opensource libraries. 47 | 48 | Take a look here: 49 | 50 | * **[InAppNotify](https://github.com/lucabecchetti/InAppNotify)** - Manage in app notifications 51 | * **[CountriesViewController](https://github.com/lucabecchetti/CountriesViewController)** - Countries selection view 52 | * **[SwiftMulticastProtocol](https://github.com/lucabecchetti/SwiftMulticastProtocol)** - send message to multiple classes 53 | 54 | ## Installation with CocoaPods 55 | 56 | [CocoaPods](http://cocoapods.org) is a dependency manager for Objective-C, which automates and simplifies the process of using 3rd-party libraries like SwiftMultiSelect in your projects. You can install it with the following command: 57 | 58 | ```bash 59 | $ gem install cocoapods 60 | ``` 61 | 62 | #### Podfile 63 | 64 | To integrate SwiftMultiSelect into your Xcode project using CocoaPods, specify it in your `Podfile`: 65 | 66 | ```ruby 67 | source 'https://github.com/CocoaPods/Specs.git' 68 | platform :ios, '8.0' 69 | 70 | target 'TargetName' do 71 | use_frameworks! 72 | pod 'SwiftMultiSelect' 73 | end 74 | ``` 75 | 76 | Then, run the following command: 77 | 78 | ```bash 79 | $ pod install 80 | ``` 81 | 82 | ## How to use 83 | 84 | First of all import library in your project 85 | 86 | ```swift 87 | import SwiftMultiSelect 88 | ``` 89 | 90 | The library can show elements from PhoneBook or from a custom list, this is defined by config variable "dataSourceType", it can assume a value from SwiftMultiSelectSourceType "enum", by default is "phone". 91 | 92 | ```swift 93 | 94 | /// (default) use a contact from PhoneBook, (need a string in info.plist) 95 | SwiftMultiSelect.dataSourceType = .phone 96 | 97 | /// (default) use items from custom list, (need to implement a datasource protocol) 98 | SwiftMultiSelect.dataSourceType = .custom 99 | 100 | ``` 101 | 102 | ### Use PhoneBook contacts 103 | 104 | Note: If you want to use a default value "phone", insert this string in yout info.plist file: 105 | 106 | ```xml 107 | 108 | 109 | ..... 110 | 111 | NSContactsUsageDescription 112 | This app needs access to contacts. 113 | 114 | .... 115 | 116 | 117 | ``` 118 | 119 | The basic code to show a simple multi selection is: 120 | 121 | ```swift 122 | //Implement delegate in your UIViewController 123 | class ViewController: UIViewController,SwiftMultiSelectDelegate { 124 | 125 | override func viewDidLoad() { 126 | 127 | super.viewDidLoad() 128 | 129 | //Register delegate 130 | SwiftMultiSelect.delegate = self 131 | 132 | } 133 | 134 | //MARK: - SwiftMultiSelectDelegate 135 | 136 | //User write something in searchbar 137 | func userDidSearch(searchString: String) { 138 | 139 | print("User is looking for: \(searchString)") 140 | 141 | } 142 | 143 | //User did unselect an item 144 | func swiftMultiSelect(didUnselectItem item: SwiftMultiSelectItem) { 145 | print("row: \(item.title) has been deselected!") 146 | } 147 | 148 | //User did select an item 149 | func swiftMultiSelect(didSelectItem item: SwiftMultiSelectItem) { 150 | print("item: \(item.title) has been selected!") 151 | } 152 | 153 | //User did close controller with no selection 154 | func didCloseSwiftMultiSelect() { 155 | print("no items selected") 156 | } 157 | 158 | //User completed selection 159 | func swiftMultiSelect(didSelectItems items: [SwiftMultiSelectItem]) { 160 | 161 | print("you have been selected: \(items.count) items!") 162 | 163 | for item in items{ 164 | print(item.string) 165 | } 166 | 167 | } 168 | 169 | } 170 | ``` 171 | 172 | ### Show controller 173 | 174 | Now, somewhere in the code, use: 175 | 176 | ```swift 177 | SwiftMultiSelect.Show(to: self) 178 | ``` 179 | 180 | ### Use a custom list of SwiftMultiSelectItem 181 | 182 | #### Create SwiftMultiSelectItem object 183 | 184 | This library can show only an array of "SwiftMultiSelectItem" object, you can pass many parameters to his initializer: 185 | 186 | ```swift 187 | let item = SwiftMultiSelectItem( 188 | //An incremental unique identifier 189 | row : 0, 190 | //Title for first line 191 | title : "Item 0", 192 | //Description line 193 | description : "i am description 0", 194 | //Image asset, shown if no imageURL has been set 195 | image : UIImage(), 196 | //Url of remote image 197 | imageURL : "", 198 | //Custom color, if not present a random color will be assigned 199 | color : UIColor.gray 200 | //Your custom data, Any object 201 | userInfo : ["id" : 10] 202 | ) 203 | ``` 204 | 205 | #### Implement dataSource protocol 206 | To pass you list of SwiftMultiSelectItem, from the previuos example, you have to implement SwiftMultiSelectDataSource 207 | 208 | ```swift 209 | //Implement delegate in your UIViewController 210 | class ViewController: UIViewController,SwiftMultiSelectDelegate,SwiftMultiSelectDataSource { 211 | 212 | //Declare list to use 213 | var items:[SwiftMultiSelectItem] = [SwiftMultiSelectItem]() 214 | 215 | override func viewDidLoad() { 216 | 217 | super.viewDidLoad() 218 | // Do any additional setup after loading the view, typically from a nib. 219 | 220 | //Generate items 221 | createItems() 222 | 223 | //Se the correct data source type 224 | SwiftMultiSelect.dataSourceType = .custom 225 | 226 | //Register delegate 227 | SwiftMultiSelect.dataSource = self 228 | SwiftMultiSelect.delegate = self 229 | 230 | } 231 | 232 | //MARK: - SwiftMultiSelectDataSource 233 | 234 | func numberOfItemsInSwiftMultiSelect() -> Int { 235 | return items.count 236 | } 237 | 238 | func swiftMultiSelect(itemAtRow row: Int) -> SwiftMultiSelectItem { 239 | return items[row] 240 | } 241 | 242 | 243 | } 244 | ``` 245 | 246 | ### Interact with controller 247 | 248 | To interact with controller you have a Delegate class and DataSource Class: 249 | 250 | ```swift 251 | /// A data source 252 | public protocol SwiftMultiSelectDataSource{ 253 | 254 | /// Ask datasource for current item in row 255 | func swiftMultiSelect(itemAtRow row:Int) -> SwiftMultiSelectItem 256 | 257 | /// Asks datasource for the number of items 258 | func numberOfItemsInSwiftMultiSelect() -> Int 259 | 260 | } 261 | 262 | /// A delegate 263 | public protocol SwiftMultiSelectDelegate{ 264 | 265 | /// Called when user did end selection 266 | func swiftMultiSelect(didSelectItems items:[SwiftMultiSelectItem]) 267 | 268 | /// Called when user has been selected an item 269 | func swiftMultiSelect(didSelectItem item:SwiftMultiSelectItem) 270 | 271 | /// Called when user has been unselected an item 272 | func swiftMultiSelect(didUnselectItem item:SwiftMultiSelectItem) 273 | 274 | /// Called when user has been closed with no selection 275 | func didCloseSwiftMultiSelect() 276 | 277 | /// Called when user did write in searchbar 278 | func userDidSearch(searchString:String) 279 | } 280 | ``` 281 | 282 | ### Customization 283 | 284 | SwiftMultiSelect is fully customizable, to configure it you have to modify that Config struct: 285 | 286 | ```swift 287 | /// Public struct for configuration and customizations 288 | public struct Config { 289 | 290 | /// Background of main view 291 | public static var mainBackground : UIColor = UIColor.white 292 | /// View's title 293 | public static var viewTitle : String = "Swift Multiple Select" 294 | /// Title for done button 295 | public static var doneString : String = "Done" 296 | //Placeholder image during lazy load 297 | public static var placeholder_image : UIImage = SwiftMultiSelect.image(named: "user_blank")! 298 | /// Array of colors to use in initials 299 | public static var colorArray : [UIColor] = [ 300 | ThemeColors.amethystColor, 301 | ThemeColors.asbestosColor, 302 | ThemeColors.emeraldColor, 303 | ThemeColors.peterRiverColor, 304 | ThemeColors.pomegranateColor, 305 | ThemeColors.pumpkinColor, 306 | ThemeColors.sunflowerColor 307 | ] 308 | 309 | /// Define the style of tableview 310 | public struct tableStyle{ 311 | 312 | //Background color of tableview 313 | public static var backgroundColor : UIColor = .white 314 | //Height of single row 315 | public static var tableRowHeight : Double = 70.0 316 | //Margin between imageavatar and cell borders 317 | public static var avatarMargin : Double = 7.0 318 | //Color for title label, first line 319 | public static var title_color : UIColor = .black 320 | //Font for title label 321 | public static var title_font : UIFont = UIFont.boldSystemFont(ofSize: 16.0) 322 | //Color for description label, first line 323 | public static var description_color : UIColor = .gray 324 | //Font for description label 325 | public static var description_font : UIFont = UIFont.systemFont(ofSize: 13.0) 326 | //Color for initials label 327 | public static var initials_color : UIColor = .white 328 | //Font for initials label 329 | public static var initials_font : UIFont = UIFont.systemFont(ofSize: 18.0) 330 | 331 | } 332 | 333 | /// Define the style of scrollview 334 | public struct selectorStyle{ 335 | 336 | //Image asset for remove button 337 | public static var removeButtonImage : UIImage = SwiftMultiSelect.image(named: "remove")! 338 | //The height of selectorview, all subviews will be resized 339 | public static var selectionHeight : Double = 90.0 340 | //Scale factor for size of imageavatar based on cell size 341 | public static var avatarScale : Double = 1.7 342 | //Color for separator line between scrollview and tableview 343 | public static var separatorColor : UIColor = UIColor.lightGray 344 | //Height for separator line between scrollview and tableview 345 | public static var separatorHeight : Double = 0.7 346 | //Background color of uiscrollview 347 | public static var backgroundColor : UIColor = .white 348 | //Color for title label 349 | public static var title_color : UIColor = .black 350 | //Font for title label 351 | public static var title_font : UIFont = UIFont.systemFont(ofSize: 11.0) 352 | //Color for initials label 353 | public static var initials_color : UIColor = .white 354 | //Font for initials label 355 | public static var initials_font : UIFont = UIFont.systemFont(ofSize: 18.0) 356 | //Background color of collectionviewcell 357 | public static var backgroundCellColor : UIColor = .clear 358 | 359 | } 360 | 361 | } 362 | ``` 363 | 364 | You can set variables before show a controller, for example in ViewDidLoad: 365 | 366 | ```swift 367 | override func viewDidLoad() { 368 | 369 | super.viewDidLoad() 370 | 371 | // Do any additional setup 372 | Config.doneString = "Ok" 373 | 374 | SwiftMultiSelect.dataSource = self 375 | SwiftMultiSelect.delegate = self 376 | 377 | } 378 | ``` 379 | 380 | ## Projects using SwiftMultiSelect 381 | 382 | - Frind - [www.frind.it](https://www.frind.it) 383 | - OnItsWay - [OnItsWay](https://itunes.apple.com/us/app/onitsway-deliveries-made-easy/id1190157855?ls=1&mt=8) 384 | 385 | ### Your App and SwiftMultiSelect 386 | I'm interested in making a list of all projects which use this library. Feel free to open an Issue on GitHub with the name and links of your project; we'll add it to this site. 387 | 388 | ## Credits & License 389 | SwiftMultiSelect is owned and maintained by [Luca Becchetti](http://www.lucabecchetti.com) 390 | 391 | As open source creation any help is welcome! 392 | 393 | The code of this library is licensed under MIT License; you can use it in commercial products without any limitation. 394 | 395 | The only requirement is to add a line in your Credits/About section with the text below: 396 | 397 | ``` 398 | In app notification by SwiftMultiSelect - http://www.lucabecchetti.com 399 | Created by Becchetti Luca and licensed under MIT License. 400 | ``` 401 | ## About me 402 | 403 | I am a professional programmer with a background in software design and development, currently developing my qualitative skills on a startup company named "[Frind](https://www.frind.it) " as Project Manager and ios senior software engineer. 404 | 405 | I'm high skilled in Software Design (10+ years of experience), i have been worked since i was young as webmaster, and i'm a senior Php developer. In the last years i have been worked hard with mobile application programming, Swift for ios world, and Java for Android world. 406 | 407 | I'm an expert mobile developer and architect with several years of experience of team managing, design and development on all the major mobile platforms: iOS, Android (3+ years of experience). 408 | 409 | I'm also has broad experience on Web design and development both on client and server side and API /Networking design. 410 | 411 | All my last works are hosted on AWS Amazon cloud, i'm able to configure a netowrk, with Unix servers. For my last works i configured apache2, ssl, ejabberd in cluster mode, Api servers with load balancer, and more. 412 | 413 | I live in Assisi (Perugia), a small town in Italy, for any question, [contact me](mailto:luca.becchetti@brokenice.it) 414 | -------------------------------------------------------------------------------- /SwiftMultiSelect.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | 3 | # 1 4 | s.platform = :ios 5 | s.ios.deployment_target = '9.0' 6 | s.name = "SwiftMultiSelect" 7 | s.summary = "SwiftMultiSelect lets a user select multiple contacts from PhoneBook or from custom list" 8 | s.requires_arc = true 9 | 10 | # 2 11 | s.version = "0.2.4" 12 | 13 | # 3 14 | s.license = { :type => "MIT", :file => "LICENSE" } 15 | 16 | # 4 - Replace with your name and e-mail address 17 | s.author = { "Luca Becchetti" => "luca.becchetti@brokenice.it" } 18 | 19 | 20 | # 5 - Replace this URL with your own Github page's URL (from the address bar) 21 | s.homepage = "https://github.com/lucabecchetti/swiftmultiselect" 22 | 23 | # 6 - Replace this URL with your own Git URL from "Quick Setup" 24 | s.source = { :git => "https://github.com/lucabecchetti/swiftmultiselect.git", :tag => "#{s.version}"} 25 | 26 | # 7 27 | s.framework = "UIKit" 28 | 29 | # 8 30 | s.source_files = "SwiftMultiSelect/*.swift" 31 | s.resource = "SwiftMultiSelect/Assets/*.*" 32 | 33 | end 34 | -------------------------------------------------------------------------------- /SwiftMultiSelect/0.1.0/SwiftMultiSelect.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | 3 | # 1 4 | s.platform = :ios 5 | s.ios.deployment_target = '9.0' 6 | s.name = "SwiftMultiSelect" 7 | s.summary = "SwiftMultiSelect lets a user select multiple contacts from PhoneBook or from custom list" 8 | s.requires_arc = true 9 | 10 | # 2 11 | s.version = "0.1.0" 12 | 13 | # 3 14 | s.license = { :type => "MIT", :file => "LICENSE" } 15 | 16 | # 4 - Replace with your name and e-mail address 17 | s.author = { "Luca Becchetti" => "luca.becchetti@brokenice.it" } 18 | 19 | 20 | # 5 - Replace this URL with your own Github page's URL (from the address bar) 21 | s.homepage = "https://github.com/lucabecchetti/swiftmultiselect" 22 | 23 | # 6 - Replace this URL with your own Git URL from "Quick Setup" 24 | s.source = { :git => "https://github.com/lucabecchetti/swiftmultiselect.git", :tag => "#{s.version}"} 25 | 26 | # 7 27 | s.framework = "UIKit" 28 | 29 | # 8 30 | s.source_files = "SwiftMultiSelect/*.{swift}" 31 | 32 | # 9 33 | #s.resources = "SwiftMultiSelect/*.{png,jpeg,jpg,storyboard,xib}" 34 | end 35 | -------------------------------------------------------------------------------- /SwiftMultiSelect/0.1.3/SwiftMultiSelect.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | 3 | # 1 4 | s.platform = :ios 5 | s.ios.deployment_target = '9.0' 6 | s.name = "SwiftMultiSelect" 7 | s.summary = "SwiftMultiSelect lets a user select multiple contacts from PhoneBook or from custom list" 8 | s.requires_arc = true 9 | 10 | # 2 11 | s.version = "0.1.3" 12 | 13 | # 3 14 | s.license = { :type => "MIT", :file => "LICENSE" } 15 | 16 | # 4 - Replace with your name and e-mail address 17 | s.author = { "Luca Becchetti" => "luca.becchetti@brokenice.it" } 18 | 19 | 20 | # 5 - Replace this URL with your own Github page's URL (from the address bar) 21 | s.homepage = "https://github.com/lucabecchetti/swiftmultiselect" 22 | 23 | # 6 - Replace this URL with your own Git URL from "Quick Setup" 24 | s.source = { :git => "https://github.com/lucabecchetti/swiftmultiselect.git", :tag => "#{s.version}"} 25 | 26 | # 7 27 | s.framework = "UIKit" 28 | 29 | # 8 30 | s.source_files = "SwiftMultiSelect/*.{swift}" 31 | 32 | s.resource_bundles = { 33 | 'SwiftMultiSelect' => ['SwiftMultiSelect/Resources/*.png'] 34 | } 35 | 36 | end 37 | -------------------------------------------------------------------------------- /SwiftMultiSelect/0.1.5/SwiftMultiSelect.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | 3 | # 1 4 | s.platform = :ios 5 | s.ios.deployment_target = '9.0' 6 | s.name = "SwiftMultiSelect" 7 | s.summary = "SwiftMultiSelect lets a user select multiple contacts from PhoneBook or from custom list" 8 | s.requires_arc = true 9 | 10 | # 2 11 | s.version = "0.1.5" 12 | 13 | # 3 14 | s.license = { :type => "MIT", :file => "LICENSE" } 15 | 16 | # 4 - Replace with your name and e-mail address 17 | s.author = { "Luca Becchetti" => "luca.becchetti@brokenice.it" } 18 | 19 | 20 | # 5 - Replace this URL with your own Github page's URL (from the address bar) 21 | s.homepage = "https://github.com/lucabecchetti/swiftmultiselect" 22 | 23 | # 6 - Replace this URL with your own Git URL from "Quick Setup" 24 | s.source = { :git => "https://github.com/lucabecchetti/swiftmultiselect.git", :tag => "#{s.version}"} 25 | 26 | # 7 27 | s.framework = "UIKit" 28 | 29 | # 8 30 | s.source_files = "SwiftMultiSelect/*.swift" 31 | s.resource = "SwiftMultiSelect/Assets/*.*" 32 | 33 | end 34 | -------------------------------------------------------------------------------- /SwiftMultiSelect/0.1.6/SwiftMultiSelect.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | 3 | # 1 4 | s.platform = :ios 5 | s.ios.deployment_target = '9.0' 6 | s.name = "SwiftMultiSelect" 7 | s.summary = "SwiftMultiSelect lets a user select multiple contacts from PhoneBook or from custom list" 8 | s.requires_arc = true 9 | 10 | # 2 11 | s.version = "0.1.6" 12 | 13 | # 3 14 | s.license = { :type => "MIT", :file => "LICENSE" } 15 | 16 | # 4 - Replace with your name and e-mail address 17 | s.author = { "Luca Becchetti" => "luca.becchetti@brokenice.it" } 18 | 19 | 20 | # 5 - Replace this URL with your own Github page's URL (from the address bar) 21 | s.homepage = "https://github.com/lucabecchetti/swiftmultiselect" 22 | 23 | # 6 - Replace this URL with your own Git URL from "Quick Setup" 24 | s.source = { :git => "https://github.com/lucabecchetti/swiftmultiselect.git", :tag => "#{s.version}"} 25 | 26 | # 7 27 | s.framework = "UIKit" 28 | 29 | # 8 30 | s.source_files = "SwiftMultiSelect/*.swift" 31 | s.resource = "SwiftMultiSelect/Assets/*.*" 32 | 33 | end 34 | -------------------------------------------------------------------------------- /SwiftMultiSelect/0.2.1/SwiftMultiSelect.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | 3 | # 1 4 | s.platform = :ios 5 | s.ios.deployment_target = '9.0' 6 | s.name = "SwiftMultiSelect" 7 | s.summary = "SwiftMultiSelect lets a user select multiple contacts from PhoneBook or from custom list" 8 | s.requires_arc = true 9 | 10 | # 2 11 | s.version = "0.2.1" 12 | 13 | # 3 14 | s.license = { :type => "MIT", :file => "LICENSE" } 15 | 16 | # 4 - Replace with your name and e-mail address 17 | s.author = { "Luca Becchetti" => "luca.becchetti@brokenice.it" } 18 | 19 | 20 | # 5 - Replace this URL with your own Github page's URL (from the address bar) 21 | s.homepage = "https://github.com/lucabecchetti/swiftmultiselect" 22 | 23 | # 6 - Replace this URL with your own Git URL from "Quick Setup" 24 | s.source = { :git => "https://github.com/lucabecchetti/swiftmultiselect.git", :tag => "#{s.version}"} 25 | 26 | # 7 27 | s.framework = "UIKit" 28 | 29 | # 8 30 | s.source_files = "SwiftMultiSelect/*.swift" 31 | s.resource = "SwiftMultiSelect/Assets/*.*" 32 | 33 | end 34 | -------------------------------------------------------------------------------- /SwiftMultiSelect/0.2.2/SwiftMultiSelect.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | 3 | # 1 4 | s.platform = :ios 5 | s.ios.deployment_target = '9.0' 6 | s.name = "SwiftMultiSelect" 7 | s.summary = "SwiftMultiSelect lets a user select multiple contacts from PhoneBook or from custom list" 8 | s.requires_arc = true 9 | 10 | # 2 11 | s.version = "0.2.2" 12 | 13 | # 3 14 | s.license = { :type => "MIT", :file => "LICENSE" } 15 | 16 | # 4 - Replace with your name and e-mail address 17 | s.author = { "Luca Becchetti" => "luca.becchetti@brokenice.it" } 18 | 19 | 20 | # 5 - Replace this URL with your own Github page's URL (from the address bar) 21 | s.homepage = "https://github.com/lucabecchetti/swiftmultiselect" 22 | 23 | # 6 - Replace this URL with your own Git URL from "Quick Setup" 24 | s.source = { :git => "https://github.com/lucabecchetti/swiftmultiselect.git", :tag => "#{s.version}"} 25 | 26 | # 7 27 | s.framework = "UIKit" 28 | 29 | # 8 30 | s.source_files = "SwiftMultiSelect/*.swift" 31 | s.resource = "SwiftMultiSelect/Assets/*.*" 32 | 33 | end 34 | -------------------------------------------------------------------------------- /SwiftMultiSelect/0.2.3/SwiftMultiSelect.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | 3 | # 1 4 | s.platform = :ios 5 | s.ios.deployment_target = '9.0' 6 | s.name = "SwiftMultiSelect" 7 | s.summary = "SwiftMultiSelect lets a user select multiple contacts from PhoneBook or from custom list" 8 | s.requires_arc = true 9 | 10 | # 2 11 | s.version = "0.2.3" 12 | 13 | # 3 14 | s.license = { :type => "MIT", :file => "LICENSE" } 15 | 16 | # 4 - Replace with your name and e-mail address 17 | s.author = { "Luca Becchetti" => "luca.becchetti@brokenice.it" } 18 | 19 | 20 | # 5 - Replace this URL with your own Github page's URL (from the address bar) 21 | s.homepage = "https://github.com/lucabecchetti/swiftmultiselect" 22 | 23 | # 6 - Replace this URL with your own Git URL from "Quick Setup" 24 | s.source = { :git => "https://github.com/lucabecchetti/swiftmultiselect.git", :tag => "#{s.version}"} 25 | 26 | # 7 27 | s.framework = "UIKit" 28 | 29 | # 8 30 | s.source_files = "SwiftMultiSelect/*.swift" 31 | s.resource = "SwiftMultiSelect/Assets/*.*" 32 | 33 | end 34 | -------------------------------------------------------------------------------- /SwiftMultiSelect/Assets/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /SwiftMultiSelect/Assets/Assets.xcassets/remove.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "remove.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "remove@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "remove@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /SwiftMultiSelect/Assets/Assets.xcassets/remove.imageset/remove.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucabecchetti/SwiftMultiSelect/89087b0f3b18117c0871948d70388a904faf536a/SwiftMultiSelect/Assets/Assets.xcassets/remove.imageset/remove.png -------------------------------------------------------------------------------- /SwiftMultiSelect/Assets/Assets.xcassets/remove.imageset/remove@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucabecchetti/SwiftMultiSelect/89087b0f3b18117c0871948d70388a904faf536a/SwiftMultiSelect/Assets/Assets.xcassets/remove.imageset/remove@2x.png -------------------------------------------------------------------------------- /SwiftMultiSelect/Assets/Assets.xcassets/remove.imageset/remove@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucabecchetti/SwiftMultiSelect/89087b0f3b18117c0871948d70388a904faf536a/SwiftMultiSelect/Assets/Assets.xcassets/remove.imageset/remove@3x.png -------------------------------------------------------------------------------- /SwiftMultiSelect/Assets/Assets.xcassets/user_blank.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "user_blank.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "user_blank@2x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /SwiftMultiSelect/Assets/Assets.xcassets/user_blank.imageset/user_blank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucabecchetti/SwiftMultiSelect/89087b0f3b18117c0871948d70388a904faf536a/SwiftMultiSelect/Assets/Assets.xcassets/user_blank.imageset/user_blank.png -------------------------------------------------------------------------------- /SwiftMultiSelect/Assets/Assets.xcassets/user_blank.imageset/user_blank@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucabecchetti/SwiftMultiSelect/89087b0f3b18117c0871948d70388a904faf536a/SwiftMultiSelect/Assets/Assets.xcassets/user_blank.imageset/user_blank@2x.png -------------------------------------------------------------------------------- /SwiftMultiSelect/ContactsLibrary.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ContactsLibrary.swift 3 | // frind 4 | // 5 | // Created by Spike on 26/11/15. 6 | // Copyright © 2015 brokenice. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Contacts 11 | import ContactsUI 12 | 13 | 14 | /// Class to manage Contacts 15 | public class ContactsLibrary{ 16 | 17 | //Contacts store 18 | public static var contactStore = CNContactStore() 19 | 20 | 21 | /// Function to request access for PhoneBook 22 | /// 23 | /// - Parameter completionHandler: <#completionHandler description#> 24 | class func requestForAccess(_ completionHandler: @escaping (_ accessGranted: Bool) -> Void) { 25 | 26 | let authorizationStatus = CNContactStore.authorizationStatus(for: CNEntityType.contacts) 27 | 28 | switch authorizationStatus { 29 | case .authorized: 30 | completionHandler(true) 31 | 32 | case .denied, .notDetermined: 33 | self.contactStore.requestAccess(for: CNEntityType.contacts, completionHandler: { (access, accessError) -> Void in 34 | if access { 35 | completionHandler(access) 36 | } 37 | else { 38 | if authorizationStatus == CNAuthorizationStatus.denied { 39 | DispatchQueue.main.async(execute: { () -> Void in 40 | print("\(accessError!.localizedDescription)\n\nPlease allow the app to access your contacts through the Settings.") 41 | }) 42 | } 43 | } 44 | }) 45 | 46 | default: 47 | completionHandler(false) 48 | } 49 | } 50 | 51 | 52 | /// Function to get contacts from device 53 | /// 54 | /// - Parameters: 55 | /// - keys: array of keys to get 56 | /// - completionHandler: callback function, contains contacts array as parameter 57 | public class func getContacts(_ keys:[CNKeyDescriptor] = [CNContactGivenNameKey as CNKeyDescriptor, CNContactFamilyNameKey as CNKeyDescriptor, CNContactEmailAddressesKey as CNKeyDescriptor, CNContactOrganizationNameKey as CNKeyDescriptor, CNContactPhoneNumbersKey as CNKeyDescriptor, CNContactViewController.descriptorForRequiredKeys()],completionHandler: @escaping (_ success:Bool, _ contacts: [SwiftMultiSelectItem]?) -> Void){ 58 | 59 | self.requestForAccess { (accessGranted) -> Void in 60 | if accessGranted { 61 | 62 | var contactsArray = [SwiftMultiSelectItem]() 63 | 64 | let contactFetchRequest = CNContactFetchRequest(keysToFetch: self.allowedContactKeys()) 65 | 66 | do { 67 | var row = 0 68 | try self.contactStore.enumerateContacts(with: contactFetchRequest, usingBlock: { (contact, stop) -> Void in 69 | 70 | var username = "\(contact.givenName) \(contact.familyName)" 71 | var companyName = contact.organizationName 72 | 73 | if username.trimmingCharacters(in: .whitespacesAndNewlines) == "" && companyName != ""{ 74 | username = companyName 75 | companyName = "" 76 | } 77 | 78 | let item_contact = SwiftMultiSelectItem(row: row, title: username, description: companyName, image: nil, imageURL: nil, color: nil, userInfo: contact) 79 | contactsArray.append(item_contact) 80 | 81 | row += 1 82 | 83 | }) 84 | completionHandler(true, contactsArray) 85 | } 86 | 87 | //Catching exception as enumerateContactsWithFetchRequest can throw errors 88 | catch let error as NSError { 89 | 90 | print(error.localizedDescription) 91 | 92 | } 93 | 94 | }else{ 95 | completionHandler(false, nil) 96 | } 97 | } 98 | 99 | } 100 | 101 | 102 | /// Get allowed keys 103 | /// 104 | /// - Returns: array 105 | class func allowedContactKeys() -> [CNKeyDescriptor]{ 106 | 107 | return [ 108 | CNContactNamePrefixKey as CNKeyDescriptor, 109 | CNContactGivenNameKey as CNKeyDescriptor, 110 | CNContactMiddleNameKey as CNKeyDescriptor, 111 | CNContactFamilyNameKey as CNKeyDescriptor, 112 | CNContactNameSuffixKey as CNKeyDescriptor, 113 | //CNContactNicknameKey, 114 | //CNContactPhoneticGivenNameKey, 115 | //CNContactPhoneticMiddleNameKey, 116 | //CNContactPhoneticFamilyNameKey, 117 | CNContactOrganizationNameKey as CNKeyDescriptor, 118 | //CNContactDepartmentNameKey, 119 | //CNContactJobTitleKey, 120 | //CNContactBirthdayKey, 121 | //CNContactNonGregorianBirthdayKey, 122 | //CNContactNoteKey, 123 | CNContactImageDataKey as CNKeyDescriptor, 124 | CNContactThumbnailImageDataKey as CNKeyDescriptor, 125 | CNContactImageDataAvailableKey as CNKeyDescriptor, 126 | //CNContactTypeKey, 127 | CNContactPhoneNumbersKey as CNKeyDescriptor, 128 | CNContactEmailAddressesKey as CNKeyDescriptor, 129 | //CNContactPostalAddressesKey, 130 | CNContactDatesKey as CNKeyDescriptor, 131 | //CNContactUrlAddressesKey, 132 | //CNContactRelationsKey, 133 | //CNContactSocialProfilesKey, 134 | //CNContactInstantMessageAddressesKey 135 | ] 136 | 137 | } 138 | 139 | } 140 | 141 | -------------------------------------------------------------------------------- /SwiftMultiSelect/CustomCollectionCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CustomCollectionCell.swift 3 | // SwiftMultiSelect 4 | // 5 | // Created by Luca Becchetti on 27/07/17. 6 | // Copyright © 2017 Luca Becchetti. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | 12 | /// Class to represent custom cell for tableview 13 | class CustomCollectionCell: UICollectionViewCell 14 | { 15 | 16 | /// Lazy var for label title 17 | open fileprivate(set) lazy var labelTitle: UILabel = { 18 | 19 | let label = UILabel() 20 | label.autoresizingMask = [.flexibleWidth] 21 | label.isOpaque = false 22 | label.backgroundColor = UIColor.clear 23 | label.textAlignment = NSTextAlignment.center 24 | label.adjustsFontSizeToFitWidth = false 25 | label.numberOfLines = 1 26 | label.textColor = Config.selectorStyle.title_color 27 | label.font = Config.selectorStyle.title_font 28 | 29 | return label 30 | 31 | }() 32 | 33 | /// Lazy var for label subtitle 34 | open fileprivate(set) lazy var imageAvatar: UIImageView = { 35 | 36 | let image = UIImageView() 37 | image.contentMode = .scaleAspectFill 38 | image.image = Config.placeholder_image 39 | image.layer.cornerRadius = CGFloat(Config.selectorStyle.selectionHeight-((Config.selectorStyle.avatarScale*2.0)*Config.tableStyle.avatarMargin))/2.0 40 | image.layer.masksToBounds = true 41 | return image 42 | 43 | }() 44 | 45 | /// Lazy var for initials label 46 | open fileprivate(set) lazy var initials: UILabel = { 47 | 48 | let label = UILabel() 49 | label.isOpaque = false 50 | label.backgroundColor = UIColor.gray 51 | label.textAlignment = NSTextAlignment.center 52 | label.lineBreakMode = .byWordWrapping 53 | label.minimumScaleFactor = 0.6 54 | label.adjustsFontSizeToFitWidth = true 55 | label.numberOfLines = 1 56 | label.textColor = Config.selectorStyle.initials_color 57 | label.font = Config.selectorStyle.initials_font 58 | label.layer.cornerRadius = CGFloat(Config.selectorStyle.selectionHeight-((Config.selectorStyle.avatarScale*2.0)*Config.tableStyle.avatarMargin))/2.0 59 | label.layer.masksToBounds = true 60 | return label 61 | 62 | }() 63 | 64 | /// Lazy var for remove button 65 | open fileprivate(set) lazy var removeButton: UIButton = { 66 | 67 | let button = UIButton() 68 | button.setImage(Config.selectorStyle.removeButtonImage, for: .normal) 69 | return button 70 | 71 | }() 72 | 73 | override init(frame: CGRect) { 74 | 75 | super.init(frame: frame) 76 | 77 | //Add subviews to current view 78 | [labelTitle, imageAvatar, initials, removeButton].forEach { addSubview($0) } 79 | 80 | //Adjust avatar view frame 81 | imageAvatar.frame = CGRect( 82 | x : Config.tableStyle.avatarMargin*Config.selectorStyle.avatarScale, 83 | y : Config.tableStyle.avatarMargin/Config.selectorStyle.avatarScale, 84 | width : Config.selectorStyle.selectionHeight-((Config.selectorStyle.avatarScale*2.0)*Config.tableStyle.avatarMargin), 85 | height : Config.selectorStyle.selectionHeight-((Config.selectorStyle.avatarScale*2.0)*Config.tableStyle.avatarMargin) 86 | ) 87 | 88 | //Adjust initial label view frame 89 | initials.frame = imageAvatar.frame 90 | 91 | //Adjust button frame 92 | let btnSize = imageAvatar.frame.size.width/3 93 | removeButton.frame = CGRect( 94 | x: imageAvatar.frame.origin.x + imageAvatar.frame.size.width - (btnSize/1.5), 95 | y: imageAvatar.frame.origin.y, 96 | width: btnSize, 97 | height: btnSize 98 | ) 99 | 100 | //Adjust title view frame 101 | labelTitle.frame = CGRect( 102 | x : Double(self.imageAvatar.frame.origin.x), 103 | y : Double(self.imageAvatar.frame.origin.y+self.imageAvatar.frame.size.height), 104 | width : Double(bounds.width-(2*self.imageAvatar.frame.origin.x)), 105 | height : 20 106 | ) 107 | 108 | backgroundColor = Config.selectorStyle.backgroundCellColor 109 | 110 | 111 | } 112 | 113 | required init?(coder aDecoder: NSCoder) { 114 | super.init(coder: aDecoder) 115 | } 116 | 117 | } 118 | -------------------------------------------------------------------------------- /SwiftMultiSelect/CustomTableCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CustomTableCell.swift 3 | // SwiftMultiSelect 4 | // 5 | // Created by Luca Becchetti on 27/07/17. 6 | // Copyright © 2017 Luca Becchetti. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | /// Class to represent custom cell for tableview 12 | class CustomTableCell: UITableViewCell 13 | { 14 | 15 | /// Lazy var for label title 16 | open fileprivate(set) lazy var labelTitle: UILabel = { 17 | 18 | let label = UILabel() 19 | label.autoresizingMask = [.flexibleWidth] 20 | label.isOpaque = false 21 | label.backgroundColor = UIColor.clear 22 | label.textAlignment = NSTextAlignment.left 23 | label.lineBreakMode = .byWordWrapping 24 | label.adjustsFontSizeToFitWidth = false 25 | label.numberOfLines = 1 26 | label.textColor = Config.tableStyle.title_color 27 | label.font = Config.tableStyle.title_font 28 | 29 | return label 30 | 31 | }() 32 | 33 | /// Lazy var for label subtitle 34 | open fileprivate(set) lazy var labelSubTitle: UILabel = { 35 | 36 | let label = UILabel() 37 | label.autoresizingMask = [.flexibleWidth] 38 | label.isOpaque = false 39 | label.backgroundColor = UIColor.clear 40 | label.textAlignment = NSTextAlignment.left 41 | label.lineBreakMode = .byWordWrapping 42 | label.minimumScaleFactor = 0.6 43 | label.adjustsFontSizeToFitWidth = true 44 | label.numberOfLines = 1 45 | label.textColor = Config.tableStyle.description_color 46 | label.font = Config.tableStyle.description_font 47 | 48 | return label 49 | 50 | }() 51 | 52 | /// Lazy var for label subtitle 53 | open fileprivate(set) lazy var imageAvatar: UIImageView = { 54 | 55 | let image = UIImageView() 56 | image.contentMode = .scaleAspectFill 57 | image.image = Config.placeholder_image 58 | image.layer.cornerRadius = CGFloat( (Config.tableStyle.tableRowHeight-(Config.tableStyle.avatarMargin*2))/2) 59 | image.layer.masksToBounds = true 60 | return image 61 | 62 | }() 63 | 64 | /// Lazy var for initials label 65 | open fileprivate(set) lazy var initials: UILabel = { 66 | 67 | let label = UILabel() 68 | label.isOpaque = false 69 | label.backgroundColor = UIColor.gray 70 | label.textAlignment = NSTextAlignment.center 71 | label.lineBreakMode = .byWordWrapping 72 | label.minimumScaleFactor = 0.6 73 | label.adjustsFontSizeToFitWidth = true 74 | label.numberOfLines = 1 75 | label.textColor = Config.tableStyle.initials_color 76 | label.font = Config.tableStyle.initials_font 77 | label.layer.cornerRadius = CGFloat( (Config.tableStyle.tableRowHeight-(Config.tableStyle.avatarMargin*2))/2) 78 | label.layer.masksToBounds = true 79 | return label 80 | 81 | }() 82 | 83 | 84 | /// Constructor 85 | /// 86 | /// - Parameters: 87 | /// - style: style for cell 88 | /// - reuseIdentifier: string for reuse 89 | override init(style: UITableViewCellStyle, reuseIdentifier: String!) 90 | { 91 | //First Call Super 92 | super.init(style: style, reuseIdentifier: reuseIdentifier) 93 | 94 | //Add subviews to current view 95 | [labelTitle, imageAvatar, labelSubTitle, initials].forEach { addSubview($0) } 96 | 97 | //Adjust avatar view frame 98 | imageAvatar.frame = CGRect( 99 | x : Config.tableStyle.avatarMargin, 100 | y : Config.tableStyle.avatarMargin, 101 | width : Config.tableStyle.tableRowHeight-(Config.tableStyle.avatarMargin*2), 102 | height : Config.tableStyle.tableRowHeight-(Config.tableStyle.avatarMargin*2) 103 | ) 104 | 105 | //Adjust initial label view frame 106 | initials.frame = imageAvatar.frame 107 | 108 | //Adjust title view frame 109 | labelTitle.frame = CGRect( 110 | x : imageAvatar.frame.origin.x + imageAvatar.frame.size.width + CGFloat(Config.tableStyle.avatarMargin), 111 | y : imageAvatar.frame.origin.y, 112 | width : bounds.size.width - imageAvatar.frame.origin.x + imageAvatar.frame.size.width + CGFloat(Config.tableStyle.avatarMargin), 113 | height : imageAvatar.frame.size.height/2 114 | ) 115 | 116 | //Adjust subtitile view frame 117 | labelSubTitle.frame = CGRect( 118 | x : imageAvatar.frame.origin.x + imageAvatar.frame.size.width + CGFloat(Config.tableStyle.avatarMargin), 119 | y : labelTitle.frame.origin.y + labelTitle.frame.size.height, 120 | width : bounds.size.width - imageAvatar.frame.origin.x + imageAvatar.frame.size.width + CGFloat(Config.tableStyle.avatarMargin), 121 | height : imageAvatar.frame.size.height/2 122 | ) 123 | 124 | } 125 | 126 | required init?(coder aDecoder: NSCoder) { 127 | super.init(coder: aDecoder) 128 | } 129 | 130 | } 131 | 132 | -------------------------------------------------------------------------------- /SwiftMultiSelect/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 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSPrincipalClass 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /SwiftMultiSelect/MultiSelectionCollectionView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MultiSelectionCollectionView.swift 3 | // SwiftMultiSelect 4 | // 5 | // Created by Luca Becchetti on 26/07/17. 6 | // Copyright © 2017 Luca Becchetti. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Contacts 11 | 12 | extension MultiSelecetionViewController:UICollectionViewDelegate,UICollectionViewDataSource{ 13 | 14 | func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 15 | { 16 | return self.selectedItems.count 17 | } 18 | 19 | func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 20 | { 21 | 22 | let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath as IndexPath) as! CustomCollectionCell 23 | 24 | //Try to get item from delegate 25 | var item = self.selectedItems[indexPath.row] 26 | 27 | //Add target for the button 28 | cell.removeButton.addTarget(self, action: #selector(MultiSelecetionViewController.handleTap(sender:)), for: .touchUpInside) 29 | cell.removeButton.tag = item.row! 30 | cell.labelTitle.text = item.title 31 | cell.initials.isHidden = true 32 | cell.imageAvatar.isHidden = true 33 | 34 | //Test if items it's CNContact 35 | if let contact = item.userInfo as? CNContact{ 36 | 37 | DispatchQueue.global(qos: DispatchQoS.QoSClass.background).async { 38 | 39 | //Build contact image in background 40 | if(contact.imageDataAvailable && contact.imageData!.count > 0){ 41 | let img = UIImage(data: contact.imageData!) 42 | DispatchQueue.main.async { 43 | item.image = img 44 | cell.imageAvatar.image = img 45 | cell.initials.isHidden = true 46 | cell.imageAvatar.isHidden = false 47 | } 48 | }else{ 49 | DispatchQueue.main.async { 50 | cell.initials.text = item.getInitials() 51 | cell.initials.isHidden = false 52 | cell.imageAvatar.isHidden = true 53 | } 54 | } 55 | 56 | } 57 | 58 | //Item is custom type 59 | }else{ 60 | if item.image == nil && item.imageURL == nil{ 61 | cell.initials.text = item.getInitials() 62 | cell.initials.isHidden = false 63 | cell.imageAvatar.isHidden = true 64 | }else{ 65 | if item.imageURL != ""{ 66 | cell.initials.isHidden = true 67 | cell.imageAvatar.isHidden = false 68 | cell.imageAvatar.setImageFromURL(stringImageUrl: item.imageURL!) 69 | }else{ 70 | cell.imageAvatar.image = item.image 71 | cell.initials.isHidden = true 72 | cell.imageAvatar.isHidden = false 73 | } 74 | } 75 | } 76 | 77 | //Set item color 78 | if item.color != nil{ 79 | cell.initials.backgroundColor = item.color! 80 | } 81 | 82 | return cell 83 | 84 | } 85 | 86 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: IndexPath) -> CGSize 87 | { 88 | 89 | return CGSize(width: CGFloat(Config.selectorStyle.selectionHeight),height: CGFloat(Config.selectorStyle.selectionHeight)) 90 | } 91 | 92 | @objc func handleTap(sender:UIButton){ 93 | 94 | //Find current item 95 | let item = selectedItems.filter { (itm) -> Bool in 96 | itm.row == sender.tag 97 | }.first 98 | 99 | //remove item 100 | reloadAndPositionScroll(idp: item!.row!, remove: true) 101 | 102 | if self.selectedItems.count <= 0 { 103 | //Comunicate deselection to delegate 104 | toggleSelectionScrollView(show: false) 105 | } 106 | 107 | } 108 | 109 | 110 | /// Remove item from collectionview and reset tag for button 111 | /// 112 | /// - Parameter index: id to remove 113 | func removeItemAndReload(index:Int){ 114 | 115 | //if no selection reload all 116 | if selectedItems.count == 0{ 117 | self.selectionScrollView.reloadData() 118 | }else{ 119 | //reload current 120 | self.selectionScrollView.deleteItems(at: [IndexPath(item: index, section: 0)]) 121 | } 122 | } 123 | 124 | /// Reaload collectionview data and scroll to last position 125 | /// 126 | /// - Parameters: 127 | /// - idp: is the tableview position index 128 | /// - remove: true if you have to remove item 129 | func reloadAndPositionScroll(idp:Int, remove:Bool){ 130 | 131 | //Identify the item inside selected array 132 | let item = selectedItems.filter { (itm) -> Bool in 133 | itm.row == idp 134 | }.first 135 | 136 | //Remove 137 | if remove { 138 | 139 | //For remove from collection view and create IndexPath, i need the index posistion in the array 140 | let id = selectedItems.index { (itm) -> Bool in 141 | itm.row == idp 142 | } 143 | 144 | //Filter array removing the item 145 | selectedItems = selectedItems.filter({ (itm) -> Bool in 146 | itm.row != idp 147 | }) 148 | 149 | //Reload collectionview 150 | if id != nil{ 151 | removeItemAndReload(index: id!) 152 | } 153 | 154 | SwiftMultiSelect.delegate?.swiftMultiSelect(didUnselectItem: item!) 155 | 156 | //Reload cell state 157 | reloadCellState(row: idp, selected: false) 158 | 159 | 160 | if selectedItems.count <= 0{ 161 | //Toggle scrollview 162 | toggleSelectionScrollView(show: false) 163 | } 164 | 165 | 166 | 167 | //Add 168 | }else{ 169 | 170 | toggleSelectionScrollView(show: true) 171 | 172 | //Reload data 173 | self.selectionScrollView.insertItems(at: [IndexPath(item: selectedItems.count-1, section: 0)]) 174 | let lastItemIndex = IndexPath(item: self.selectedItems.count-1, section: 0) 175 | 176 | //Scroll to selected item 177 | self.selectionScrollView.scrollToItem(at: lastItemIndex, at: .right, animated: true) 178 | 179 | reloadCellState(row: idp, selected: true) 180 | 181 | 182 | } 183 | 184 | 185 | 186 | } 187 | 188 | 189 | } 190 | 191 | -------------------------------------------------------------------------------- /SwiftMultiSelect/MultiSelectionTableView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MultiSelectionTableView.swift 3 | // SwiftMultiSelect 4 | // 5 | // Created by Luca Becchetti on 26/07/17. 6 | // Copyright © 2017 Luca Becchetti. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Contacts 11 | 12 | // MARK: - UITableViewDelegate,UITableViewDataSource 13 | extension MultiSelecetionViewController:UITableViewDelegate,UITableViewDataSource{ 14 | 15 | func numberOfSections(in tableView: UITableView) -> Int { 16 | return 1 17 | } 18 | 19 | func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool { 20 | return false 21 | } 22 | 23 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 24 | 25 | if SwiftMultiSelect.dataSourceType == .phone{ 26 | if searchString == "" { 27 | return SwiftMultiSelect.items!.count 28 | }else{ 29 | return SwiftMultiSelect.items!.filter({$0.title.lowercased().contains(searchString.lowercased()) || ($0.description != nil && $0.description!.lowercased().contains(searchString.lowercased())) }).count 30 | } 31 | }else{ 32 | 33 | //Try to get rows from delegate 34 | guard let rows = SwiftMultiSelect.dataSource?.numberOfItemsInSwiftMultiSelect() else { 35 | return 0 36 | } 37 | 38 | return rows 39 | } 40 | 41 | } 42 | 43 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 44 | 45 | //Get Reference to Cell 46 | let cell : CustomTableCell = self.tableView.dequeueReusableCell(withIdentifier: "cell") as! CustomTableCell 47 | cell.selectionStyle = .none 48 | 49 | var item:SwiftMultiSelectItem! 50 | 51 | if SwiftMultiSelect.dataSourceType == .phone{ 52 | item = (searchString == "") ? SwiftMultiSelect.items![indexPath.row] : SwiftMultiSelect.items!.filter({$0.title.lowercased().contains(searchString.lowercased()) || ($0.description != nil && $0.description!.lowercased().contains(searchString.lowercased())) })[indexPath.row] 53 | }else{ 54 | //Try to get item from delegate 55 | item = SwiftMultiSelect.dataSource?.swiftMultiSelect(itemAtRow: indexPath.row) 56 | } 57 | 58 | //Configure cell properties 59 | cell.labelTitle.text = item.title 60 | cell.labelSubTitle.text = item.description 61 | cell.initials.isHidden = true 62 | cell.imageAvatar.isHidden = true 63 | 64 | if let contact = item.userInfo as? CNContact{ 65 | 66 | DispatchQueue.global(qos: DispatchQoS.QoSClass.background).async { 67 | 68 | if(contact.imageDataAvailable && contact.imageData!.count > 0){ 69 | let img = UIImage(data: contact.imageData!) 70 | DispatchQueue.main.async { 71 | item.image = img 72 | cell.imageAvatar.image = img 73 | cell.initials.isHidden = true 74 | cell.imageAvatar.isHidden = false 75 | } 76 | }else{ 77 | DispatchQueue.main.async { 78 | cell.initials.text = item.getInitials() 79 | cell.initials.isHidden = false 80 | cell.imageAvatar.isHidden = true 81 | } 82 | } 83 | 84 | } 85 | 86 | }else{ 87 | if item.image == nil && item.imageURL == nil{ 88 | cell.initials.text = item.getInitials() 89 | cell.initials.isHidden = false 90 | cell.imageAvatar.isHidden = true 91 | }else{ 92 | if item.imageURL != ""{ 93 | cell.initials.isHidden = true 94 | cell.imageAvatar.isHidden = false 95 | cell.imageAvatar.setImageFromURL(stringImageUrl: item.imageURL!) 96 | }else{ 97 | cell.imageAvatar.image = item.image 98 | cell.initials.isHidden = true 99 | cell.imageAvatar.isHidden = false 100 | } 101 | } 102 | } 103 | 104 | if item.color != nil{ 105 | cell.initials.backgroundColor = item.color! 106 | }else{ 107 | cell.initials.backgroundColor = updateInitialsColorForIndexPath(indexPath) 108 | } 109 | 110 | 111 | //Set initial state 112 | if let itm_pre = self.selectedItems.index(where: { (itm) -> Bool in 113 | itm == item 114 | }){ 115 | self.selectedItems[itm_pre].color = cell.initials.backgroundColor! 116 | cell.accessoryType = UITableViewCellAccessoryType.checkmark 117 | }else{ 118 | cell.accessoryType = UITableViewCellAccessoryType.none 119 | } 120 | 121 | 122 | return cell 123 | 124 | } 125 | 126 | 127 | /// Function that select a random color for passed indexpath 128 | /// 129 | /// - Parameter indexpath: 130 | /// - Returns: UIColor random, from Config.colorArray 131 | func updateInitialsColorForIndexPath(_ indexpath: IndexPath) -> UIColor{ 132 | 133 | //Applies color to Initial Label 134 | let randomValue = (indexpath.row + indexpath.section) % Config.colorArray.count 135 | 136 | return Config.colorArray[randomValue] 137 | 138 | } 139 | 140 | 141 | /// Function to change accessoryType for passed index 142 | /// 143 | /// - Parameters: 144 | /// - row: index of row 145 | /// - selected: true = chechmark, false = none 146 | func reloadCellState(row:Int, selected:Bool){ 147 | 148 | if let cell = self.tableView.cellForRow(at: IndexPath(row: row, section: 0)) as? CustomTableCell{ 149 | cell.accessoryType = (selected) ? .checkmark : .none 150 | } 151 | 152 | } 153 | 154 | func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 155 | 156 | //Get selected cell 157 | let cell = tableView.cellForRow(at: indexPath) as! CustomTableCell 158 | 159 | var item:SwiftMultiSelectItem! 160 | 161 | if SwiftMultiSelect.dataSourceType == .phone{ 162 | item = (searchString == "") ? SwiftMultiSelect.items![indexPath.row] : SwiftMultiSelect.items!.filter({$0.title.lowercased().contains(searchString.lowercased()) || ($0.description != nil && $0.description!.lowercased().contains(searchString.lowercased())) })[indexPath.row] 163 | }else{ 164 | //Try to get item from delegate 165 | item = SwiftMultiSelect.dataSource?.swiftMultiSelect(itemAtRow: indexPath.row) 166 | } 167 | 168 | //Save item data 169 | item.color = cell.initials.backgroundColor! 170 | 171 | //Check if cell is already selected or not 172 | if cell.accessoryType == UITableViewCellAccessoryType.checkmark 173 | { 174 | 175 | //Set accessory type 176 | cell.accessoryType = UITableViewCellAccessoryType.none 177 | 178 | //Comunicate deselection to delegate 179 | SwiftMultiSelect.delegate?.swiftMultiSelect(didUnselectItem: item) 180 | 181 | //Reload collectionview 182 | self.reloadAndPositionScroll(idp: item.row!, remove:true) 183 | 184 | } 185 | else{ 186 | 187 | //Set accessory type 188 | cell.accessoryType = UITableViewCellAccessoryType.checkmark 189 | 190 | //Add current item to selected 191 | selectedItems.append(item) 192 | 193 | //Comunicate selection to delegate 194 | SwiftMultiSelect.delegate?.swiftMultiSelect(didSelectItem: item) 195 | 196 | //Reload collectionview 197 | self.reloadAndPositionScroll(idp: item.row!, remove:false) 198 | 199 | } 200 | 201 | //Reset search 202 | if searchString != ""{ 203 | searchBar.text = "" 204 | searchString = "" 205 | SwiftMultiSelect.delegate?.userDidSearch(searchString: "") 206 | self.tableView.reloadData() 207 | } 208 | 209 | } 210 | 211 | func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { 212 | 213 | return CGFloat(Config.tableStyle.tableRowHeight) 214 | 215 | } 216 | 217 | // MARK: - UISearchBarDelegate 218 | 219 | func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) { 220 | self.searchString = searchText 221 | 222 | if (searchText.isEmpty) { 223 | self.perform(#selector(self.hideKeyboardWithSearchBar(_:)), with: searchBar, afterDelay: 0) 224 | self.searchString = "" 225 | } 226 | 227 | SwiftMultiSelect.delegate?.userDidSearch(searchString: searchText) 228 | 229 | self.tableView.reloadData() 230 | } 231 | 232 | @objc func hideKeyboardWithSearchBar(_ searchBar:UISearchBar){ 233 | searchBar.resignFirstResponder() 234 | } 235 | 236 | func searchBarShouldEndEditing(_ searchBar: UISearchBar) -> Bool{ 237 | return true 238 | } 239 | 240 | } 241 | -------------------------------------------------------------------------------- /SwiftMultiSelect/MultiSelectionViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MultiSelectionViewController.swift 3 | // SwiftMultiSelect 4 | // 5 | // Created by Luca Becchetti on 26/07/17. 6 | // Copyright © 2017 Luca Becchetti. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | /// Class that represent the selection view 12 | class MultiSelecetionViewController: UIViewController,UIGestureRecognizerDelegate,UISearchBarDelegate { 13 | 14 | /// Screen total with 15 | public var totalWidth:CGFloat{ 16 | get{ 17 | return UIScreen.main.bounds.width 18 | } 19 | } 20 | 21 | /// Screen total height 22 | public var totalHeight:CGFloat{ 23 | get{ 24 | return UIScreen.main.bounds.height 25 | } 26 | } 27 | 28 | /// Array of selected items 29 | open var selectedItems : [SwiftMultiSelectItem] = [SwiftMultiSelectItem](){ 30 | didSet{ 31 | //Reset button navigation bar 32 | rightButtonBar.title = "\(Config.doneString) (\(self.selectedItems.count))" 33 | self.navigationItem.rightBarButtonItem?.isEnabled = (self.selectedItems.count > 0) 34 | } 35 | } 36 | 37 | /// Lazy view that represent a selection scrollview 38 | open fileprivate(set) lazy var selectionScrollView: UICollectionView = { 39 | 40 | //Build layout 41 | let layout = UICollectionViewFlowLayout() 42 | layout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0) 43 | layout.scrollDirection = UICollectionViewScrollDirection.horizontal 44 | layout.minimumInteritemSpacing = 0 45 | layout.minimumLineSpacing = 0 46 | 47 | //Build collectin view 48 | let selected = UICollectionView(frame: CGRect.zero, collectionViewLayout: layout) 49 | selected.backgroundColor = Config.selectorStyle.backgroundColor 50 | selected.isHidden = (SwiftMultiSelect.initialSelected.count <= 0) 51 | return selected 52 | 53 | }() 54 | 55 | /// Lazy view that represent a selection scrollview 56 | open fileprivate(set) lazy var separator: UIView = { 57 | 58 | //Build layout 59 | let sep = UIView() 60 | sep.autoresizingMask = [.flexibleWidth] 61 | sep.backgroundColor = Config.selectorStyle.separatorColor 62 | return sep 63 | 64 | }() 65 | 66 | /// Lazy var for table view 67 | open fileprivate(set) lazy var tableView: UITableView = { 68 | 69 | let tableView:UITableView = UITableView() 70 | tableView.backgroundColor = Config.tableStyle.backgroundColor 71 | return tableView 72 | 73 | }() 74 | 75 | /// Lazy var for table view 76 | open fileprivate(set) lazy var searchBar: UISearchBar = { 77 | 78 | let searchBar:UISearchBar = UISearchBar() 79 | searchBar.translatesAutoresizingMaskIntoConstraints = false 80 | return searchBar 81 | 82 | }() 83 | 84 | /// Lazy var for global stackview container 85 | open fileprivate(set) lazy var stackView: UIStackView = { 86 | 87 | let stackView = UIStackView(arrangedSubviews: [self.searchBar,self.selectionScrollView,self.tableView]) 88 | stackView.axis = .vertical 89 | stackView.distribution = .fill 90 | stackView.alignment = .fill 91 | stackView.spacing = 0 92 | stackView.translatesAutoresizingMaskIntoConstraints = false 93 | return stackView 94 | 95 | }() 96 | 97 | /// Calculate the nav bar height if present 98 | var navBarHeight:CGFloat{ 99 | get{ 100 | if (self.navigationController != nil) { 101 | return self.navigationController!.navigationBar.frame.size.height + (UIApplication.shared.isStatusBarHidden ? 0 : 20) 102 | }else{ 103 | return 0 104 | } 105 | } 106 | } 107 | 108 | //Nav bar buttons 109 | var leftButtonBar : UIBarButtonItem? 110 | var rightButtonBar : UIBarButtonItem = UIBarButtonItem() 111 | 112 | //Searched string 113 | var searchString = "" 114 | 115 | /// Function to build a views and set constraint 116 | func createViewsAndSetConstraints(){ 117 | 118 | //Add stack view to current view 119 | view.addSubview(stackView) 120 | 121 | selectionScrollView.addSubview(separator) 122 | separator.frame = CGRect(x: 0.0, y: Config.selectorStyle.selectionHeight-Config.selectorStyle.separatorHeight, width: Double(self.view.frame.size.width), height: Config.selectorStyle.separatorHeight) 123 | separator.layer.zPosition = CGFloat(separator.subviews.count+1) 124 | 125 | //Register tableview delegate 126 | tableView.delegate = self 127 | tableView.dataSource = self 128 | //Register cell class 129 | tableView.register(CustomTableCell.classForCoder(), forCellReuseIdentifier: "cell") 130 | 131 | //Register collectionvie delegate 132 | selectionScrollView.delegate = self 133 | selectionScrollView.dataSource = self 134 | //Register cell class 135 | selectionScrollView.register(CustomCollectionCell.classForCoder(), forCellWithReuseIdentifier: "cell") 136 | 137 | //register search delegate 138 | searchBar.delegate = self 139 | 140 | //Prevent adding top margin to collectionviewcell 141 | self.automaticallyAdjustsScrollViewInsets = false 142 | 143 | //autolayout the stack view and elements 144 | let viewsDictionary = [ 145 | "stackView" : stackView, 146 | "selected" : self.selectionScrollView 147 | ] as [String : Any] 148 | 149 | //constraint for stackview 150 | let stackView_H = NSLayoutConstraint.constraints( 151 | withVisualFormat: "H:|-0-[stackView]-0-|", 152 | options: NSLayoutFormatOptions(rawValue: 0), 153 | metrics: nil, 154 | views: viewsDictionary 155 | ) 156 | //constraint for stackview 157 | let stackView_V = NSLayoutConstraint.constraints( 158 | withVisualFormat: "V:|-\(navBarHeight)-[stackView]-0-|", 159 | options: NSLayoutFormatOptions(rawValue:0), 160 | metrics: nil, 161 | views: viewsDictionary 162 | ) 163 | 164 | searchBar.topAnchor.constraint(equalTo: stackView.topAnchor, constant: 0).isActive = true 165 | searchBar.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 0).isActive = true 166 | searchBar.rightAnchor.constraint(equalTo: view.rightAnchor, constant: 0).isActive = true 167 | searchBar.heightAnchor.constraint(equalToConstant: CGFloat(40)).isActive = true 168 | 169 | selectionScrollView.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 0).isActive = true 170 | selectionScrollView.rightAnchor.constraint(equalTo: view.rightAnchor, constant: 0).isActive = true 171 | selectionScrollView.heightAnchor.constraint(equalToConstant: CGFloat(Config.selectorStyle.selectionHeight)).isActive = true 172 | //Add all constraints to view 173 | view.addConstraints(stackView_H) 174 | view.addConstraints(stackView_V) 175 | } 176 | 177 | 178 | /// Toggle de selection view 179 | /// 180 | /// - Parameter show: true show scroller, false hide the scroller 181 | func toggleSelectionScrollView(show:Bool) { 182 | 183 | UIView.animate(withDuration: 0.2, animations: { 184 | self.selectionScrollView.isHidden = !show 185 | }) 186 | } 187 | 188 | 189 | /// Selector for right button 190 | @objc public func selectionDidEnd(){ 191 | 192 | SwiftMultiSelect.delegate?.swiftMultiSelect(didSelectItems: self.selectedItems) 193 | self.dismiss(animated: true, completion: nil) 194 | 195 | } 196 | 197 | /// Selector for left button 198 | @objc public func dismissSelector(){ 199 | 200 | self.dismiss(animated: true, completion: nil) 201 | SwiftMultiSelect.delegate?.didCloseSwiftMultiSelect() 202 | 203 | } 204 | 205 | //MARK: Life Cycle 206 | override func viewDidLoad() { 207 | 208 | super.viewDidLoad() 209 | 210 | self.title = Config.viewTitle 211 | 212 | rightButtonBar.isEnabled = false 213 | leftButtonBar = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(MultiSelecetionViewController.dismissSelector)) 214 | leftButtonBar!.isEnabled = true 215 | self.navigationItem.leftBarButtonItem = leftButtonBar 216 | self.navigationItem.rightBarButtonItem = rightButtonBar 217 | 218 | rightButtonBar.action = #selector(MultiSelecetionViewController.selectionDidEnd) 219 | rightButtonBar.target = self 220 | 221 | self.view.backgroundColor = Config.mainBackground 222 | 223 | createViewsAndSetConstraints() 224 | 225 | self.tableView.reloadData() 226 | 227 | if(SwiftMultiSelect.initialSelected.count>0){ 228 | self.selectionScrollView.reloadData() 229 | rightButtonBar.isEnabled = true 230 | rightButtonBar.title = "\(Config.doneString) (\(SwiftMultiSelect.initialSelected.count))" 231 | } 232 | 233 | } 234 | } 235 | -------------------------------------------------------------------------------- /SwiftMultiSelect/SwiftMultiSelect.h: -------------------------------------------------------------------------------- 1 | // 2 | // SwiftMultiSelect.h 3 | // SwiftMultiSelect 4 | // 5 | // Created by Luca Becchetti on 24/07/17. 6 | // Copyright © 2017 Luca Becchetti. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for SwiftMultiSelect. 12 | FOUNDATION_EXPORT double SwiftMultiSelectVersionNumber; 13 | 14 | //! Project version string for SwiftMultiSelect. 15 | FOUNDATION_EXPORT const unsigned char SwiftMultiSelectVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /SwiftMultiSelect/SwiftMultiSelect.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SwiftMultiSelect.swift 3 | // SwiftMultiSelect 4 | // 5 | // Created by Luca Becchetti on 24/07/17. 6 | // Copyright © 2017 Luca Becchetti. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | /// Define the type of datasource 12 | public enum SwiftMultiSelectSourceType : Int{ 13 | 14 | case phone = 0 15 | case custom = 1 16 | 17 | } 18 | 19 | /// Main static class 20 | public class SwiftMultiSelect{ 21 | 22 | public static var items : [SwiftMultiSelectItem]? 23 | 24 | public static var dataSourceType : SwiftMultiSelectSourceType? = .phone{ 25 | didSet{ 26 | 27 | if self.dataSourceType == .phone{ 28 | self.getContacts() 29 | }else{ 30 | self.items = nil 31 | } 32 | 33 | } 34 | } 35 | 36 | /// Delegate reference 37 | public static var delegate : SwiftMultiSelectDelegate?{ 38 | 39 | didSet{ 40 | if self.dataSourceType == .phone{ 41 | self.getContacts() 42 | }else{ 43 | self.items = nil 44 | } 45 | } 46 | 47 | } 48 | 49 | public static var dataSource : SwiftMultiSelectDataSource? 50 | 51 | /// Array of initial items selected 52 | public static var initialSelected : [SwiftMultiSelectItem] = [SwiftMultiSelectItem]() 53 | 54 | 55 | /// Function to present a selector in a UIViewContoller claass 56 | /// 57 | /// - Parameter to: UIViewController current visibile 58 | public class func Show(to: UIViewController) { 59 | 60 | // Create instance of selector 61 | let selector = MultiSelecetionViewController() 62 | 63 | // Set initial items 64 | selector.selectedItems = initialSelected 65 | 66 | //Create navigation controller 67 | let navController = UINavigationController(rootViewController: selector) 68 | 69 | // Present selectora 70 | to.present(navController, animated: true, completion: nil) 71 | 72 | } 73 | 74 | private class func getContacts(){ 75 | //ATTENTION: You have to provide a info.plist string for access contacts 76 | //NSContactsUsageDescription 77 | //This app needs access to contacts 78 | // 79 | //Retrieve contacts from phone 80 | ContactsLibrary.getContacts { (success, data) in 81 | 82 | self.items = data! 83 | 84 | } 85 | } 86 | 87 | class func image(named name: String) -> UIImage? { 88 | let image = UIImage(named: name) ?? UIImage(named: name, in: Bundle(for: self), compatibleWith: nil) 89 | return image 90 | } 91 | 92 | } 93 | 94 | /// Public struct for configuration and customizations 95 | public struct Config { 96 | 97 | /// Background of main view 98 | public static var mainBackground : UIColor = UIColor.white 99 | /// View's title 100 | public static var viewTitle : String = "Swift Multiple Select" 101 | /// Title for done button 102 | public static var doneString : String = "Done" 103 | //Placeholder image during lazy load 104 | public static var placeholder_image : UIImage = SwiftMultiSelect.image(named: "user_blank")! 105 | /// Array of colors to use in initials 106 | public static var colorArray : [UIColor] = [ 107 | ThemeColors.amethystColor, 108 | ThemeColors.asbestosColor, 109 | ThemeColors.emeraldColor, 110 | ThemeColors.peterRiverColor, 111 | ThemeColors.pomegranateColor, 112 | ThemeColors.pumpkinColor, 113 | ThemeColors.sunflowerColor 114 | ] 115 | 116 | /// Define the style of tableview 117 | public struct tableStyle{ 118 | 119 | //Background color of tableview 120 | public static var backgroundColor : UIColor = .white 121 | //Height of single row 122 | public static var tableRowHeight : Double = 70.0 123 | //Margin between imageavatar and cell borders 124 | public static var avatarMargin : Double = 7.0 125 | //Color for title label, first line 126 | public static var title_color : UIColor = .black 127 | //Font for title label 128 | public static var title_font : UIFont = UIFont.boldSystemFont(ofSize: 16.0) 129 | //Color for description label, first line 130 | public static var description_color : UIColor = .gray 131 | //Font for description label 132 | public static var description_font : UIFont = UIFont.systemFont(ofSize: 13.0) 133 | //Color for initials label 134 | public static var initials_color : UIColor = .white 135 | //Font for initials label 136 | public static var initials_font : UIFont = UIFont.systemFont(ofSize: 18.0) 137 | 138 | } 139 | 140 | /// Define the style of scrollview 141 | public struct selectorStyle{ 142 | 143 | //Image asset for remove button 144 | public static var removeButtonImage : UIImage = SwiftMultiSelect.image(named: "remove")! 145 | //The height of selectorview, all subviews will be resized 146 | public static var selectionHeight : Double = 90.0 147 | //Scale factor for size of imageavatar based on cell size 148 | public static var avatarScale : Double = 1.7 149 | //Color for separator line between scrollview and tableview 150 | public static var separatorColor : UIColor = UIColor.lightGray 151 | //Height for separator line between scrollview and tableview 152 | public static var separatorHeight : Double = 0.7 153 | //Background color of uiscrollview 154 | public static var backgroundColor : UIColor = .white 155 | //Color for title label 156 | public static var title_color : UIColor = .black 157 | //Font for title label 158 | public static var title_font : UIFont = UIFont.systemFont(ofSize: 11.0) 159 | //Color for initials label 160 | public static var initials_color : UIColor = .white 161 | //Font for initials label 162 | public static var initials_font : UIFont = UIFont.systemFont(ofSize: 18.0) 163 | //Background color of collectionviewcell 164 | public static var backgroundCellColor : UIColor = .clear 165 | 166 | } 167 | 168 | } 169 | 170 | 171 | //I colori degli avatar utente 172 | public struct ThemeColors{ 173 | static let emeraldColor = UIColor(red: (46/255), green: (204/255), blue: (113/255), alpha: 1.0) 174 | static let sunflowerColor = UIColor(red: (241/255), green: (196/255), blue: (15/255), alpha: 1.0) 175 | static let pumpkinColor = UIColor(red: (211/255), green: (84/255), blue: (0/255), alpha: 1.0) 176 | static let asbestosColor = UIColor(red: (127/255), green: (140/255), blue: (141/255), alpha: 1.0) 177 | static let amethystColor = UIColor(red: (155/255), green: (89/255), blue: (182/255), alpha: 1.0) 178 | static let peterRiverColor = UIColor(red: (52/255), green: (152/255), blue: (219/255), alpha: 1.0) 179 | static let pomegranateColor = UIColor(red: (192/255), green: (57/255), blue: (43/255), alpha: 1.0) 180 | static let lightGrayColor = UIColor(red:0.79, green:0.78, blue:0.78, alpha:1) 181 | } 182 | 183 | // Struct that represent single items of the tableView, and CollectionView 184 | public struct SwiftMultiSelectItem{ 185 | 186 | public var title : String 187 | public var description : String? 188 | public var image : UIImage? 189 | public var imageURL : String? 190 | public var userInfo : Any? 191 | public var color : UIColor? 192 | public var row : Int? 193 | 194 | ///Unique identifier 195 | fileprivate(set) var id : Int? 196 | 197 | /// String representation for struct 198 | public var string : String{ 199 | var describe = "\n+--------------------+" 200 | describe += "\n| title: \(title)" 201 | describe += "\n| description: \(String(describing: self.description))" 202 | describe += "\n| userInfo: \(String(describing: userInfo))" 203 | describe += "\n| title: \(title)" 204 | describe += "\n+--------------------+" 205 | return describe 206 | } 207 | 208 | /// Constructor for item struct 209 | /// 210 | /// - Parameters: 211 | /// - title: title, first line 212 | /// - description: description, second line 213 | /// - image: image asset 214 | /// - imageURL: image url 215 | /// - userInfo: optional information data 216 | public init(row:Int,title:String,description:String? = nil,image:UIImage? = nil,imageURL:String? = nil,color:UIColor? = nil, userInfo:Any? = nil) { 217 | 218 | self.title = title 219 | self.row = row 220 | 221 | if let desc = description{ 222 | self.description = desc 223 | } 224 | if let img = image{ 225 | self.image = img 226 | } 227 | if let url = imageURL{ 228 | self.imageURL = url 229 | } 230 | if let info = userInfo{ 231 | self.userInfo = info 232 | } 233 | if let col = color{ 234 | self.color = col 235 | } 236 | 237 | 238 | } 239 | 240 | /// Custom equal function to compare objects 241 | /// 242 | /// - Parameters: 243 | /// - lhs: left object 244 | /// - rhs: right object 245 | /// - Returns: True if two objects referer to the same row 246 | public static func ==(lhs: SwiftMultiSelectItem, rhs: SwiftMultiSelectItem) -> Bool{ 247 | return lhs.row == rhs.row 248 | } 249 | 250 | /// Custom disequal function to compare objects 251 | /// 252 | /// - Parameters: 253 | /// - lhs: left object 254 | /// - rhs: right object 255 | /// - Returns: True if two objects does not referer to the same row 256 | public static func != (lhs: SwiftMultiSelectItem, rhs: SwiftMultiSelectItem) -> Bool{ 257 | return lhs.row != rhs.row 258 | } 259 | 260 | /// Get initial letters 261 | /// 262 | /// - Returns: String 2 intials 263 | func getInitials() -> String { 264 | 265 | let tit = (title as NSString) 266 | var initials = String() 267 | if title != "" && tit.length >= 2 268 | { 269 | initials.append(tit.substring(to: 2)) 270 | } 271 | 272 | return initials.uppercased() 273 | } 274 | 275 | } 276 | 277 | 278 | /// A data source 279 | public protocol SwiftMultiSelectDataSource{ 280 | 281 | /// Ask delegate for current item in row 282 | func swiftMultiSelect(itemAtRow row:Int) -> SwiftMultiSelectItem 283 | 284 | /// Asks for the number of items 285 | func numberOfItemsInSwiftMultiSelect() -> Int 286 | 287 | } 288 | 289 | /// A delegate to handle 290 | public protocol SwiftMultiSelectDelegate{ 291 | 292 | /// Tell to delegate that user did end selection 293 | func swiftMultiSelect(didSelectItems items:[SwiftMultiSelectItem]) 294 | 295 | /// Tell to delegate that item has been selected 296 | func swiftMultiSelect(didSelectItem item:SwiftMultiSelectItem) 297 | 298 | /// Tell to delegate that item has been unselected 299 | func swiftMultiSelect(didUnselectItem item:SwiftMultiSelectItem) 300 | 301 | /// Tell to delegate user has closed without select 302 | func didCloseSwiftMultiSelect() 303 | 304 | /// Tell to delegate user has closed without select 305 | func userDidSearch(searchString:String) 306 | 307 | 308 | } 309 | 310 | // MARK: - UIImageView 311 | extension UIImageView{ 312 | 313 | 314 | /// Set an image in UIImageView from remote URL 315 | /// 316 | /// - Parameter url: url of the image 317 | func setImageFromURL(stringImageUrl url: String){ 318 | 319 | //Placeholder image 320 | image = Config.placeholder_image 321 | 322 | //Download async image 323 | DispatchQueue.global(qos: DispatchQoS.QoSClass.background).async { 324 | if let url = URL(string: url) { 325 | do{ 326 | 327 | let data = try Data.init(contentsOf: url) 328 | 329 | //Set image in the main thread 330 | DispatchQueue.main.async { 331 | self.image = UIImage(data: data) 332 | } 333 | 334 | }catch{ 335 | 336 | } 337 | } 338 | } 339 | 340 | } 341 | } 342 | 343 | 344 | 345 | -------------------------------------------------------------------------------- /SwiftMultiSelectExample/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment the next line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | 4 | target 'SwiftMultiSelectExample' do 5 | # Comment the next line if you're not using Swift and don't want to use dynamic frameworks 6 | use_frameworks! 7 | 8 | # Pods for SwiftMultiSelectExample 9 | pod 'SwiftMultiSelect', :path => '../' 10 | 11 | end 12 | -------------------------------------------------------------------------------- /SwiftMultiSelectExample/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - SwiftMultiSelect (0.1.6) 3 | 4 | DEPENDENCIES: 5 | - SwiftMultiSelect (from `../`) 6 | 7 | EXTERNAL SOURCES: 8 | SwiftMultiSelect: 9 | :path: ../ 10 | 11 | SPEC CHECKSUMS: 12 | SwiftMultiSelect: f7ad593963bc64810487d1d59c366df2ed39326b 13 | 14 | PODFILE CHECKSUM: aab54105cbfac083eacb873aac5dddec936e159c 15 | 16 | COCOAPODS: 1.3.0.beta.1 17 | -------------------------------------------------------------------------------- /SwiftMultiSelectExample/Pods/Local Podspecs/SwiftMultiSelect.podspec.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "SwiftMultiSelect", 3 | "platforms": { 4 | "ios": "9.0" 5 | }, 6 | "summary": "SwiftMultiSelect lets a user select multiple contacts from PhoneBook or from custom list", 7 | "requires_arc": true, 8 | "version": "0.1.6", 9 | "license": { 10 | "type": "MIT", 11 | "file": "LICENSE" 12 | }, 13 | "authors": { 14 | "Luca Becchetti": "luca.becchetti@brokenice.it" 15 | }, 16 | "homepage": "https://github.com/lucabecchetti/swiftmultiselect", 17 | "source": { 18 | "git": "https://github.com/lucabecchetti/swiftmultiselect.git", 19 | "tag": "0.1.6" 20 | }, 21 | "frameworks": "UIKit", 22 | "source_files": "SwiftMultiSelect/*.swift", 23 | "resources": "SwiftMultiSelect/Assets/*.*" 24 | } 25 | -------------------------------------------------------------------------------- /SwiftMultiSelectExample/Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - SwiftMultiSelect (0.1.6) 3 | 4 | DEPENDENCIES: 5 | - SwiftMultiSelect (from `../`) 6 | 7 | EXTERNAL SOURCES: 8 | SwiftMultiSelect: 9 | :path: ../ 10 | 11 | SPEC CHECKSUMS: 12 | SwiftMultiSelect: f7ad593963bc64810487d1d59c366df2ed39326b 13 | 14 | PODFILE CHECKSUM: aab54105cbfac083eacb873aac5dddec936e159c 15 | 16 | COCOAPODS: 1.3.0.beta.1 17 | -------------------------------------------------------------------------------- /SwiftMultiSelectExample/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 | 0BEAAA66012ACDF222158C088EA1EC98 /* SwiftMultiSelect-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 625F3DC744055124C9CBDF9382061C73 /* SwiftMultiSelect-dummy.m */; }; 11 | 236D358807826EA506F58FF8A37F55E9 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D88AAE1F92055A60CC2FC970D7D34634 /* Foundation.framework */; }; 12 | 23F55CF7D4EF2BA2658B4A73DFC2AE2A /* Pods-SwiftMultiSelectExample-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 08DA79F605BC04D05057EFE81A5CB008 /* Pods-SwiftMultiSelectExample-dummy.m */; }; 13 | 2C8C3BDE5B53C084CBCC039524438348 /* Pods-SwiftMultiSelectExample-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = EBEAD688B1630E39500EF527BEF4DADB /* Pods-SwiftMultiSelectExample-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; 14 | 3264E69EF1EC4E08FA1899DE15F9939F /* MultiSelectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9D4F9928BCE0C561E7FD3C26AB2C4E0 /* MultiSelectionViewController.swift */; }; 15 | 4847B650951E610C9BA6ABEACE41F81D /* CustomTableCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D4E1F52F6E76EBC962D45A4F6138BF4 /* CustomTableCell.swift */; }; 16 | 5F18C4F27ACB68F4C07E7B164DFF3BC4 /* MultiSelectionTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C670599C8E81C659808C1AA4D0C62A9 /* MultiSelectionTableView.swift */; }; 17 | 609A0E1022034522689B8A874AD59B1E /* CustomCollectionCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A092B2402E853C071F4ABBAA6C2865B /* CustomCollectionCell.swift */; }; 18 | 8125568154F27F0D8AC19A2A2A5FAAD1 /* SwiftMultiSelect-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = D37757AEBE43FB1C5D5A465E7E0EFB2C /* SwiftMultiSelect-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; 19 | 8D81CCCC0F54BAC9EAD50B04A00337A4 /* SwiftMultiSelect.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5951048D102AABD7FC14240F8517497B /* SwiftMultiSelect.swift */; }; 20 | B06767207A8FF0B1F8DDA4860DFC176E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 52C6B06BE06DABCF45ED0D9191D244E3 /* Assets.xcassets */; }; 21 | BA96A509168C7BE88998BFEECFE81F2E /* ContactsLibrary.swift in Sources */ = {isa = PBXBuildFile; fileRef = 547CA702E55560018EF85DBD60C6666B /* ContactsLibrary.swift */; }; 22 | C390041BF2EAA5C151EB156D9887690E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D88AAE1F92055A60CC2FC970D7D34634 /* Foundation.framework */; }; 23 | E4C6C03AD12C189A881C38A31B29270B /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B63C6A64CF66340668996F78DA6BB482 /* UIKit.framework */; }; 24 | F9EDC8216A095FD93AB29E7DBB735ECC /* MultiSelectionCollectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C877646BD51220588BEB7C45F04B2987 /* MultiSelectionCollectionView.swift */; }; 25 | /* End PBXBuildFile section */ 26 | 27 | /* Begin PBXContainerItemProxy section */ 28 | ADF6910295993ABE9F1590211C3798EC /* PBXContainerItemProxy */ = { 29 | isa = PBXContainerItemProxy; 30 | containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; 31 | proxyType = 1; 32 | remoteGlobalIDString = E4878A69C8B5391B2485FBF9E51BFB57; 33 | remoteInfo = SwiftMultiSelect; 34 | }; 35 | /* End PBXContainerItemProxy section */ 36 | 37 | /* Begin PBXFileReference section */ 38 | 0680D02F86EAA08ED3F9ABC3743D8EDF /* Pods-SwiftMultiSelectExample-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-SwiftMultiSelectExample-acknowledgements.markdown"; sourceTree = ""; }; 39 | 08DA79F605BC04D05057EFE81A5CB008 /* Pods-SwiftMultiSelectExample-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-SwiftMultiSelectExample-dummy.m"; sourceTree = ""; }; 40 | 0A092B2402E853C071F4ABBAA6C2865B /* CustomCollectionCell.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = CustomCollectionCell.swift; sourceTree = ""; }; 41 | 0D4E1F52F6E76EBC962D45A4F6138BF4 /* CustomTableCell.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = CustomTableCell.swift; sourceTree = ""; }; 42 | 2C670599C8E81C659808C1AA4D0C62A9 /* MultiSelectionTableView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = MultiSelectionTableView.swift; sourceTree = ""; }; 43 | 35808EFB77EF2AD67B563C9A79ADCFBD /* SwiftMultiSelect.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = SwiftMultiSelect.framework; path = SwiftMultiSelect.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 44 | 3E86947696A89CD08681349A69329CA4 /* SwiftMultiSelect.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; path = SwiftMultiSelect.modulemap; sourceTree = ""; }; 45 | 405344B388FA45BC823142D1A154D423 /* Pods-SwiftMultiSelectExample-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-SwiftMultiSelectExample-frameworks.sh"; sourceTree = ""; }; 46 | 5281FEF3930C2EF140B09CCC8D451E90 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 47 | 52C6B06BE06DABCF45ED0D9191D244E3 /* Assets.xcassets */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 48 | 547CA702E55560018EF85DBD60C6666B /* ContactsLibrary.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ContactsLibrary.swift; sourceTree = ""; }; 49 | 5951048D102AABD7FC14240F8517497B /* SwiftMultiSelect.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = SwiftMultiSelect.swift; sourceTree = ""; }; 50 | 5E471611BE134725EDD835EF8ACFAE77 /* Pods-SwiftMultiSelectExample.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; path = "Pods-SwiftMultiSelectExample.modulemap"; sourceTree = ""; }; 51 | 625F3DC744055124C9CBDF9382061C73 /* SwiftMultiSelect-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "SwiftMultiSelect-dummy.m"; sourceTree = ""; }; 52 | 64282000BE654C78F4BEB0D224B440DA /* SwiftMultiSelect-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwiftMultiSelect-prefix.pch"; sourceTree = ""; }; 53 | 93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 54 | A96F631BD152F1A3E12B03F55396C78C /* Pods_SwiftMultiSelectExample.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Pods_SwiftMultiSelectExample.framework; path = "Pods-SwiftMultiSelectExample.framework"; sourceTree = BUILT_PRODUCTS_DIR; }; 55 | AB828CAC30C41B9B44CD1E551E24346F /* Pods-SwiftMultiSelectExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-SwiftMultiSelectExample.release.xcconfig"; sourceTree = ""; }; 56 | ADB83487D503902B865864A56F0D2873 /* Pods-SwiftMultiSelectExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-SwiftMultiSelectExample.debug.xcconfig"; sourceTree = ""; }; 57 | B63C6A64CF66340668996F78DA6BB482 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.3.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; }; 58 | B7A870670BA51AE80809F0A981CC59D3 /* Pods-SwiftMultiSelectExample-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-SwiftMultiSelectExample-acknowledgements.plist"; sourceTree = ""; }; 59 | BA1327F00AA288D20A83800EF1C2B334 /* SwiftMultiSelect.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwiftMultiSelect.xcconfig; sourceTree = ""; }; 60 | C877646BD51220588BEB7C45F04B2987 /* MultiSelectionCollectionView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = MultiSelectionCollectionView.swift; sourceTree = ""; }; 61 | CA5AF7B0CB0375C338643E76F3087CB1 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 62 | D37757AEBE43FB1C5D5A465E7E0EFB2C /* SwiftMultiSelect-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwiftMultiSelect-umbrella.h"; sourceTree = ""; }; 63 | D774336E2B280A8645095605388E7596 /* Pods-SwiftMultiSelectExample-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-SwiftMultiSelectExample-resources.sh"; sourceTree = ""; }; 64 | D88AAE1F92055A60CC2FC970D7D34634 /* 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; }; 65 | E9D4F9928BCE0C561E7FD3C26AB2C4E0 /* MultiSelectionViewController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = MultiSelectionViewController.swift; sourceTree = ""; }; 66 | EBEAD688B1630E39500EF527BEF4DADB /* Pods-SwiftMultiSelectExample-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-SwiftMultiSelectExample-umbrella.h"; sourceTree = ""; }; 67 | /* End PBXFileReference section */ 68 | 69 | /* Begin PBXFrameworksBuildPhase section */ 70 | 3D99B8ACDD6EAF1031B5C47BD738B05B /* Frameworks */ = { 71 | isa = PBXFrameworksBuildPhase; 72 | buildActionMask = 2147483647; 73 | files = ( 74 | C390041BF2EAA5C151EB156D9887690E /* Foundation.framework in Frameworks */, 75 | E4C6C03AD12C189A881C38A31B29270B /* UIKit.framework in Frameworks */, 76 | ); 77 | runOnlyForDeploymentPostprocessing = 0; 78 | }; 79 | D568858BBE394AD09A64B2E2EECE57F7 /* Frameworks */ = { 80 | isa = PBXFrameworksBuildPhase; 81 | buildActionMask = 2147483647; 82 | files = ( 83 | 236D358807826EA506F58FF8A37F55E9 /* Foundation.framework in Frameworks */, 84 | ); 85 | runOnlyForDeploymentPostprocessing = 0; 86 | }; 87 | /* End PBXFrameworksBuildPhase section */ 88 | 89 | /* Begin PBXGroup section */ 90 | 022E1DE2F4038687B6AEC30EF543BC47 /* SwiftMultiSelect */ = { 91 | isa = PBXGroup; 92 | children = ( 93 | B804A8F33B9CFE20D8C5AFB829671757 /* Assets */, 94 | ); 95 | name = SwiftMultiSelect; 96 | path = SwiftMultiSelect; 97 | sourceTree = ""; 98 | }; 99 | 046511239F73018774955DCEDCE4B132 /* Development Pods */ = { 100 | isa = PBXGroup; 101 | children = ( 102 | 32B8F9D3DC4C813EF8A9D7738445F7A0 /* SwiftMultiSelect */, 103 | ); 104 | name = "Development Pods"; 105 | sourceTree = ""; 106 | }; 107 | 32B8F9D3DC4C813EF8A9D7738445F7A0 /* SwiftMultiSelect */ = { 108 | isa = PBXGroup; 109 | children = ( 110 | 3AA2D4863D25966EA164019149FCB906 /* Resources */, 111 | 4DAF1DEFBC7B680278F02BA8B56BEF96 /* Support Files */, 112 | 82FA19CDA7223A8A060FA5BCFFA27465 /* SwiftMultiSelect */, 113 | ); 114 | name = SwiftMultiSelect; 115 | path = ../..; 116 | sourceTree = ""; 117 | }; 118 | 3AA2D4863D25966EA164019149FCB906 /* Resources */ = { 119 | isa = PBXGroup; 120 | children = ( 121 | 022E1DE2F4038687B6AEC30EF543BC47 /* SwiftMultiSelect */, 122 | ); 123 | name = Resources; 124 | sourceTree = ""; 125 | }; 126 | 433CD3331B6C3787F473C941B61FC68F /* Frameworks */ = { 127 | isa = PBXGroup; 128 | children = ( 129 | 438B396F6B4147076630CAEFE34282C1 /* iOS */, 130 | ); 131 | name = Frameworks; 132 | sourceTree = ""; 133 | }; 134 | 438B396F6B4147076630CAEFE34282C1 /* iOS */ = { 135 | isa = PBXGroup; 136 | children = ( 137 | D88AAE1F92055A60CC2FC970D7D34634 /* Foundation.framework */, 138 | B63C6A64CF66340668996F78DA6BB482 /* UIKit.framework */, 139 | ); 140 | name = iOS; 141 | sourceTree = ""; 142 | }; 143 | 4DAF1DEFBC7B680278F02BA8B56BEF96 /* Support Files */ = { 144 | isa = PBXGroup; 145 | children = ( 146 | 5281FEF3930C2EF140B09CCC8D451E90 /* Info.plist */, 147 | 3E86947696A89CD08681349A69329CA4 /* SwiftMultiSelect.modulemap */, 148 | BA1327F00AA288D20A83800EF1C2B334 /* SwiftMultiSelect.xcconfig */, 149 | 625F3DC744055124C9CBDF9382061C73 /* SwiftMultiSelect-dummy.m */, 150 | 64282000BE654C78F4BEB0D224B440DA /* SwiftMultiSelect-prefix.pch */, 151 | D37757AEBE43FB1C5D5A465E7E0EFB2C /* SwiftMultiSelect-umbrella.h */, 152 | ); 153 | name = "Support Files"; 154 | path = "SwiftMultiSelectExample/Pods/Target Support Files/SwiftMultiSelect"; 155 | sourceTree = ""; 156 | }; 157 | 593E38AB241981118EEA217B603745A8 /* Pods-SwiftMultiSelectExample */ = { 158 | isa = PBXGroup; 159 | children = ( 160 | CA5AF7B0CB0375C338643E76F3087CB1 /* Info.plist */, 161 | 5E471611BE134725EDD835EF8ACFAE77 /* Pods-SwiftMultiSelectExample.modulemap */, 162 | 0680D02F86EAA08ED3F9ABC3743D8EDF /* Pods-SwiftMultiSelectExample-acknowledgements.markdown */, 163 | B7A870670BA51AE80809F0A981CC59D3 /* Pods-SwiftMultiSelectExample-acknowledgements.plist */, 164 | 08DA79F605BC04D05057EFE81A5CB008 /* Pods-SwiftMultiSelectExample-dummy.m */, 165 | 405344B388FA45BC823142D1A154D423 /* Pods-SwiftMultiSelectExample-frameworks.sh */, 166 | D774336E2B280A8645095605388E7596 /* Pods-SwiftMultiSelectExample-resources.sh */, 167 | EBEAD688B1630E39500EF527BEF4DADB /* Pods-SwiftMultiSelectExample-umbrella.h */, 168 | ADB83487D503902B865864A56F0D2873 /* Pods-SwiftMultiSelectExample.debug.xcconfig */, 169 | AB828CAC30C41B9B44CD1E551E24346F /* Pods-SwiftMultiSelectExample.release.xcconfig */, 170 | ); 171 | name = "Pods-SwiftMultiSelectExample"; 172 | path = "Target Support Files/Pods-SwiftMultiSelectExample"; 173 | sourceTree = ""; 174 | }; 175 | 7DB346D0F39D3F0E887471402A8071AB = { 176 | isa = PBXGroup; 177 | children = ( 178 | 93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */, 179 | 046511239F73018774955DCEDCE4B132 /* Development Pods */, 180 | 433CD3331B6C3787F473C941B61FC68F /* Frameworks */, 181 | 8B3A8F35F9C479EB7193FB958E4E6316 /* Products */, 182 | F9AEF95FBA598B137188A76C4E96F61D /* Targets Support Files */, 183 | ); 184 | sourceTree = ""; 185 | }; 186 | 82FA19CDA7223A8A060FA5BCFFA27465 /* SwiftMultiSelect */ = { 187 | isa = PBXGroup; 188 | children = ( 189 | 547CA702E55560018EF85DBD60C6666B /* ContactsLibrary.swift */, 190 | 0A092B2402E853C071F4ABBAA6C2865B /* CustomCollectionCell.swift */, 191 | 0D4E1F52F6E76EBC962D45A4F6138BF4 /* CustomTableCell.swift */, 192 | C877646BD51220588BEB7C45F04B2987 /* MultiSelectionCollectionView.swift */, 193 | 2C670599C8E81C659808C1AA4D0C62A9 /* MultiSelectionTableView.swift */, 194 | E9D4F9928BCE0C561E7FD3C26AB2C4E0 /* MultiSelectionViewController.swift */, 195 | 5951048D102AABD7FC14240F8517497B /* SwiftMultiSelect.swift */, 196 | ); 197 | name = SwiftMultiSelect; 198 | path = SwiftMultiSelect; 199 | sourceTree = ""; 200 | }; 201 | 8B3A8F35F9C479EB7193FB958E4E6316 /* Products */ = { 202 | isa = PBXGroup; 203 | children = ( 204 | A96F631BD152F1A3E12B03F55396C78C /* Pods_SwiftMultiSelectExample.framework */, 205 | 35808EFB77EF2AD67B563C9A79ADCFBD /* SwiftMultiSelect.framework */, 206 | ); 207 | name = Products; 208 | sourceTree = ""; 209 | }; 210 | B804A8F33B9CFE20D8C5AFB829671757 /* Assets */ = { 211 | isa = PBXGroup; 212 | children = ( 213 | 52C6B06BE06DABCF45ED0D9191D244E3 /* Assets.xcassets */, 214 | ); 215 | name = Assets; 216 | path = Assets; 217 | sourceTree = ""; 218 | }; 219 | F9AEF95FBA598B137188A76C4E96F61D /* Targets Support Files */ = { 220 | isa = PBXGroup; 221 | children = ( 222 | 593E38AB241981118EEA217B603745A8 /* Pods-SwiftMultiSelectExample */, 223 | ); 224 | name = "Targets Support Files"; 225 | sourceTree = ""; 226 | }; 227 | /* End PBXGroup section */ 228 | 229 | /* Begin PBXHeadersBuildPhase section */ 230 | 55F5A1ADA17033EED9BDF77270BF7B6A /* Headers */ = { 231 | isa = PBXHeadersBuildPhase; 232 | buildActionMask = 2147483647; 233 | files = ( 234 | 8125568154F27F0D8AC19A2A2A5FAAD1 /* SwiftMultiSelect-umbrella.h in Headers */, 235 | ); 236 | runOnlyForDeploymentPostprocessing = 0; 237 | }; 238 | 6FFB2FDB091B2019273166B14104B707 /* Headers */ = { 239 | isa = PBXHeadersBuildPhase; 240 | buildActionMask = 2147483647; 241 | files = ( 242 | 2C8C3BDE5B53C084CBCC039524438348 /* Pods-SwiftMultiSelectExample-umbrella.h in Headers */, 243 | ); 244 | runOnlyForDeploymentPostprocessing = 0; 245 | }; 246 | /* End PBXHeadersBuildPhase section */ 247 | 248 | /* Begin PBXNativeTarget section */ 249 | 4E5EFBD9269CFC1A5A1ABE06C322EE6C /* Pods-SwiftMultiSelectExample */ = { 250 | isa = PBXNativeTarget; 251 | buildConfigurationList = 19452DC347FB02841ACA6D907B936C4A /* Build configuration list for PBXNativeTarget "Pods-SwiftMultiSelectExample" */; 252 | buildPhases = ( 253 | CEE9494AD2F35C9BFE6EB5A6DB5993FD /* Sources */, 254 | D568858BBE394AD09A64B2E2EECE57F7 /* Frameworks */, 255 | 6FFB2FDB091B2019273166B14104B707 /* Headers */, 256 | ); 257 | buildRules = ( 258 | ); 259 | dependencies = ( 260 | 061D1C2BA51F58A22AD8A5CE766891BC /* PBXTargetDependency */, 261 | ); 262 | name = "Pods-SwiftMultiSelectExample"; 263 | productName = "Pods-SwiftMultiSelectExample"; 264 | productReference = A96F631BD152F1A3E12B03F55396C78C /* Pods_SwiftMultiSelectExample.framework */; 265 | productType = "com.apple.product-type.framework"; 266 | }; 267 | E4878A69C8B5391B2485FBF9E51BFB57 /* SwiftMultiSelect */ = { 268 | isa = PBXNativeTarget; 269 | buildConfigurationList = A36F8080D17CA5C1C65047105FA4C61B /* Build configuration list for PBXNativeTarget "SwiftMultiSelect" */; 270 | buildPhases = ( 271 | 403A599688FAABB4C2BF11166EDA3C0F /* Sources */, 272 | 3D99B8ACDD6EAF1031B5C47BD738B05B /* Frameworks */, 273 | 00146D9BCE92C2D3506A19A8F7D64C70 /* Resources */, 274 | 55F5A1ADA17033EED9BDF77270BF7B6A /* Headers */, 275 | ); 276 | buildRules = ( 277 | ); 278 | dependencies = ( 279 | ); 280 | name = SwiftMultiSelect; 281 | productName = SwiftMultiSelect; 282 | productReference = 35808EFB77EF2AD67B563C9A79ADCFBD /* SwiftMultiSelect.framework */; 283 | productType = "com.apple.product-type.framework"; 284 | }; 285 | /* End PBXNativeTarget section */ 286 | 287 | /* Begin PBXProject section */ 288 | D41D8CD98F00B204E9800998ECF8427E /* Project object */ = { 289 | isa = PBXProject; 290 | attributes = { 291 | LastSwiftUpdateCheck = 0830; 292 | LastUpgradeCheck = 0700; 293 | }; 294 | buildConfigurationList = 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */; 295 | compatibilityVersion = "Xcode 3.2"; 296 | developmentRegion = English; 297 | hasScannedForEncodings = 0; 298 | knownRegions = ( 299 | en, 300 | ); 301 | mainGroup = 7DB346D0F39D3F0E887471402A8071AB; 302 | productRefGroup = 8B3A8F35F9C479EB7193FB958E4E6316 /* Products */; 303 | projectDirPath = ""; 304 | projectRoot = ""; 305 | targets = ( 306 | 4E5EFBD9269CFC1A5A1ABE06C322EE6C /* Pods-SwiftMultiSelectExample */, 307 | E4878A69C8B5391B2485FBF9E51BFB57 /* SwiftMultiSelect */, 308 | ); 309 | }; 310 | /* End PBXProject section */ 311 | 312 | /* Begin PBXResourcesBuildPhase section */ 313 | 00146D9BCE92C2D3506A19A8F7D64C70 /* Resources */ = { 314 | isa = PBXResourcesBuildPhase; 315 | buildActionMask = 2147483647; 316 | files = ( 317 | B06767207A8FF0B1F8DDA4860DFC176E /* Assets.xcassets in Resources */, 318 | ); 319 | runOnlyForDeploymentPostprocessing = 0; 320 | }; 321 | /* End PBXResourcesBuildPhase section */ 322 | 323 | /* Begin PBXSourcesBuildPhase section */ 324 | 403A599688FAABB4C2BF11166EDA3C0F /* Sources */ = { 325 | isa = PBXSourcesBuildPhase; 326 | buildActionMask = 2147483647; 327 | files = ( 328 | BA96A509168C7BE88998BFEECFE81F2E /* ContactsLibrary.swift in Sources */, 329 | 609A0E1022034522689B8A874AD59B1E /* CustomCollectionCell.swift in Sources */, 330 | 4847B650951E610C9BA6ABEACE41F81D /* CustomTableCell.swift in Sources */, 331 | F9EDC8216A095FD93AB29E7DBB735ECC /* MultiSelectionCollectionView.swift in Sources */, 332 | 5F18C4F27ACB68F4C07E7B164DFF3BC4 /* MultiSelectionTableView.swift in Sources */, 333 | 3264E69EF1EC4E08FA1899DE15F9939F /* MultiSelectionViewController.swift in Sources */, 334 | 0BEAAA66012ACDF222158C088EA1EC98 /* SwiftMultiSelect-dummy.m in Sources */, 335 | 8D81CCCC0F54BAC9EAD50B04A00337A4 /* SwiftMultiSelect.swift in Sources */, 336 | ); 337 | runOnlyForDeploymentPostprocessing = 0; 338 | }; 339 | CEE9494AD2F35C9BFE6EB5A6DB5993FD /* Sources */ = { 340 | isa = PBXSourcesBuildPhase; 341 | buildActionMask = 2147483647; 342 | files = ( 343 | 23F55CF7D4EF2BA2658B4A73DFC2AE2A /* Pods-SwiftMultiSelectExample-dummy.m in Sources */, 344 | ); 345 | runOnlyForDeploymentPostprocessing = 0; 346 | }; 347 | /* End PBXSourcesBuildPhase section */ 348 | 349 | /* Begin PBXTargetDependency section */ 350 | 061D1C2BA51F58A22AD8A5CE766891BC /* PBXTargetDependency */ = { 351 | isa = PBXTargetDependency; 352 | name = SwiftMultiSelect; 353 | target = E4878A69C8B5391B2485FBF9E51BFB57 /* SwiftMultiSelect */; 354 | targetProxy = ADF6910295993ABE9F1590211C3798EC /* PBXContainerItemProxy */; 355 | }; 356 | /* End PBXTargetDependency section */ 357 | 358 | /* Begin XCBuildConfiguration section */ 359 | 66A2B529CD703362A9110801CACBB77B /* Release */ = { 360 | isa = XCBuildConfiguration; 361 | baseConfigurationReference = AB828CAC30C41B9B44CD1E551E24346F /* Pods-SwiftMultiSelectExample.release.xcconfig */; 362 | buildSettings = { 363 | CODE_SIGN_IDENTITY = ""; 364 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 365 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 366 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 367 | CURRENT_PROJECT_VERSION = 1; 368 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 369 | DEFINES_MODULE = YES; 370 | DYLIB_COMPATIBILITY_VERSION = 1; 371 | DYLIB_CURRENT_VERSION = 1; 372 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 373 | ENABLE_STRICT_OBJC_MSGSEND = YES; 374 | GCC_NO_COMMON_BLOCKS = YES; 375 | INFOPLIST_FILE = "Target Support Files/Pods-SwiftMultiSelectExample/Info.plist"; 376 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 377 | IPHONEOS_DEPLOYMENT_TARGET = 10.3; 378 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 379 | MACH_O_TYPE = staticlib; 380 | MODULEMAP_FILE = "Target Support Files/Pods-SwiftMultiSelectExample/Pods-SwiftMultiSelectExample.modulemap"; 381 | MTL_ENABLE_DEBUG_INFO = NO; 382 | OTHER_LDFLAGS = ""; 383 | OTHER_LIBTOOLFLAGS = ""; 384 | PODS_ROOT = "$(SRCROOT)"; 385 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; 386 | PRODUCT_NAME = Pods_SwiftMultiSelectExample; 387 | SDKROOT = iphoneos; 388 | SKIP_INSTALL = YES; 389 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 390 | SWIFT_VERSION = 3.0; 391 | TARGETED_DEVICE_FAMILY = "1,2"; 392 | VERSIONING_SYSTEM = "apple-generic"; 393 | VERSION_INFO_PREFIX = ""; 394 | }; 395 | name = Release; 396 | }; 397 | 707B86CFB21B645E37109F39754D4051 /* Release */ = { 398 | isa = XCBuildConfiguration; 399 | buildSettings = { 400 | ALWAYS_SEARCH_USER_PATHS = NO; 401 | CLANG_ANALYZER_NONNULL = YES; 402 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES; 403 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 404 | CLANG_CXX_LIBRARY = "libc++"; 405 | CLANG_ENABLE_MODULES = YES; 406 | CLANG_ENABLE_OBJC_ARC = YES; 407 | CLANG_WARN_BOOL_CONVERSION = YES; 408 | CLANG_WARN_CONSTANT_CONVERSION = YES; 409 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES; 410 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 411 | CLANG_WARN_EMPTY_BODY = YES; 412 | CLANG_WARN_ENUM_CONVERSION = YES; 413 | CLANG_WARN_INFINITE_RECURSION = YES; 414 | CLANG_WARN_INT_CONVERSION = YES; 415 | CLANG_WARN_OBJC_ROOT_CLASS = YES; 416 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 417 | CLANG_WARN_UNREACHABLE_CODE = YES; 418 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 419 | CODE_SIGNING_REQUIRED = NO; 420 | COPY_PHASE_STRIP = YES; 421 | ENABLE_NS_ASSERTIONS = NO; 422 | GCC_C_LANGUAGE_STANDARD = gnu99; 423 | GCC_PREPROCESSOR_DEFINITIONS = ( 424 | "POD_CONFIGURATION_RELEASE=1", 425 | "$(inherited)", 426 | ); 427 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 428 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 429 | GCC_WARN_UNDECLARED_SELECTOR = YES; 430 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 431 | GCC_WARN_UNUSED_FUNCTION = YES; 432 | GCC_WARN_UNUSED_VARIABLE = YES; 433 | IPHONEOS_DEPLOYMENT_TARGET = 10.3; 434 | PROVISIONING_PROFILE_SPECIFIER = NO_SIGNING/; 435 | STRIP_INSTALLED_PRODUCT = NO; 436 | SYMROOT = "${SRCROOT}/../build"; 437 | VALIDATE_PRODUCT = YES; 438 | }; 439 | name = Release; 440 | }; 441 | 9BAB75E24E779F6E792F3BEAC3BA15F1 /* Release */ = { 442 | isa = XCBuildConfiguration; 443 | baseConfigurationReference = BA1327F00AA288D20A83800EF1C2B334 /* SwiftMultiSelect.xcconfig */; 444 | buildSettings = { 445 | CODE_SIGN_IDENTITY = ""; 446 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 447 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 448 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 449 | CURRENT_PROJECT_VERSION = 1; 450 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 451 | DEFINES_MODULE = YES; 452 | DYLIB_COMPATIBILITY_VERSION = 1; 453 | DYLIB_CURRENT_VERSION = 1; 454 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 455 | ENABLE_STRICT_OBJC_MSGSEND = YES; 456 | GCC_NO_COMMON_BLOCKS = YES; 457 | GCC_PREFIX_HEADER = "Target Support Files/SwiftMultiSelect/SwiftMultiSelect-prefix.pch"; 458 | INFOPLIST_FILE = "Target Support Files/SwiftMultiSelect/Info.plist"; 459 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 460 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 461 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 462 | MODULEMAP_FILE = "Target Support Files/SwiftMultiSelect/SwiftMultiSelect.modulemap"; 463 | MTL_ENABLE_DEBUG_INFO = NO; 464 | PRODUCT_NAME = SwiftMultiSelect; 465 | SDKROOT = iphoneos; 466 | SKIP_INSTALL = YES; 467 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; 468 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 469 | SWIFT_VERSION = 3.0; 470 | TARGETED_DEVICE_FAMILY = "1,2"; 471 | VERSIONING_SYSTEM = "apple-generic"; 472 | VERSION_INFO_PREFIX = ""; 473 | }; 474 | name = Release; 475 | }; 476 | A7E615CDAAE1128DE884709B85BB8D7F /* Debug */ = { 477 | isa = XCBuildConfiguration; 478 | baseConfigurationReference = ADB83487D503902B865864A56F0D2873 /* Pods-SwiftMultiSelectExample.debug.xcconfig */; 479 | buildSettings = { 480 | CODE_SIGN_IDENTITY = ""; 481 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 482 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 483 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 484 | CURRENT_PROJECT_VERSION = 1; 485 | DEBUG_INFORMATION_FORMAT = dwarf; 486 | DEFINES_MODULE = YES; 487 | DYLIB_COMPATIBILITY_VERSION = 1; 488 | DYLIB_CURRENT_VERSION = 1; 489 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 490 | ENABLE_STRICT_OBJC_MSGSEND = YES; 491 | GCC_NO_COMMON_BLOCKS = YES; 492 | INFOPLIST_FILE = "Target Support Files/Pods-SwiftMultiSelectExample/Info.plist"; 493 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 494 | IPHONEOS_DEPLOYMENT_TARGET = 10.3; 495 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 496 | MACH_O_TYPE = staticlib; 497 | MODULEMAP_FILE = "Target Support Files/Pods-SwiftMultiSelectExample/Pods-SwiftMultiSelectExample.modulemap"; 498 | MTL_ENABLE_DEBUG_INFO = YES; 499 | OTHER_LDFLAGS = ""; 500 | OTHER_LIBTOOLFLAGS = ""; 501 | PODS_ROOT = "$(SRCROOT)"; 502 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; 503 | PRODUCT_NAME = Pods_SwiftMultiSelectExample; 504 | SDKROOT = iphoneos; 505 | SKIP_INSTALL = YES; 506 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 507 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 508 | SWIFT_VERSION = 3.0; 509 | TARGETED_DEVICE_FAMILY = "1,2"; 510 | VERSIONING_SYSTEM = "apple-generic"; 511 | VERSION_INFO_PREFIX = ""; 512 | }; 513 | name = Debug; 514 | }; 515 | EF26A3C5B6EDA309192C6025F703DE0A /* Debug */ = { 516 | isa = XCBuildConfiguration; 517 | buildSettings = { 518 | ALWAYS_SEARCH_USER_PATHS = NO; 519 | CLANG_ANALYZER_NONNULL = YES; 520 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES; 521 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 522 | CLANG_CXX_LIBRARY = "libc++"; 523 | CLANG_ENABLE_MODULES = YES; 524 | CLANG_ENABLE_OBJC_ARC = YES; 525 | CLANG_WARN_BOOL_CONVERSION = YES; 526 | CLANG_WARN_CONSTANT_CONVERSION = YES; 527 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES; 528 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 529 | CLANG_WARN_EMPTY_BODY = YES; 530 | CLANG_WARN_ENUM_CONVERSION = YES; 531 | CLANG_WARN_INFINITE_RECURSION = YES; 532 | CLANG_WARN_INT_CONVERSION = YES; 533 | CLANG_WARN_OBJC_ROOT_CLASS = YES; 534 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 535 | CLANG_WARN_UNREACHABLE_CODE = YES; 536 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 537 | CODE_SIGNING_REQUIRED = NO; 538 | COPY_PHASE_STRIP = NO; 539 | ENABLE_TESTABILITY = YES; 540 | GCC_C_LANGUAGE_STANDARD = gnu99; 541 | GCC_DYNAMIC_NO_PIC = NO; 542 | GCC_OPTIMIZATION_LEVEL = 0; 543 | GCC_PREPROCESSOR_DEFINITIONS = ( 544 | "POD_CONFIGURATION_DEBUG=1", 545 | "DEBUG=1", 546 | "$(inherited)", 547 | ); 548 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 549 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 550 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 551 | GCC_WARN_UNDECLARED_SELECTOR = YES; 552 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 553 | GCC_WARN_UNUSED_FUNCTION = YES; 554 | GCC_WARN_UNUSED_VARIABLE = YES; 555 | IPHONEOS_DEPLOYMENT_TARGET = 10.3; 556 | ONLY_ACTIVE_ARCH = YES; 557 | PROVISIONING_PROFILE_SPECIFIER = NO_SIGNING/; 558 | STRIP_INSTALLED_PRODUCT = NO; 559 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 560 | SYMROOT = "${SRCROOT}/../build"; 561 | }; 562 | name = Debug; 563 | }; 564 | FBC66206E2E005F6B2B854A5A42C080B /* Debug */ = { 565 | isa = XCBuildConfiguration; 566 | baseConfigurationReference = BA1327F00AA288D20A83800EF1C2B334 /* SwiftMultiSelect.xcconfig */; 567 | buildSettings = { 568 | CODE_SIGN_IDENTITY = ""; 569 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 570 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 571 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 572 | CURRENT_PROJECT_VERSION = 1; 573 | DEBUG_INFORMATION_FORMAT = dwarf; 574 | DEFINES_MODULE = YES; 575 | DYLIB_COMPATIBILITY_VERSION = 1; 576 | DYLIB_CURRENT_VERSION = 1; 577 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 578 | ENABLE_STRICT_OBJC_MSGSEND = YES; 579 | GCC_NO_COMMON_BLOCKS = YES; 580 | GCC_PREFIX_HEADER = "Target Support Files/SwiftMultiSelect/SwiftMultiSelect-prefix.pch"; 581 | INFOPLIST_FILE = "Target Support Files/SwiftMultiSelect/Info.plist"; 582 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 583 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 584 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 585 | MODULEMAP_FILE = "Target Support Files/SwiftMultiSelect/SwiftMultiSelect.modulemap"; 586 | MTL_ENABLE_DEBUG_INFO = YES; 587 | PRODUCT_NAME = SwiftMultiSelect; 588 | SDKROOT = iphoneos; 589 | SKIP_INSTALL = YES; 590 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; 591 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 592 | SWIFT_VERSION = 3.0; 593 | TARGETED_DEVICE_FAMILY = "1,2"; 594 | VERSIONING_SYSTEM = "apple-generic"; 595 | VERSION_INFO_PREFIX = ""; 596 | }; 597 | name = Debug; 598 | }; 599 | /* End XCBuildConfiguration section */ 600 | 601 | /* Begin XCConfigurationList section */ 602 | 19452DC347FB02841ACA6D907B936C4A /* Build configuration list for PBXNativeTarget "Pods-SwiftMultiSelectExample" */ = { 603 | isa = XCConfigurationList; 604 | buildConfigurations = ( 605 | A7E615CDAAE1128DE884709B85BB8D7F /* Debug */, 606 | 66A2B529CD703362A9110801CACBB77B /* Release */, 607 | ); 608 | defaultConfigurationIsVisible = 0; 609 | defaultConfigurationName = Release; 610 | }; 611 | 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */ = { 612 | isa = XCConfigurationList; 613 | buildConfigurations = ( 614 | EF26A3C5B6EDA309192C6025F703DE0A /* Debug */, 615 | 707B86CFB21B645E37109F39754D4051 /* Release */, 616 | ); 617 | defaultConfigurationIsVisible = 0; 618 | defaultConfigurationName = Release; 619 | }; 620 | A36F8080D17CA5C1C65047105FA4C61B /* Build configuration list for PBXNativeTarget "SwiftMultiSelect" */ = { 621 | isa = XCConfigurationList; 622 | buildConfigurations = ( 623 | FBC66206E2E005F6B2B854A5A42C080B /* Debug */, 624 | 9BAB75E24E779F6E792F3BEAC3BA15F1 /* Release */, 625 | ); 626 | defaultConfigurationIsVisible = 0; 627 | defaultConfigurationName = Release; 628 | }; 629 | /* End XCConfigurationList section */ 630 | }; 631 | rootObject = D41D8CD98F00B204E9800998ECF8427E /* Project object */; 632 | } 633 | -------------------------------------------------------------------------------- /SwiftMultiSelectExample/Pods/Pods.xcodeproj/xcuserdata/frind.xcuserdatad/xcschemes/Pods-SwiftMultiSelectExample.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 66 | 67 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /SwiftMultiSelectExample/Pods/Pods.xcodeproj/xcuserdata/frind.xcuserdatad/xcschemes/SwiftMultiSelect.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 45 | 46 | 52 | 53 | 55 | 56 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /SwiftMultiSelectExample/Pods/Pods.xcodeproj/xcuserdata/frind.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Pods-SwiftMultiSelectExample.xcscheme 8 | 9 | isShown 10 | 11 | 12 | SwiftMultiSelect.xcscheme 13 | 14 | isShown 15 | 16 | 17 | 18 | SuppressBuildableAutocreation 19 | 20 | 4E5EFBD9269CFC1A5A1ABE06C322EE6C 21 | 22 | primary 23 | 24 | 25 | E4878A69C8B5391B2485FBF9E51BFB57 26 | 27 | primary 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /SwiftMultiSelectExample/Pods/Target Support Files/Pods-SwiftMultiSelectExample/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 | -------------------------------------------------------------------------------- /SwiftMultiSelectExample/Pods/Target Support Files/Pods-SwiftMultiSelectExample/Pods-SwiftMultiSelectExample-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## SwiftMultiSelect 5 | 6 | MIT License 7 | 8 | Copyright (c) 2017 Luca Becchetti 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in all 18 | copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 26 | SOFTWARE. 27 | 28 | Generated by CocoaPods - https://cocoapods.org 29 | -------------------------------------------------------------------------------- /SwiftMultiSelectExample/Pods/Target Support Files/Pods-SwiftMultiSelectExample/Pods-SwiftMultiSelectExample-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 | MIT License 18 | 19 | Copyright (c) 2017 Luca Becchetti 20 | 21 | Permission is hereby granted, free of charge, to any person obtaining a copy 22 | of this software and associated documentation files (the "Software"), to deal 23 | in the Software without restriction, including without limitation the rights 24 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 25 | copies of the Software, and to permit persons to whom the Software is 26 | furnished to do so, subject to the following conditions: 27 | 28 | The above copyright notice and this permission notice shall be included in all 29 | copies or substantial portions of the Software. 30 | 31 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 32 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 33 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 34 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 35 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 36 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 37 | SOFTWARE. 38 | 39 | License 40 | MIT 41 | Title 42 | SwiftMultiSelect 43 | Type 44 | PSGroupSpecifier 45 | 46 | 47 | FooterText 48 | Generated by CocoaPods - https://cocoapods.org 49 | Title 50 | 51 | Type 52 | PSGroupSpecifier 53 | 54 | 55 | StringsTable 56 | Acknowledgements 57 | Title 58 | Acknowledgements 59 | 60 | 61 | -------------------------------------------------------------------------------- /SwiftMultiSelectExample/Pods/Target Support Files/Pods-SwiftMultiSelectExample/Pods-SwiftMultiSelectExample-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_SwiftMultiSelectExample : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_SwiftMultiSelectExample 5 | @end 6 | -------------------------------------------------------------------------------- /SwiftMultiSelectExample/Pods/Target Support Files/Pods-SwiftMultiSelectExample/Pods-SwiftMultiSelectExample-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 | install_framework() 10 | { 11 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then 12 | local source="${BUILT_PRODUCTS_DIR}/$1" 13 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then 14 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" 15 | elif [ -r "$1" ]; then 16 | local source="$1" 17 | fi 18 | 19 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 20 | 21 | if [ -L "${source}" ]; then 22 | echo "Symlinked..." 23 | source="$(readlink "${source}")" 24 | fi 25 | 26 | # use filter instead of exclude so missing patterns dont' throw errors 27 | echo "rsync --delete -av --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" 28 | rsync --delete -av --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" 29 | 30 | local basename 31 | basename="$(basename -s .framework "$1")" 32 | binary="${destination}/${basename}.framework/${basename}" 33 | if ! [ -r "$binary" ]; then 34 | binary="${destination}/${basename}" 35 | fi 36 | 37 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 38 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then 39 | strip_invalid_archs "$binary" 40 | fi 41 | 42 | # Resign the code if required by the build settings to avoid unstable apps 43 | code_sign_if_enabled "${destination}/$(basename "$1")" 44 | 45 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. 46 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then 47 | local swift_runtime_libs 48 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) 49 | for lib in $swift_runtime_libs; do 50 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" 51 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" 52 | code_sign_if_enabled "${destination}/${lib}" 53 | done 54 | fi 55 | } 56 | 57 | # Copies the dSYM of a vendored framework 58 | install_dsym() { 59 | local source="$1" 60 | if [ -r "$source" ]; then 61 | echo "rsync --delete -av --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DWARF_DSYM_FOLDER_PATH}\"" 62 | rsync --delete -av --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DWARF_DSYM_FOLDER_PATH}" 63 | fi 64 | } 65 | 66 | # Signs a framework with the provided identity 67 | code_sign_if_enabled() { 68 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then 69 | # Use the current code_sign_identitiy 70 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" 71 | local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements '$1'" 72 | 73 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 74 | code_sign_cmd="$code_sign_cmd &" 75 | fi 76 | echo "$code_sign_cmd" 77 | eval "$code_sign_cmd" 78 | fi 79 | } 80 | 81 | # Strip invalid architectures 82 | strip_invalid_archs() { 83 | binary="$1" 84 | # Get architectures for current file 85 | archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)" 86 | stripped="" 87 | for arch in $archs; do 88 | if ! [[ "${VALID_ARCHS}" == *"$arch"* ]]; then 89 | # Strip non-valid architectures in-place 90 | lipo -remove "$arch" -output "$binary" "$binary" || exit 1 91 | stripped="$stripped $arch" 92 | fi 93 | done 94 | if [[ "$stripped" ]]; then 95 | echo "Stripped $binary of architectures:$stripped" 96 | fi 97 | } 98 | 99 | 100 | if [[ "$CONFIGURATION" == "Debug" ]]; then 101 | install_framework "$BUILT_PRODUCTS_DIR/SwiftMultiSelect/SwiftMultiSelect.framework" 102 | fi 103 | if [[ "$CONFIGURATION" == "Release" ]]; then 104 | install_framework "$BUILT_PRODUCTS_DIR/SwiftMultiSelect/SwiftMultiSelect.framework" 105 | fi 106 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 107 | wait 108 | fi 109 | -------------------------------------------------------------------------------- /SwiftMultiSelectExample/Pods/Target Support Files/Pods-SwiftMultiSelectExample/Pods-SwiftMultiSelectExample-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 | case "${TARGETED_DEVICE_FAMILY}" in 12 | 1,2) 13 | TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" 14 | ;; 15 | 1) 16 | TARGET_DEVICE_ARGS="--target-device iphone" 17 | ;; 18 | 2) 19 | TARGET_DEVICE_ARGS="--target-device ipad" 20 | ;; 21 | 3) 22 | TARGET_DEVICE_ARGS="--target-device tv" 23 | ;; 24 | 4) 25 | TARGET_DEVICE_ARGS="--target-device watch" 26 | ;; 27 | *) 28 | TARGET_DEVICE_ARGS="--target-device mac" 29 | ;; 30 | esac 31 | 32 | install_resource() 33 | { 34 | if [[ "$1" = /* ]] ; then 35 | RESOURCE_PATH="$1" 36 | else 37 | RESOURCE_PATH="${PODS_ROOT}/$1" 38 | fi 39 | if [[ ! -e "$RESOURCE_PATH" ]] ; then 40 | cat << EOM 41 | error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. 42 | EOM 43 | exit 1 44 | fi 45 | case $RESOURCE_PATH in 46 | *.storyboard) 47 | 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 48 | 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} 49 | ;; 50 | *.xib) 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\" .xib`.nib $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\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} 53 | ;; 54 | *.framework) 55 | echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true 56 | mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 57 | echo "rsync --delete -av $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true 58 | rsync --delete -av "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 59 | ;; 60 | *.xcdatamodel) 61 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" || true 62 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" 63 | ;; 64 | *.xcdatamodeld) 65 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" || true 66 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" 67 | ;; 68 | *.xcmappingmodel) 69 | echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" || true 70 | xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" 71 | ;; 72 | *.xcassets) 73 | ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH" 74 | XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") 75 | ;; 76 | *) 77 | echo "$RESOURCE_PATH" || true 78 | echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" 79 | ;; 80 | esac 81 | } 82 | 83 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 84 | rsync --delete -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 85 | if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then 86 | mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 87 | rsync --delete -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 88 | fi 89 | rm -f "$RESOURCES_TO_COPY" 90 | 91 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ] 92 | then 93 | # Find all other xcassets (this unfortunately includes those of path pods and other targets). 94 | OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) 95 | while read line; do 96 | if [[ $line != "${PODS_ROOT}*" ]]; then 97 | XCASSET_FILES+=("$line") 98 | fi 99 | done <<<"$OTHER_XCASSETS" 100 | 101 | 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}" 102 | fi 103 | -------------------------------------------------------------------------------- /SwiftMultiSelectExample/Pods/Target Support Files/Pods-SwiftMultiSelectExample/Pods-SwiftMultiSelectExample-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_SwiftMultiSelectExampleVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_SwiftMultiSelectExampleVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /SwiftMultiSelectExample/Pods/Target Support Files/Pods-SwiftMultiSelectExample/Pods-SwiftMultiSelectExample.debug.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/SwiftMultiSelect" 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/SwiftMultiSelect/SwiftMultiSelect.framework/Headers" 6 | OTHER_LDFLAGS = $(inherited) -framework "SwiftMultiSelect" 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 | -------------------------------------------------------------------------------- /SwiftMultiSelectExample/Pods/Target Support Files/Pods-SwiftMultiSelectExample/Pods-SwiftMultiSelectExample.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_SwiftMultiSelectExample { 2 | umbrella header "Pods-SwiftMultiSelectExample-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /SwiftMultiSelectExample/Pods/Target Support Files/Pods-SwiftMultiSelectExample/Pods-SwiftMultiSelectExample.release.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/SwiftMultiSelect" 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/SwiftMultiSelect/SwiftMultiSelect.framework/Headers" 6 | OTHER_LDFLAGS = $(inherited) -framework "SwiftMultiSelect" 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 | -------------------------------------------------------------------------------- /SwiftMultiSelectExample/Pods/Target Support Files/SwiftMultiSelect/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.6 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /SwiftMultiSelectExample/Pods/Target Support Files/SwiftMultiSelect/SwiftMultiSelect-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_SwiftMultiSelect : NSObject 3 | @end 4 | @implementation PodsDummy_SwiftMultiSelect 5 | @end 6 | -------------------------------------------------------------------------------- /SwiftMultiSelectExample/Pods/Target Support Files/SwiftMultiSelect/SwiftMultiSelect-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 | -------------------------------------------------------------------------------- /SwiftMultiSelectExample/Pods/Target Support Files/SwiftMultiSelect/SwiftMultiSelect-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 SwiftMultiSelectVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char SwiftMultiSelectVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /SwiftMultiSelectExample/Pods/Target Support Files/SwiftMultiSelect/SwiftMultiSelect.modulemap: -------------------------------------------------------------------------------- 1 | framework module SwiftMultiSelect { 2 | umbrella header "SwiftMultiSelect-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /SwiftMultiSelectExample/Pods/Target Support Files/SwiftMultiSelect/SwiftMultiSelect.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = $PODS_CONFIGURATION_BUILD_DIR/SwiftMultiSelect 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public" 4 | OTHER_LDFLAGS = -framework "UIKit" 5 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 6 | PODS_BUILD_DIR = $BUILD_DIR 7 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 8 | PODS_ROOT = ${SRCROOT} 9 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../.. 10 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 11 | SKIP_INSTALL = YES 12 | -------------------------------------------------------------------------------- /SwiftMultiSelectExample/SwiftMultiSelectExample.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 4EEC4B04AB2CBCA55F961220 /* Pods_SwiftMultiSelectExample.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E73FBC79F7806466052A9D4C /* Pods_SwiftMultiSelectExample.framework */; }; 11 | B1C3BCCC1F2B2B2600904FA3 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1C3BCCB1F2B2B2600904FA3 /* AppDelegate.swift */; }; 12 | B1C3BCCE1F2B2B2600904FA3 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1C3BCCD1F2B2B2600904FA3 /* ViewController.swift */; }; 13 | B1C3BCD11F2B2B2600904FA3 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B1C3BCCF1F2B2B2600904FA3 /* Main.storyboard */; }; 14 | B1C3BCD31F2B2B2600904FA3 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B1C3BCD21F2B2B2600904FA3 /* Assets.xcassets */; }; 15 | B1C3BCD61F2B2B2600904FA3 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B1C3BCD41F2B2B2600904FA3 /* LaunchScreen.storyboard */; }; 16 | /* End PBXBuildFile section */ 17 | 18 | /* Begin PBXFileReference section */ 19 | 82EE9FC18253E00CEA25297C /* Pods-SwiftMultiSelectExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SwiftMultiSelectExample.release.xcconfig"; path = "Pods/Target Support Files/Pods-SwiftMultiSelectExample/Pods-SwiftMultiSelectExample.release.xcconfig"; sourceTree = ""; }; 20 | A8F4428936230C1B080F6F03 /* Pods-SwiftMultiSelectExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SwiftMultiSelectExample.debug.xcconfig"; path = "Pods/Target Support Files/Pods-SwiftMultiSelectExample/Pods-SwiftMultiSelectExample.debug.xcconfig"; sourceTree = ""; }; 21 | B1C3BCC81F2B2B2600904FA3 /* SwiftMultiSelectExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SwiftMultiSelectExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 22 | B1C3BCCB1F2B2B2600904FA3 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 23 | B1C3BCCD1F2B2B2600904FA3 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 24 | B1C3BCD01F2B2B2600904FA3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 25 | B1C3BCD21F2B2B2600904FA3 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 26 | B1C3BCD51F2B2B2600904FA3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 27 | B1C3BCD71F2B2B2600904FA3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 28 | E73FBC79F7806466052A9D4C /* Pods_SwiftMultiSelectExample.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SwiftMultiSelectExample.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 29 | /* End PBXFileReference section */ 30 | 31 | /* Begin PBXFrameworksBuildPhase section */ 32 | B1C3BCC51F2B2B2600904FA3 /* Frameworks */ = { 33 | isa = PBXFrameworksBuildPhase; 34 | buildActionMask = 2147483647; 35 | files = ( 36 | 4EEC4B04AB2CBCA55F961220 /* Pods_SwiftMultiSelectExample.framework in Frameworks */, 37 | ); 38 | runOnlyForDeploymentPostprocessing = 0; 39 | }; 40 | /* End PBXFrameworksBuildPhase section */ 41 | 42 | /* Begin PBXGroup section */ 43 | 21898860F6666057E553CAE5 /* Pods */ = { 44 | isa = PBXGroup; 45 | children = ( 46 | A8F4428936230C1B080F6F03 /* Pods-SwiftMultiSelectExample.debug.xcconfig */, 47 | 82EE9FC18253E00CEA25297C /* Pods-SwiftMultiSelectExample.release.xcconfig */, 48 | ); 49 | name = Pods; 50 | sourceTree = ""; 51 | }; 52 | B1C3BCBF1F2B2B2600904FA3 = { 53 | isa = PBXGroup; 54 | children = ( 55 | B1C3BCCA1F2B2B2600904FA3 /* SwiftMultiSelectExample */, 56 | B1C3BCC91F2B2B2600904FA3 /* Products */, 57 | 21898860F6666057E553CAE5 /* Pods */, 58 | CCFBA34070E4549E6DB3C0D6 /* Frameworks */, 59 | ); 60 | sourceTree = ""; 61 | }; 62 | B1C3BCC91F2B2B2600904FA3 /* Products */ = { 63 | isa = PBXGroup; 64 | children = ( 65 | B1C3BCC81F2B2B2600904FA3 /* SwiftMultiSelectExample.app */, 66 | ); 67 | name = Products; 68 | sourceTree = ""; 69 | }; 70 | B1C3BCCA1F2B2B2600904FA3 /* SwiftMultiSelectExample */ = { 71 | isa = PBXGroup; 72 | children = ( 73 | B1C3BCCB1F2B2B2600904FA3 /* AppDelegate.swift */, 74 | B1C3BCCD1F2B2B2600904FA3 /* ViewController.swift */, 75 | B1C3BCCF1F2B2B2600904FA3 /* Main.storyboard */, 76 | B1C3BCD21F2B2B2600904FA3 /* Assets.xcassets */, 77 | B1C3BCD41F2B2B2600904FA3 /* LaunchScreen.storyboard */, 78 | B1C3BCD71F2B2B2600904FA3 /* Info.plist */, 79 | ); 80 | path = SwiftMultiSelectExample; 81 | sourceTree = ""; 82 | }; 83 | CCFBA34070E4549E6DB3C0D6 /* Frameworks */ = { 84 | isa = PBXGroup; 85 | children = ( 86 | E73FBC79F7806466052A9D4C /* Pods_SwiftMultiSelectExample.framework */, 87 | ); 88 | name = Frameworks; 89 | sourceTree = ""; 90 | }; 91 | /* End PBXGroup section */ 92 | 93 | /* Begin PBXNativeTarget section */ 94 | B1C3BCC71F2B2B2600904FA3 /* SwiftMultiSelectExample */ = { 95 | isa = PBXNativeTarget; 96 | buildConfigurationList = B1C3BCDA1F2B2B2600904FA3 /* Build configuration list for PBXNativeTarget "SwiftMultiSelectExample" */; 97 | buildPhases = ( 98 | DEE43819E4DCE9EA7A652529 /* [CP] Check Pods Manifest.lock */, 99 | B1C3BCC41F2B2B2600904FA3 /* Sources */, 100 | B1C3BCC51F2B2B2600904FA3 /* Frameworks */, 101 | B1C3BCC61F2B2B2600904FA3 /* Resources */, 102 | 3AC247347D87DF6CC62BABC4 /* [CP] Embed Pods Frameworks */, 103 | 8759781DEFD9615CA4754B46 /* [CP] Copy Pods Resources */, 104 | ); 105 | buildRules = ( 106 | ); 107 | dependencies = ( 108 | ); 109 | name = SwiftMultiSelectExample; 110 | productName = SwiftMultiSelectExample; 111 | productReference = B1C3BCC81F2B2B2600904FA3 /* SwiftMultiSelectExample.app */; 112 | productType = "com.apple.product-type.application"; 113 | }; 114 | /* End PBXNativeTarget section */ 115 | 116 | /* Begin PBXProject section */ 117 | B1C3BCC01F2B2B2600904FA3 /* Project object */ = { 118 | isa = PBXProject; 119 | attributes = { 120 | LastSwiftUpdateCheck = 0830; 121 | LastUpgradeCheck = 0830; 122 | ORGANIZATIONNAME = "Luca Becchetti"; 123 | TargetAttributes = { 124 | B1C3BCC71F2B2B2600904FA3 = { 125 | CreatedOnToolsVersion = 8.3.2; 126 | DevelopmentTeam = 3NJYMZCH8Y; 127 | ProvisioningStyle = Automatic; 128 | }; 129 | }; 130 | }; 131 | buildConfigurationList = B1C3BCC31F2B2B2600904FA3 /* Build configuration list for PBXProject "SwiftMultiSelectExample" */; 132 | compatibilityVersion = "Xcode 3.2"; 133 | developmentRegion = English; 134 | hasScannedForEncodings = 0; 135 | knownRegions = ( 136 | en, 137 | Base, 138 | ); 139 | mainGroup = B1C3BCBF1F2B2B2600904FA3; 140 | productRefGroup = B1C3BCC91F2B2B2600904FA3 /* Products */; 141 | projectDirPath = ""; 142 | projectRoot = ""; 143 | targets = ( 144 | B1C3BCC71F2B2B2600904FA3 /* SwiftMultiSelectExample */, 145 | ); 146 | }; 147 | /* End PBXProject section */ 148 | 149 | /* Begin PBXResourcesBuildPhase section */ 150 | B1C3BCC61F2B2B2600904FA3 /* Resources */ = { 151 | isa = PBXResourcesBuildPhase; 152 | buildActionMask = 2147483647; 153 | files = ( 154 | B1C3BCD61F2B2B2600904FA3 /* LaunchScreen.storyboard in Resources */, 155 | B1C3BCD31F2B2B2600904FA3 /* Assets.xcassets in Resources */, 156 | B1C3BCD11F2B2B2600904FA3 /* Main.storyboard in Resources */, 157 | ); 158 | runOnlyForDeploymentPostprocessing = 0; 159 | }; 160 | /* End PBXResourcesBuildPhase section */ 161 | 162 | /* Begin PBXShellScriptBuildPhase section */ 163 | 3AC247347D87DF6CC62BABC4 /* [CP] Embed Pods Frameworks */ = { 164 | isa = PBXShellScriptBuildPhase; 165 | buildActionMask = 2147483647; 166 | files = ( 167 | ); 168 | inputPaths = ( 169 | ); 170 | name = "[CP] Embed Pods Frameworks"; 171 | outputPaths = ( 172 | ); 173 | runOnlyForDeploymentPostprocessing = 0; 174 | shellPath = /bin/sh; 175 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-SwiftMultiSelectExample/Pods-SwiftMultiSelectExample-frameworks.sh\"\n"; 176 | showEnvVarsInLog = 0; 177 | }; 178 | 8759781DEFD9615CA4754B46 /* [CP] Copy Pods Resources */ = { 179 | isa = PBXShellScriptBuildPhase; 180 | buildActionMask = 2147483647; 181 | files = ( 182 | ); 183 | inputPaths = ( 184 | ); 185 | name = "[CP] Copy Pods Resources"; 186 | outputPaths = ( 187 | ); 188 | runOnlyForDeploymentPostprocessing = 0; 189 | shellPath = /bin/sh; 190 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-SwiftMultiSelectExample/Pods-SwiftMultiSelectExample-resources.sh\"\n"; 191 | showEnvVarsInLog = 0; 192 | }; 193 | DEE43819E4DCE9EA7A652529 /* [CP] Check Pods Manifest.lock */ = { 194 | isa = PBXShellScriptBuildPhase; 195 | buildActionMask = 2147483647; 196 | files = ( 197 | ); 198 | inputPaths = ( 199 | ); 200 | name = "[CP] Check Pods Manifest.lock"; 201 | outputPaths = ( 202 | ); 203 | runOnlyForDeploymentPostprocessing = 0; 204 | shellPath = /bin/sh; 205 | 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"; 206 | showEnvVarsInLog = 0; 207 | }; 208 | /* End PBXShellScriptBuildPhase section */ 209 | 210 | /* Begin PBXSourcesBuildPhase section */ 211 | B1C3BCC41F2B2B2600904FA3 /* Sources */ = { 212 | isa = PBXSourcesBuildPhase; 213 | buildActionMask = 2147483647; 214 | files = ( 215 | B1C3BCCE1F2B2B2600904FA3 /* ViewController.swift in Sources */, 216 | B1C3BCCC1F2B2B2600904FA3 /* AppDelegate.swift in Sources */, 217 | ); 218 | runOnlyForDeploymentPostprocessing = 0; 219 | }; 220 | /* End PBXSourcesBuildPhase section */ 221 | 222 | /* Begin PBXVariantGroup section */ 223 | B1C3BCCF1F2B2B2600904FA3 /* Main.storyboard */ = { 224 | isa = PBXVariantGroup; 225 | children = ( 226 | B1C3BCD01F2B2B2600904FA3 /* Base */, 227 | ); 228 | name = Main.storyboard; 229 | sourceTree = ""; 230 | }; 231 | B1C3BCD41F2B2B2600904FA3 /* LaunchScreen.storyboard */ = { 232 | isa = PBXVariantGroup; 233 | children = ( 234 | B1C3BCD51F2B2B2600904FA3 /* Base */, 235 | ); 236 | name = LaunchScreen.storyboard; 237 | sourceTree = ""; 238 | }; 239 | /* End PBXVariantGroup section */ 240 | 241 | /* Begin XCBuildConfiguration section */ 242 | B1C3BCD81F2B2B2600904FA3 /* Debug */ = { 243 | isa = XCBuildConfiguration; 244 | buildSettings = { 245 | ALWAYS_SEARCH_USER_PATHS = NO; 246 | CLANG_ANALYZER_NONNULL = YES; 247 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 248 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 249 | CLANG_CXX_LIBRARY = "libc++"; 250 | CLANG_ENABLE_MODULES = YES; 251 | CLANG_ENABLE_OBJC_ARC = YES; 252 | CLANG_WARN_BOOL_CONVERSION = YES; 253 | CLANG_WARN_CONSTANT_CONVERSION = YES; 254 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 255 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 256 | CLANG_WARN_EMPTY_BODY = YES; 257 | CLANG_WARN_ENUM_CONVERSION = YES; 258 | CLANG_WARN_INFINITE_RECURSION = YES; 259 | CLANG_WARN_INT_CONVERSION = YES; 260 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 261 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 262 | CLANG_WARN_UNREACHABLE_CODE = YES; 263 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 264 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 265 | COPY_PHASE_STRIP = NO; 266 | DEBUG_INFORMATION_FORMAT = dwarf; 267 | ENABLE_STRICT_OBJC_MSGSEND = YES; 268 | ENABLE_TESTABILITY = YES; 269 | GCC_C_LANGUAGE_STANDARD = gnu99; 270 | GCC_DYNAMIC_NO_PIC = NO; 271 | GCC_NO_COMMON_BLOCKS = YES; 272 | GCC_OPTIMIZATION_LEVEL = 0; 273 | GCC_PREPROCESSOR_DEFINITIONS = ( 274 | "DEBUG=1", 275 | "$(inherited)", 276 | ); 277 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 278 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 279 | GCC_WARN_UNDECLARED_SELECTOR = YES; 280 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 281 | GCC_WARN_UNUSED_FUNCTION = YES; 282 | GCC_WARN_UNUSED_VARIABLE = YES; 283 | IPHONEOS_DEPLOYMENT_TARGET = 10.3; 284 | MTL_ENABLE_DEBUG_INFO = YES; 285 | ONLY_ACTIVE_ARCH = YES; 286 | SDKROOT = iphoneos; 287 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 288 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 289 | SWIFT_VERSION = 4.0; 290 | }; 291 | name = Debug; 292 | }; 293 | B1C3BCD91F2B2B2600904FA3 /* Release */ = { 294 | isa = XCBuildConfiguration; 295 | buildSettings = { 296 | ALWAYS_SEARCH_USER_PATHS = NO; 297 | CLANG_ANALYZER_NONNULL = YES; 298 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 299 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 300 | CLANG_CXX_LIBRARY = "libc++"; 301 | CLANG_ENABLE_MODULES = YES; 302 | CLANG_ENABLE_OBJC_ARC = YES; 303 | CLANG_WARN_BOOL_CONVERSION = YES; 304 | CLANG_WARN_CONSTANT_CONVERSION = YES; 305 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 306 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 307 | CLANG_WARN_EMPTY_BODY = YES; 308 | CLANG_WARN_ENUM_CONVERSION = YES; 309 | CLANG_WARN_INFINITE_RECURSION = YES; 310 | CLANG_WARN_INT_CONVERSION = YES; 311 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 312 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 313 | CLANG_WARN_UNREACHABLE_CODE = YES; 314 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 315 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 316 | COPY_PHASE_STRIP = NO; 317 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 318 | ENABLE_NS_ASSERTIONS = NO; 319 | ENABLE_STRICT_OBJC_MSGSEND = YES; 320 | GCC_C_LANGUAGE_STANDARD = gnu99; 321 | GCC_NO_COMMON_BLOCKS = YES; 322 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 323 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 324 | GCC_WARN_UNDECLARED_SELECTOR = YES; 325 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 326 | GCC_WARN_UNUSED_FUNCTION = YES; 327 | GCC_WARN_UNUSED_VARIABLE = YES; 328 | IPHONEOS_DEPLOYMENT_TARGET = 10.3; 329 | MTL_ENABLE_DEBUG_INFO = NO; 330 | SDKROOT = iphoneos; 331 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 332 | SWIFT_VERSION = 4.0; 333 | VALIDATE_PRODUCT = YES; 334 | }; 335 | name = Release; 336 | }; 337 | B1C3BCDB1F2B2B2600904FA3 /* Debug */ = { 338 | isa = XCBuildConfiguration; 339 | baseConfigurationReference = A8F4428936230C1B080F6F03 /* Pods-SwiftMultiSelectExample.debug.xcconfig */; 340 | buildSettings = { 341 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 342 | DEVELOPMENT_TEAM = 3NJYMZCH8Y; 343 | INFOPLIST_FILE = SwiftMultiSelectExample/Info.plist; 344 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 345 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 346 | PRODUCT_BUNDLE_IDENTIFIER = it.brokenice.SwiftMultiSelectExample; 347 | PRODUCT_NAME = "$(TARGET_NAME)"; 348 | SWIFT_VERSION = 4.0; 349 | }; 350 | name = Debug; 351 | }; 352 | B1C3BCDC1F2B2B2600904FA3 /* Release */ = { 353 | isa = XCBuildConfiguration; 354 | baseConfigurationReference = 82EE9FC18253E00CEA25297C /* Pods-SwiftMultiSelectExample.release.xcconfig */; 355 | buildSettings = { 356 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 357 | DEVELOPMENT_TEAM = 3NJYMZCH8Y; 358 | INFOPLIST_FILE = SwiftMultiSelectExample/Info.plist; 359 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 360 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 361 | PRODUCT_BUNDLE_IDENTIFIER = it.brokenice.SwiftMultiSelectExample; 362 | PRODUCT_NAME = "$(TARGET_NAME)"; 363 | SWIFT_VERSION = 4.0; 364 | }; 365 | name = Release; 366 | }; 367 | /* End XCBuildConfiguration section */ 368 | 369 | /* Begin XCConfigurationList section */ 370 | B1C3BCC31F2B2B2600904FA3 /* Build configuration list for PBXProject "SwiftMultiSelectExample" */ = { 371 | isa = XCConfigurationList; 372 | buildConfigurations = ( 373 | B1C3BCD81F2B2B2600904FA3 /* Debug */, 374 | B1C3BCD91F2B2B2600904FA3 /* Release */, 375 | ); 376 | defaultConfigurationIsVisible = 0; 377 | defaultConfigurationName = Release; 378 | }; 379 | B1C3BCDA1F2B2B2600904FA3 /* Build configuration list for PBXNativeTarget "SwiftMultiSelectExample" */ = { 380 | isa = XCConfigurationList; 381 | buildConfigurations = ( 382 | B1C3BCDB1F2B2B2600904FA3 /* Debug */, 383 | B1C3BCDC1F2B2B2600904FA3 /* Release */, 384 | ); 385 | defaultConfigurationIsVisible = 0; 386 | defaultConfigurationName = Release; 387 | }; 388 | /* End XCConfigurationList section */ 389 | }; 390 | rootObject = B1C3BCC01F2B2B2600904FA3 /* Project object */; 391 | } 392 | -------------------------------------------------------------------------------- /SwiftMultiSelectExample/SwiftMultiSelectExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SwiftMultiSelectExample/SwiftMultiSelectExample.xcodeproj/project.xcworkspace/xcuserdata/frind.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucabecchetti/SwiftMultiSelect/89087b0f3b18117c0871948d70388a904faf536a/SwiftMultiSelectExample/SwiftMultiSelectExample.xcodeproj/project.xcworkspace/xcuserdata/frind.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /SwiftMultiSelectExample/SwiftMultiSelectExample.xcodeproj/xcuserdata/frind.xcuserdatad/xcschemes/SwiftMultiSelectExample.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /SwiftMultiSelectExample/SwiftMultiSelectExample.xcodeproj/xcuserdata/frind.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | SwiftMultiSelectExample.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | B1C3BCC71F2B2B2600904FA3 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /SwiftMultiSelectExample/SwiftMultiSelectExample.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /SwiftMultiSelectExample/SwiftMultiSelectExample.xcworkspace/xcuserdata/frind.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucabecchetti/SwiftMultiSelect/89087b0f3b18117c0871948d70388a904faf536a/SwiftMultiSelectExample/SwiftMultiSelectExample.xcworkspace/xcuserdata/frind.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /SwiftMultiSelectExample/SwiftMultiSelectExample/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // SwiftMultiSelectExample 4 | // 5 | // Created by Luca Becchetti on 28/07/17. 6 | // Copyright © 2017 Luca Becchetti. 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: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 18 | // Override point for customization after application launch. 19 | return true 20 | } 21 | 22 | func applicationWillResignActive(_ application: UIApplication) { 23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 24 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 25 | } 26 | 27 | func applicationDidEnterBackground(_ application: UIApplication) { 28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 30 | } 31 | 32 | func applicationWillEnterForeground(_ application: UIApplication) { 33 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 34 | } 35 | 36 | func applicationDidBecomeActive(_ application: UIApplication) { 37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 38 | } 39 | 40 | func applicationWillTerminate(_ application: UIApplication) { 41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 42 | } 43 | 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /SwiftMultiSelectExample/SwiftMultiSelectExample/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "iPhone_Notifications_iOS7-10_20pt@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "iPhone_Notifications_iOS7-10_20pt@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "iPhone_Settings_iOS5-10_29pt@2x.png", 19 | "scale" : "2x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "iPhone_Settings_iOS5-10_29pt@3x.png", 25 | "scale" : "3x" 26 | }, 27 | { 28 | "size" : "40x40", 29 | "idiom" : "iphone", 30 | "filename" : "iPhone_Spotlight_iOS7-10_40pt@2x.png", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "iPhone_Spotlight_iOS7-10_40pt@3x.png", 37 | "scale" : "3x" 38 | }, 39 | { 40 | "size" : "60x60", 41 | "idiom" : "iphone", 42 | "filename" : "iPhone_App_iOS7-10_60pt@2x.png", 43 | "scale" : "2x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "iPhone_App_iOS7-10_60pt@3x.png", 49 | "scale" : "3x" 50 | }, 51 | { 52 | "idiom" : "ipad", 53 | "size" : "20x20", 54 | "scale" : "1x" 55 | }, 56 | { 57 | "idiom" : "ipad", 58 | "size" : "20x20", 59 | "scale" : "2x" 60 | }, 61 | { 62 | "idiom" : "ipad", 63 | "size" : "29x29", 64 | "scale" : "1x" 65 | }, 66 | { 67 | "idiom" : "ipad", 68 | "size" : "29x29", 69 | "scale" : "2x" 70 | }, 71 | { 72 | "idiom" : "ipad", 73 | "size" : "40x40", 74 | "scale" : "1x" 75 | }, 76 | { 77 | "idiom" : "ipad", 78 | "size" : "40x40", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "idiom" : "ipad", 83 | "size" : "76x76", 84 | "scale" : "1x" 85 | }, 86 | { 87 | "idiom" : "ipad", 88 | "size" : "76x76", 89 | "scale" : "2x" 90 | }, 91 | { 92 | "idiom" : "ipad", 93 | "size" : "83.5x83.5", 94 | "scale" : "2x" 95 | } 96 | ], 97 | "info" : { 98 | "version" : 1, 99 | "author" : "xcode" 100 | } 101 | } -------------------------------------------------------------------------------- /SwiftMultiSelectExample/SwiftMultiSelectExample/Assets.xcassets/AppIcon.appiconset/iPhone_App_iOS7-10_60pt@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucabecchetti/SwiftMultiSelect/89087b0f3b18117c0871948d70388a904faf536a/SwiftMultiSelectExample/SwiftMultiSelectExample/Assets.xcassets/AppIcon.appiconset/iPhone_App_iOS7-10_60pt@2x.png -------------------------------------------------------------------------------- /SwiftMultiSelectExample/SwiftMultiSelectExample/Assets.xcassets/AppIcon.appiconset/iPhone_App_iOS7-10_60pt@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucabecchetti/SwiftMultiSelect/89087b0f3b18117c0871948d70388a904faf536a/SwiftMultiSelectExample/SwiftMultiSelectExample/Assets.xcassets/AppIcon.appiconset/iPhone_App_iOS7-10_60pt@3x.png -------------------------------------------------------------------------------- /SwiftMultiSelectExample/SwiftMultiSelectExample/Assets.xcassets/AppIcon.appiconset/iPhone_Notifications_iOS7-10_20pt@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucabecchetti/SwiftMultiSelect/89087b0f3b18117c0871948d70388a904faf536a/SwiftMultiSelectExample/SwiftMultiSelectExample/Assets.xcassets/AppIcon.appiconset/iPhone_Notifications_iOS7-10_20pt@2x.png -------------------------------------------------------------------------------- /SwiftMultiSelectExample/SwiftMultiSelectExample/Assets.xcassets/AppIcon.appiconset/iPhone_Notifications_iOS7-10_20pt@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucabecchetti/SwiftMultiSelect/89087b0f3b18117c0871948d70388a904faf536a/SwiftMultiSelectExample/SwiftMultiSelectExample/Assets.xcassets/AppIcon.appiconset/iPhone_Notifications_iOS7-10_20pt@3x.png -------------------------------------------------------------------------------- /SwiftMultiSelectExample/SwiftMultiSelectExample/Assets.xcassets/AppIcon.appiconset/iPhone_Settings_iOS5-10_29pt@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucabecchetti/SwiftMultiSelect/89087b0f3b18117c0871948d70388a904faf536a/SwiftMultiSelectExample/SwiftMultiSelectExample/Assets.xcassets/AppIcon.appiconset/iPhone_Settings_iOS5-10_29pt@2x.png -------------------------------------------------------------------------------- /SwiftMultiSelectExample/SwiftMultiSelectExample/Assets.xcassets/AppIcon.appiconset/iPhone_Settings_iOS5-10_29pt@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucabecchetti/SwiftMultiSelect/89087b0f3b18117c0871948d70388a904faf536a/SwiftMultiSelectExample/SwiftMultiSelectExample/Assets.xcassets/AppIcon.appiconset/iPhone_Settings_iOS5-10_29pt@3x.png -------------------------------------------------------------------------------- /SwiftMultiSelectExample/SwiftMultiSelectExample/Assets.xcassets/AppIcon.appiconset/iPhone_Spotlight_iOS7-10_40pt@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucabecchetti/SwiftMultiSelect/89087b0f3b18117c0871948d70388a904faf536a/SwiftMultiSelectExample/SwiftMultiSelectExample/Assets.xcassets/AppIcon.appiconset/iPhone_Spotlight_iOS7-10_40pt@2x.png -------------------------------------------------------------------------------- /SwiftMultiSelectExample/SwiftMultiSelectExample/Assets.xcassets/AppIcon.appiconset/iPhone_Spotlight_iOS7-10_40pt@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucabecchetti/SwiftMultiSelect/89087b0f3b18117c0871948d70388a904faf536a/SwiftMultiSelectExample/SwiftMultiSelectExample/Assets.xcassets/AppIcon.appiconset/iPhone_Spotlight_iOS7-10_40pt@3x.png -------------------------------------------------------------------------------- /SwiftMultiSelectExample/SwiftMultiSelectExample/Assets.xcassets/logo.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "logomulti-2.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "logomulti-1.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "logomulti.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /SwiftMultiSelectExample/SwiftMultiSelectExample/Assets.xcassets/logo.imageset/logomulti-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucabecchetti/SwiftMultiSelect/89087b0f3b18117c0871948d70388a904faf536a/SwiftMultiSelectExample/SwiftMultiSelectExample/Assets.xcassets/logo.imageset/logomulti-1.png -------------------------------------------------------------------------------- /SwiftMultiSelectExample/SwiftMultiSelectExample/Assets.xcassets/logo.imageset/logomulti-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucabecchetti/SwiftMultiSelect/89087b0f3b18117c0871948d70388a904faf536a/SwiftMultiSelectExample/SwiftMultiSelectExample/Assets.xcassets/logo.imageset/logomulti-2.png -------------------------------------------------------------------------------- /SwiftMultiSelectExample/SwiftMultiSelectExample/Assets.xcassets/logo.imageset/logomulti.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucabecchetti/SwiftMultiSelect/89087b0f3b18117c0871948d70388a904faf536a/SwiftMultiSelectExample/SwiftMultiSelectExample/Assets.xcassets/logo.imageset/logomulti.png -------------------------------------------------------------------------------- /SwiftMultiSelectExample/SwiftMultiSelectExample/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /SwiftMultiSelectExample/SwiftMultiSelectExample/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 48 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /SwiftMultiSelectExample/SwiftMultiSelectExample/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | NSContactsUsageDescription 38 | This app needs access to contacts to find your friends. 39 | 40 | 41 | -------------------------------------------------------------------------------- /SwiftMultiSelectExample/SwiftMultiSelectExample/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // SwiftMultiSelectDemo 4 | // 5 | // Created by Luca Becchetti on 24/07/17. 6 | // Copyright © 2017 Luca Becchetti. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import SwiftMultiSelect 11 | 12 | class ViewController: UIViewController,SwiftMultiSelectDelegate,SwiftMultiSelectDataSource { 13 | 14 | @IBOutlet weak var switchAddress: UISwitch! 15 | @IBOutlet weak var badge: UILabel! 16 | @IBOutlet weak var switchInitial: UISwitch! 17 | var items:[SwiftMultiSelectItem] = [SwiftMultiSelectItem]() 18 | var initialValues:[SwiftMultiSelectItem] = [SwiftMultiSelectItem]() 19 | var selectedItems:[SwiftMultiSelectItem] = [SwiftMultiSelectItem]() 20 | override func viewDidLoad() { 21 | 22 | super.viewDidLoad() 23 | // Do any additional setup after loading the view, typically from a nib. 24 | 25 | badge.isHidden = true 26 | badge.layer.masksToBounds = true 27 | badge.layer.cornerRadius = 25 28 | createItems() 29 | 30 | Config.doneString = "Ok" 31 | SwiftMultiSelect.dataSource = self 32 | SwiftMultiSelect.delegate = self 33 | } 34 | 35 | 36 | /// Create a custom items set 37 | func createItems(){ 38 | 39 | self.items.removeAll() 40 | self.initialValues.removeAll() 41 | for i in 0..<50{ 42 | items.append(SwiftMultiSelectItem(row: i, title: "test\(i)", description: "description for: \(i)", imageURL : (i == 1 ? "https://randomuser.me/api/portraits/women/68.jpg" : nil))) 43 | } 44 | self.initialValues = [self.items.first!,self.items[1],self.items[2]] 45 | self.selectedItems = items 46 | } 47 | 48 | 49 | /// selector for switch addressbook 50 | /// 51 | /// - Parameter sender 52 | @IBAction func useAddr(_ sender: Any) { 53 | 54 | SwiftMultiSelect.dataSourceType = (switchAddress.isOn) ? .phone : .custom 55 | } 56 | 57 | 58 | /// Function to launch selector from button 59 | /// 60 | /// - Parameter sender 61 | @IBAction func launch(_ sender: Any) { 62 | 63 | //Example to start a selector with initial values 64 | if (switchInitial.isOn) { 65 | SwiftMultiSelect.initialSelected = initialValues 66 | }else{ 67 | SwiftMultiSelect.initialSelected = [] 68 | } 69 | 70 | SwiftMultiSelect.Show(to: self) 71 | 72 | } 73 | 74 | override func didReceiveMemoryWarning() { 75 | super.didReceiveMemoryWarning() 76 | // Dispose of any resources that can be recreated. 77 | } 78 | 79 | //MARK: - SwiftMultiSelectDelegate 80 | 81 | func userDidSearch(searchString: String) { 82 | if searchString == ""{ 83 | selectedItems = items 84 | }else{ 85 | selectedItems = items.filter({$0.title.lowercased().contains(searchString.lowercased()) || ($0.description != nil && $0.description!.lowercased().contains(searchString.lowercased())) }) 86 | } 87 | } 88 | 89 | func numberOfItemsInSwiftMultiSelect() -> Int { 90 | return selectedItems.count 91 | } 92 | 93 | func swiftMultiSelect(didUnselectItem item: SwiftMultiSelectItem) { 94 | print("row: \(item.title) has been deselected!") 95 | } 96 | 97 | func swiftMultiSelect(didSelectItem item: SwiftMultiSelectItem) { 98 | print("item: \(item.title) has been selected!") 99 | } 100 | 101 | func didCloseSwiftMultiSelect() { 102 | badge.isHidden = true 103 | badge.text = "" 104 | } 105 | 106 | func swiftMultiSelect(itemAtRow row: Int) -> SwiftMultiSelectItem { 107 | return selectedItems[row] 108 | } 109 | 110 | func swiftMultiSelect(didSelectItems items: [SwiftMultiSelectItem]) { 111 | 112 | initialValues = items 113 | badge.isHidden = (items.count <= 0) 114 | badge.text = "\(items.count)" 115 | 116 | print("you have been selected: \(items.count) items!") 117 | 118 | for item in items{ 119 | print(item.string) 120 | } 121 | 122 | } 123 | 124 | } 125 | 126 | --------------------------------------------------------------------------------