├── .gitignore
├── Resources
└── EliminationMenu.gif
├── EliminationMenu
├── Assets.xcassets
│ ├── Contents.json
│ ├── disk.imageset
│ │ ├── disk.pdf
│ │ └── Contents.json
│ ├── check.imageset
│ │ ├── check.pdf
│ │ └── Contents.json
│ ├── heart.imageset
│ │ ├── heart.pdf
│ │ └── Contents.json
│ ├── fabric.imageset
│ │ ├── fabric.pdf
│ │ └── Contents.json
│ ├── safari.imageset
│ │ ├── safari.pdf
│ │ └── Contents.json
│ └── AppIcon.appiconset
│ │ └── Contents.json
├── MyCostomType.swift
├── Info.plist
├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
├── AppDelegate.swift
└── ViewController.swift
├── EliminationMenu.xcodeproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── xcshareddata
│ └── xcschemes
│ │ ├── EliminationMenu.xcscheme
│ │ └── Example App.xcscheme
└── project.pbxproj
├── .travis.yml
├── EliminationMenu.podspec
├── EliminationMenuTests
├── Info.plist
└── EliminationMenuTests.swift
├── Package.swift
├── LICENSE
├── README.md
└── Sources
├── EliminationMenuItem.swift
└── EliminationMenu.swift
/.gitignore:
--------------------------------------------------------------------------------
1 | EliminationMenu.xcodeproj/xcuserdata
2 | *xcuserdatad*
3 | .DS_Store
--------------------------------------------------------------------------------
/Resources/EliminationMenu.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/r-dent/EliminationMenu/HEAD/Resources/EliminationMenu.gif
--------------------------------------------------------------------------------
/EliminationMenu/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/EliminationMenu/Assets.xcassets/disk.imageset/disk.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/r-dent/EliminationMenu/HEAD/EliminationMenu/Assets.xcassets/disk.imageset/disk.pdf
--------------------------------------------------------------------------------
/EliminationMenu/Assets.xcassets/check.imageset/check.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/r-dent/EliminationMenu/HEAD/EliminationMenu/Assets.xcassets/check.imageset/check.pdf
--------------------------------------------------------------------------------
/EliminationMenu/Assets.xcassets/heart.imageset/heart.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/r-dent/EliminationMenu/HEAD/EliminationMenu/Assets.xcassets/heart.imageset/heart.pdf
--------------------------------------------------------------------------------
/EliminationMenu/Assets.xcassets/fabric.imageset/fabric.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/r-dent/EliminationMenu/HEAD/EliminationMenu/Assets.xcassets/fabric.imageset/fabric.pdf
--------------------------------------------------------------------------------
/EliminationMenu/Assets.xcassets/safari.imageset/safari.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/r-dent/EliminationMenu/HEAD/EliminationMenu/Assets.xcassets/safari.imageset/safari.pdf
--------------------------------------------------------------------------------
/EliminationMenu.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/EliminationMenu/Assets.xcassets/disk.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "disk.pdf"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/EliminationMenu/Assets.xcassets/check.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "check.pdf"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/EliminationMenu/Assets.xcassets/fabric.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "fabric.pdf"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/EliminationMenu/Assets.xcassets/heart.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "heart.pdf"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/EliminationMenu/Assets.xcassets/safari.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "safari.pdf"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/EliminationMenu.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: objective-c
2 |
3 | osx_image: xcode10
4 | xcode_workspace: EliminationMenu.xcodeproj
5 | xcode_scheme: "Example App"
6 | xcode_sdk: iphonesimulator11.0
7 |
8 | script: xcodebuild build test -project EliminationMenu.xcodeproj -scheme "Example App" -destination "platform=iOS Simulator,name=iPhone 7" -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO
9 |
--------------------------------------------------------------------------------
/EliminationMenu/MyCostomType.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MyCustomType.swift
3 | // Example App
4 | //
5 | // Created by Roman Gille on 28.09.18.
6 | // Copyright © 2018 Roman Gille. All rights reserved.
7 | //
8 |
9 | import EliminationMenu
10 |
11 | struct MyCustomType: EliminationMenuItem {
12 |
13 | var title: String {
14 | return String(describing: someOtherProperty)
15 | }
16 |
17 | var value: Any? {
18 | return customProperty
19 | }
20 |
21 | let customProperty: Bool
22 | let someOtherProperty: Int
23 |
24 | }
25 |
26 |
27 |
--------------------------------------------------------------------------------
/EliminationMenu.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = 'EliminationMenu'
3 | s.version = '1.0.2'
4 | s.swift_version = '4.2'
5 |
6 | s.summary = 'A menu that eliminates all values which were not selected.'
7 | s.author = { 'Roman Gille' => 'developer@romangille.com' }
8 | s.homepage = 'https://github.com/r-dent/EliminationMenu'
9 | s.license = { :type => 'MIT', :file => 'LICENSE' }
10 |
11 | s.source = { :git => 'https://github.com/r-dent/EliminationMenu.git', :tag => "#{s.version}" }
12 | s.source_files = 'Sources/*.swift'
13 |
14 | s.requires_arc = true
15 | s.frameworks = 'UIKit'
16 |
17 | s.platform = :ios, '8.0'
18 | s.ios.deployment_target = '8'
19 | end
--------------------------------------------------------------------------------
/EliminationMenuTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Package.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version:4.2
2 | // The swift-tools-version declares the minimum version of Swift required to build this package.
3 |
4 | import PackageDescription
5 |
6 | let package = Package(
7 | name: "EliminationMenu",
8 | products: [
9 | // Products define the executables and libraries produced by a package, and make them visible to other packages.
10 | .library(
11 | name: "EliminationMenu",
12 | targets: ["EliminationMenu"]),
13 | ],
14 | dependencies: [
15 | // Dependencies declare other packages that this package depends on.
16 | // .package(url: /* package url */, from: "1.0.0"),
17 | ],
18 | targets: [
19 | // Targets are the basic building blocks of a package. A target can define a module or a test suite.
20 | // Targets can depend on other targets in this package, and on products in packages which this package depends on.
21 | .target(
22 | name: "EliminationMenu",
23 | path: "./Sources"
24 | )
25 | ]
26 | )
27 |
--------------------------------------------------------------------------------
/EliminationMenu/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ios-marketing",
45 | "size" : "1024x1024",
46 | "scale" : "1x"
47 | }
48 | ],
49 | "info" : {
50 | "version" : 1,
51 | "author" : "xcode"
52 | }
53 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2016 Roman Gille, http://romangille.com
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | "Software"), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/EliminationMenu/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.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/EliminationMenu/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/EliminationMenuTests/EliminationMenuTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // EliminationMenuTests.swift
3 | // EliminationMenuTests
4 | //
5 | // Created by Roman Gille on 02.09.16.
6 | // Copyright © 2016 Roman Gille. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | @testable import EliminationMenu
11 |
12 | class EliminationMenuTests: XCTestCase {
13 |
14 | override func setUp() {
15 | super.setUp()
16 | // Put setup code here. This method is called before the invocation of each test method in the class.
17 | }
18 |
19 | override func tearDown() {
20 | // Put teardown code here. This method is called after the invocation of each test method in the class.
21 | super.tearDown()
22 | }
23 |
24 | func testLayoutMargins() {
25 | let viewController = UIStoryboard(name: "Main", bundle: nil).instantiateInitialViewController()
26 |
27 | guard let view = viewController?.view else {
28 | XCTFail("Could not get view")
29 | return
30 | }
31 |
32 |
33 | let menuItems = [
34 | EliminationMenu.Item(value: UIColor(red: 57/255, green: 61/255, blue: 66/255, alpha: 1) , title: "Gray"),
35 | EliminationMenu.Item(value: UIColor.blue, title: "Blue"),
36 | EliminationMenu.Item(value: UIColor.red, title: "Red"),
37 | EliminationMenu.Item(value: UIColor.green, title: "Green")
38 | ]
39 |
40 | let margin = CGPoint(x: 12, y: 24)
41 |
42 | let menu = EliminationMenu.createMenu(
43 | withItems: menuItems,
44 | inView: view,
45 | aligned: .topLeft,
46 | margin: margin,
47 | selection: nil
48 | )
49 |
50 | view.layoutSubviews()
51 |
52 | XCTAssertEqual(menu.frame.origin.x, margin.x, "Margin x does not match")
53 | XCTAssertEqual(menu.frame.origin.y, margin.y, "Margin y does not match")
54 |
55 | }
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/EliminationMenu/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // RGEliminationMenu
4 | //
5 | // Created by Roman Gille on 14.04.16.
6 | // Copyright © 2016 Roman Gille. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
18 | // Override point for customization after application launch.
19 | return true
20 | }
21 |
22 | func applicationWillResignActive(_ application: UIApplication) {
23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
24 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
25 | }
26 |
27 | func applicationDidEnterBackground(_ application: UIApplication) {
28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
30 | }
31 |
32 | func applicationWillEnterForeground(_ application: UIApplication) {
33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
34 | }
35 |
36 | func applicationDidBecomeActive(_ application: UIApplication) {
37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
38 | }
39 |
40 | func applicationWillTerminate(_ application: UIApplication) {
41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
42 | }
43 |
44 |
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/EliminationMenu.xcodeproj/xcshareddata/xcschemes/EliminationMenu.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
34 |
35 |
45 |
46 |
52 |
53 |
54 |
55 |
56 |
57 |
63 |
64 |
70 |
71 |
72 |
73 |
75 |
76 |
79 |
80 |
81 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # EliminationMenu
2 | [](https://travis-ci.org/r-dent/EliminationMenu)
3 | [](http://cocoadocs.org/docsets/EliminationMenu)
4 | [](LICENSE)
5 | [](http://cocoadocs.org/docsets/EliminationMenu)
6 |
7 | Some kind of menu that eliminates all values which were not selected.
8 |
9 |
10 |
11 |
12 |
13 | ## Installation
14 |
15 | Just drag the Folder `Sources` into your project.
16 |
17 | ### Cocoapods
18 |
19 | If you´re using [CocoaPods](https://cocoapods.org), add this to your Podfile:
20 |
21 | pod EliminationMenu
22 |
23 | ### Swift Package Manager
24 |
25 | To add EliminationMenu to a [Swift Package Manager](https://swift.org/package-manager/) based project, add the following:
26 |
27 | ```swift
28 | .package(url: "https://github.com/r-dent/EliminationMenu", from: "1.0.2")
29 | ```
30 |
31 | to the `dependencies` value of your `Package.swift`.
32 |
33 |
34 | ## Usage
35 |
36 | You can create an EliminationMenu view in Interface Builder or in code.
37 |
38 | ### Create entries
39 |
40 | To set up the entries, create an array of instances conforming to `EliminationMenuItem` and set it to the `items` property of the menu object.
41 |
42 | ```swift
43 | let menuEntries = [
44 | EliminationMenu.Item(value: "SomeValue", title: "First"),
45 | EliminationMenu.Item(value: "SomeOtherValue", title: "Second"),
46 | EliminationMenu.Item(value: UIImage(named: "filename"), title: "Third"), // You can use values of any kind.
47 | EliminationMenu.Item(value: "...or a view", title: "Fourth"),
48 | "Just a String",
49 | MyCustomType(customProperty: true, someOtherProperty: 5)
50 | ]
51 | menu.items = menuEntries
52 | ```
53 |
54 | *Hint*: The default type `EliminationMenu.Item` can be used to populate the menu. But you can also make your own types conform to `EliminationMenuItem` and use them directly.
55 | `String` already conforms to it. So you can use Strings as menu items. See the example project for an overview.
56 |
57 | ### Create Menu
58 |
59 | Use the convenience method to create a menu and add it as a subview to your view controllers view.
60 |
61 | ```swift
62 | let menu = EliminationMenu.createMenu(withItems: menuEntries, inView: view, aligned: .topRight, margin: CGPoint(x: 0, y: 20)) { (item) in
63 | print("Selected value: \(item.value)")
64 | }
65 | ```
66 |
67 | If you want to use Interface Builder, just add a `UIView` and pin 2 of its edges (vertical and horizontal). Set `EliminationMenu` as the views class. Also add a width and a height constraint to supress warnings. Enable "_Remove at build time_" on the size constraints. The menu will get an intrinsic size at runtime.
68 |
69 | You can also create an instance of `EliminationMenu` and constrain it yourself in a superview. Be shure to call `menu.setup()` after all.
70 |
71 | See the [example code](EliminationMenu/ViewController.swift) for a better insight.
72 |
73 | ### Customize
74 |
75 | You can customize the properties of your menu like this:
76 |
77 | ```swift
78 | menu.font = UIFont.boldSystemFont(ofSize: 24)
79 | menu.color = UIColor.white
80 |
81 | menu.setup()
82 | ```
83 |
84 | Be shure to call `menu.setup()` to apply your changes. See the [documentation](http://cocoadocs.org/docsets/EliminationMenu) for more ways to customize.
85 |
86 | ## License
87 |
88 | `EliminationMenu` is available under the MIT license. See the [LICENSE](LICENSE) file for more info.
--------------------------------------------------------------------------------
/Sources/EliminationMenuItem.swift:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2016 Roman Gille, http://romangille.com
2 | //
3 | // Permission is hereby granted, free of charge, to any person obtaining
4 | // a copy of this software and associated documentation files (the
5 | // "Software"), to deal in the Software without restriction, including
6 | // without limitation the rights to use, copy, modify, merge, publish,
7 | // distribute, sublicense, and/or sell copies of the Software, and to
8 | // permit persons to whom the Software is furnished to do so, subject to
9 | // the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be
12 | // included in all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
22 | import UIKit
23 |
24 | /// Conforming objects can be used as menu items in an `EliminationMenu`.
25 | public protocol EliminationMenuItem {
26 | /// The title that will be shown in the menu.
27 | var title: String { get }
28 | /// The icon that will be shown in the menu.
29 | var icon: UIImage? { get }
30 | /// These insets will also set titleInsets and contentInsets of the items entry button.
31 | var iconInsets: UIEdgeInsets { get }
32 | /// The object that you will receive in the selectionHandler.
33 | var value: Any? { get }
34 | }
35 |
36 | /// This adds default implementations for optional methods of `EliminationMenuItem`.
37 | public extension EliminationMenuItem {
38 | /// Default implementation of icon to make it optional.
39 | var icon: UIImage? { return nil }
40 | /// Default implementation of iconInsets to make it optional.
41 | var iconInsets: UIEdgeInsets {
42 | return UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
43 | }
44 | }
45 |
46 | /// Adds a default `Item` to use in `EleminationMenu`.
47 | public extension EliminationMenu {
48 |
49 | // MARK: - Class: Item
50 |
51 | // An item representing a menu entry in EliminationMenu.
52 | public class Item: EliminationMenuItem {
53 | /// The title that will be shown in the menu.
54 | open var title: String = ""
55 | /// The icon that will be shown in the menu.
56 | open var icon: UIImage?
57 | /// The object that you will receive in the selectionHandler.
58 | open var value: Any?
59 | /// These insets will also set titleInsets and contentInsets of the items entry button.
60 | open var iconInsets: UIEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
61 |
62 | /**
63 | - parameter value: The value that will be passed to the selection handler.
64 | - parameter title: An optional text that is shown as menu entry.
65 | - parameter icon: An optional image. Shown before the title in the menu entry.
66 | */
67 | public init(value:Any, title: String = "", icon: UIImage? = nil) {
68 | self.title = title
69 | self.value = value
70 | self.icon = icon
71 | }
72 | }
73 |
74 | }
75 |
76 | /// Add capability to use `String` as item in `EleminationMenu`.
77 | extension String: EliminationMenuItem {
78 | public var title: String {
79 | return self
80 | }
81 |
82 | public var value: Any? {
83 | return self
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/EliminationMenu.xcodeproj/xcshareddata/xcschemes/Example App.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
42 |
43 |
49 |
50 |
51 |
52 |
53 |
54 |
64 |
66 |
72 |
73 |
74 |
75 |
76 |
77 |
83 |
85 |
91 |
92 |
93 |
94 |
96 |
97 |
100 |
101 |
102 |
--------------------------------------------------------------------------------
/EliminationMenu/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/EliminationMenu/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // EliminationMenu
4 | //
5 | // Created by Roman Gille on 14.04.16.
6 | // Copyright © 2016 Roman Gille. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import EliminationMenu
11 |
12 | class ViewController: UIViewController {
13 |
14 | @IBOutlet weak var eliminationMenu: EliminationMenu!
15 | @IBOutlet weak var infoLabel: UILabel!
16 |
17 | override func viewDidLoad() {
18 | super.viewDidLoad()
19 |
20 | /**
21 | Set up the menu created in interface builder.
22 | */
23 |
24 | eliminationMenu.font = .boldSystemFont(ofSize: 24)
25 | eliminationMenu.color = .white
26 |
27 | eliminationMenu.selectionHandler = { item in
28 | self.infoLabel.text = "Selected item:\n\"\(item.title)\""
29 | if let value = item.value {
30 | self.infoLabel.text?.append( "\n\nThe value is:\n\"\(value)\"" )
31 | }
32 | }
33 |
34 | eliminationMenu.items = [
35 | EliminationMenu.Item(value: "SomeValue", title: "First"),
36 | // String already conforms to EliminationMenuItem an can be used out of the box.
37 | "Just a String",
38 | EliminationMenu.Item(value: "This could also be an Image", title: "Third"),
39 | EliminationMenu.Item(value: "...or a view", title: "Fourth"),
40 | // Add an Element of MyCustomType which conforms to EliminationMenuItem.
41 | MyCustomType(customProperty: true, someOtherProperty: 5)
42 | ]
43 |
44 | /**
45 | Create menu in code.
46 | Using the convenience function.
47 | */
48 |
49 | let topRightMenuItems = [
50 | EliminationMenu.Item(value: UIColor(red: 57/255, green: 61/255, blue: 66/255, alpha: 1) , title: "Gray"),
51 | EliminationMenu.Item(value: UIColor.blue, title: "Blue"),
52 | EliminationMenu.Item(value: UIColor.red, title: "Red"),
53 | EliminationMenu.Item(value: UIColor.green, title: "Green")
54 | ]
55 |
56 | let topRightMenu = EliminationMenu.createMenu(
57 | withItems: topRightMenuItems,
58 | inView: view,
59 | aligned: .topRight,
60 | margin: CGPoint(x: 20, y: 20)
61 | ) { (item) in
62 | // Animate the backgroundColor of the view.
63 | if let color = item.value as? UIColor {
64 | UIView.animate(withDuration: 0.5, animations: {
65 | self.view.backgroundColor = color
66 | })
67 | }
68 | }
69 |
70 | // A little customization.
71 | topRightMenu.font = .boldSystemFont(ofSize: 24)
72 | topRightMenu.color = .white
73 | // Call this after changing layout properties of an already added menu to apply the changes.
74 | topRightMenu.setup()
75 |
76 | /**
77 | Create menu in code.
78 | Manually adding it to the view and setting constraints.
79 | */
80 |
81 | let rightMenu = EliminationMenu()
82 |
83 | rightMenu.selectionHandler = {item in
84 | self.infoLabel.text = "Selected item:\n\"\(item.title)\""
85 | if let value = item.value {
86 | self.infoLabel.text?.append( "\n\nThe value is:\n\"\(value)\"" )
87 | }
88 | }
89 |
90 | rightMenu.items = [
91 | EliminationMenu.Item(value: "Layer over layer.", icon: UIImage(named: "fabric")),
92 | EliminationMenu.Item(value: "There was this browser...", icon: UIImage(named: "safari")),
93 | EliminationMenu.Item(value: "Save to disk.", icon: UIImage(named: "disk")),
94 | EliminationMenu.Item(value: "Mic check. One, two...", icon: UIImage(named: "check")),
95 | EliminationMenu.Item(value: "To the heart!", icon: UIImage(named: "heart"))
96 | ]
97 |
98 | rightMenu.align = .bottomRight
99 |
100 | // Add menu to layout.
101 |
102 | rightMenu.translatesAutoresizingMaskIntoConstraints = false
103 | view.addSubview(rightMenu)
104 |
105 | view.addConstraints([
106 | NSLayoutConstraint(item: view, attribute: .right, relatedBy: .equal, toItem: rightMenu, attribute: .right, multiplier: 1, constant: 20),
107 | NSLayoutConstraint(item: view, attribute: .bottom, relatedBy: .equal, toItem: rightMenu, attribute: .bottom, multiplier: 1, constant: 20)
108 | ])
109 | }
110 |
111 | override func didReceiveMemoryWarning() {
112 | super.didReceiveMemoryWarning()
113 | // Dispose of any resources that can be recreated.
114 | }
115 |
116 |
117 | }
118 |
119 |
--------------------------------------------------------------------------------
/Sources/EliminationMenu.swift:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2016 Roman Gille, http://romangille.com
2 | //
3 | // Permission is hereby granted, free of charge, to any person obtaining
4 | // a copy of this software and associated documentation files (the
5 | // "Software"), to deal in the Software without restriction, including
6 | // without limitation the rights to use, copy, modify, merge, publish,
7 | // distribute, sublicense, and/or sell copies of the Software, and to
8 | // permit persons to whom the Software is furnished to do so, subject to
9 | // the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be
12 | // included in all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
22 | import UIKit
23 |
24 | /// A menu that eliminates all values which were not selected.
25 | open class EliminationMenu: UIView {
26 |
27 | /// The alignment to a corner of the parent view.
28 | public enum Alignment {
29 | case topLeft, topRight, bottomLeft, bottomRight
30 | }
31 |
32 | /// A closure that provides information about the selected menu item.
33 | public typealias SelectionHandler = (_ selectedIdtem: EliminationMenuItem) -> Void
34 | /// A closure that provides information about an animation that will or did happen.
35 | public typealias AnimationHandler = (_ opening: Bool, _ animated: Bool) -> Void
36 |
37 | /// The alignment of the menu. It defines from which direction the entries will fly in. Defaults to .BottomLeft
38 | open var align: Alignment = .bottomLeft
39 | /// The font used in the menu entry buttons. Defaults to systemFontSize().
40 | open var font: UIFont = .systemFont(ofSize: UIFont.systemFontSize)
41 | /// The color of the text in menu entries. Defaults to darkTextColor().
42 | open var color: UIColor = .darkText
43 | /// The amount of points, the menu entries are offset from the screen before fading tehm in. Defaults to 50.
44 | open var buttonAnimationOffset: CGFloat = 50
45 | /// The duration in seconds, that the show animation will take. Defaults to 0.4.
46 | open var showAnimationDuration: TimeInterval = 0.4
47 | /// The duration in seconds, that the selection animation will take. Defaults to 0.25.
48 | open var selectAnimationDuration: TimeInterval = 0.25
49 | /// Margin between the entry buttons. Defaults to 0.
50 | open var margin: CGFloat = 0
51 | /// The height of the menu entry buttons. Defaults to 44.
52 | open var buttonHeight: CGFloat = 44
53 |
54 | /// A closure to react on the selection of a menu entry. This will not fire when the selected value has not changed.
55 | open var selectionHandler: SelectionHandler?
56 | /// A closure to react on menu opening/closing. This will be called before the animation runs.
57 | open var willAnimateHandler: AnimationHandler?
58 | /// A closure to react on menu opening/closing. This will be called after the animation has finished.
59 | open var didAnimateHandler: AnimationHandler?
60 |
61 | var buttons: [UIButton] = []
62 |
63 | fileprivate var _selectedIndex = 0
64 | fileprivate let _tagOffset = 10
65 |
66 | fileprivate var isLeftAligned: Bool {
67 | return (align == .bottomLeft) || (align == .topLeft)
68 | }
69 |
70 | fileprivate var isBottomAligned: Bool {
71 | return (align == .bottomLeft) || (align == .bottomRight)
72 | }
73 |
74 | /// The entries of the menu. Setting this will reinitialize the menu.
75 | open var items: [EliminationMenuItem] = [] {
76 | didSet {
77 | setup()
78 | }
79 | }
80 |
81 | /// The button for the selected item. This is the one that you see when the menu is closed.
82 | var mainButton: UIButton {
83 | return getButton(atIndex: _selectedIndex)!
84 | }
85 |
86 | /**
87 | Convenience method to create a new menu in a given view and constrain it to some edges.
88 | - parameter items: A collection of EleminationMenu.Item objects.
89 | - parameter view: The view where the menu is added as subview.
90 | - parameter aligned: The corner in which the menu is placed.
91 | - parameter margin: The distance the menu will have to the edges of its superview.
92 | - parameter selection: The closure that will be called upon selection of a menu item.
93 | */
94 | open class func createMenu(withItems items: [EliminationMenuItem], inView view: UIView, aligned: Alignment, margin: CGPoint = CGPoint(x: 0, y: 0), selection: SelectionHandler? = nil) -> EliminationMenu {
95 | let menu = EliminationMenu()
96 | menu.selectionHandler = selection
97 | menu.align = aligned
98 |
99 | menu.translatesAutoresizingMaskIntoConstraints = false
100 | view.addSubview(menu)
101 |
102 | if menu.isLeftAligned {
103 | view.addConstraint(NSLayoutConstraint(
104 | item: menu, attribute: .left, relatedBy: .equal, toItem: view, attribute: .left, multiplier: 1, constant: margin.x)
105 | )
106 | }
107 | else {
108 | view.addConstraint(NSLayoutConstraint(
109 | item: view, attribute: .right, relatedBy: .equal, toItem: menu, attribute: .right, multiplier: 1, constant: margin.x)
110 | )
111 | }
112 |
113 | if menu.isBottomAligned {
114 | view.addConstraint(NSLayoutConstraint(
115 | item: view, attribute: .bottom, relatedBy: .equal, toItem: menu, attribute: .bottom, multiplier: 1, constant: margin.y)
116 | )
117 | }
118 | else {
119 | view.addConstraint(NSLayoutConstraint(
120 | item: view, attribute: .top, relatedBy: .equal, toItem: menu, attribute: .top, multiplier: 1, constant: -margin.y)
121 | )
122 | }
123 |
124 | menu.items = items
125 |
126 | return menu
127 | }
128 |
129 | /**
130 | Initializes the menu interface. Call this when you changed layout properties, to apply them.
131 | - parameter index: An optional index of a menu item to show selected after setup
132 | */
133 | open func setup(withSelectedIndex index: Int = 0) {
134 | // Clear existing buttons.
135 | if items.count > 0 {
136 | for subview in self.subviews {
137 | subview.removeFromSuperview()
138 | }
139 | buttons = []
140 | }
141 |
142 | guard items.count > 0 else {return}
143 |
144 | let safeIndex = (index < items.count) ? index : 0
145 |
146 | // Create first button.
147 | if buttons.count == 0 {
148 | let menuItem = items[safeIndex]
149 | let button = self.createButton(menuItem, tag: _tagOffset)
150 |
151 | button.frame = CGRect(x: 0, y: 0, width: max(button.intrinsicContentSize.width, self.bounds.size.width), height: self.buttonHeight)
152 |
153 | buttons.append(button)
154 | self.addSubview(button)
155 |
156 | self.invalidateIntrinsicContentSize()
157 | }
158 |
159 | _selectedIndex = safeIndex
160 | }
161 |
162 | @objc func buttonPressed(_ sender: UIView) {
163 | let index = sender.tag - _tagOffset
164 |
165 | if (index == _selectedIndex) {
166 | show((buttons.count < 2), animated: true)
167 | }
168 | else {
169 | select(sender.tag - _tagOffset, animated: true)
170 | }
171 | }
172 |
173 | func getButton(atIndex index: Int) -> UIButton? {
174 | return self.viewWithTag(_tagOffset + index) as? UIButton
175 | }
176 |
177 | func createButton(_ item:EliminationMenuItem, tag:Int) -> UIButton {
178 | let button = UIButton()
179 |
180 | button.setTitle(item.title, for: .normal)
181 | button.setImage(item.icon, for: .normal)
182 | button.contentHorizontalAlignment = (isLeftAligned) ? .left : .right
183 | button.tag = tag
184 | button.titleLabel?.font = self.font
185 | button.setTitleColor(color, for: .normal)
186 | button.addTarget(self, action: #selector(buttonPressed), for: .touchUpInside)
187 |
188 | setIconInsets(item.iconInsets, button: button)
189 |
190 | return button
191 | }
192 |
193 | func setIconInsets(_ iconInsets:UIEdgeInsets, button:UIButton) {
194 | button.imageEdgeInsets = UIEdgeInsets(top: iconInsets.top, left: iconInsets.left, bottom: iconInsets.bottom, right: 0)
195 | button.titleEdgeInsets = UIEdgeInsets(top: 0, left: iconInsets.right, bottom: 0, right: -iconInsets.right)
196 | button.contentEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: iconInsets.right)
197 | }
198 |
199 | func show(_ show: Bool, animated: Bool) {
200 | if show {
201 | var buttonIndex = 0
202 | let buttonVerticalSpace = CGFloat(buttonHeight + margin)
203 |
204 | willAnimateHandler?(true, animated)
205 |
206 | // Add buttons for unselected items.
207 | for titleIndex in 0.. Void in
255 | for button in self.buttons {
256 | button.transform = CGAffineTransform.identity
257 | }
258 | }, completion:{(success) -> Void in
259 | self.didAnimateHandler?(true, animated)
260 | })
261 | }
262 | else {
263 | self.select(_selectedIndex, animated: animated)
264 | }
265 | }
266 |
267 | func select(_ index: Int?, animated: Bool) {
268 | let selectedIndex: Int = index ?? 0
269 | let menuItem = items[selectedIndex]
270 |
271 | if buttons.count > 1 {
272 | let selectionDidChange = _selectedIndex != selectedIndex
273 |
274 | if selectionDidChange {
275 | selectionHandler?(menuItem)
276 | }
277 | willAnimateHandler?(false, animated)
278 |
279 |
280 | let selectedButton = getButton(atIndex: selectedIndex)
281 | let selectionTargetFrame = CGRect(origin: self.mainButton.frame.origin, size: selectedButton!.frame.size)
282 | let nonSelectedAnimationY: CGFloat
283 |
284 | if isBottomAligned {
285 | nonSelectedAnimationY = frame.size.height - selectedButton!.frame.origin.y - selectedButton!.frame.size.height
286 | }
287 | else {
288 | nonSelectedAnimationY = -(selectedButton!.frame.origin.y)
289 | }
290 |
291 | let nonSelectedTransfromation = CGAffineTransform(translationX: 0, y: nonSelectedAnimationY)
292 |
293 | UIView.animate(withDuration: (animated ? selectAnimationDuration : 0), animations: { () -> Void in
294 | for button in self.buttons {
295 | if button != selectedButton {
296 | button.transform = nonSelectedTransfromation
297 | button.alpha = 0
298 | }
299 | }
300 |
301 | selectedButton?.frame = selectionTargetFrame
302 |
303 | }, completion: { (success) -> Void in
304 | // Remove hidden buttons.
305 | for button in self.buttons {
306 | if button != selectedButton {
307 | button.removeFromSuperview()
308 |
309 | if let index = self.buttons.index(of: button) {
310 | self.buttons.remove(at: index)
311 | }
312 | }
313 | }
314 | // Correct main button position.
315 | selectedButton?.frame = CGRect(
316 | origin: CGPoint(x: 0, y: 0),
317 | size: CGSize(width: selectedButton!.intrinsicContentSize.width, height: self.buttonHeight)
318 | )
319 |
320 | self._selectedIndex = selectedIndex
321 | self.invalidateIntrinsicContentSize()
322 |
323 | self.didAnimateHandler?(true, animated)
324 | })
325 | }
326 | else {
327 | selectionHandler?(menuItem)
328 | willAnimateHandler?(false, animated)
329 |
330 | mainButton.setTitle(menuItem.title, for: .normal)
331 | mainButton.setImage(menuItem.icon, for: .normal)
332 |
333 | setIconInsets(menuItem.iconInsets, button: mainButton)
334 |
335 | mainButton.frame = CGRect(
336 | origin: mainButton.frame.origin,
337 | size: CGSize(width: mainButton.intrinsicContentSize.width, height: self.buttonHeight)
338 | )
339 | mainButton.tag = selectedIndex + _tagOffset
340 | _selectedIndex = selectedIndex
341 |
342 | didAnimateHandler?(true, animated)
343 | }
344 | }
345 |
346 | func selectEntryWithValue(_ value: AnyObject!, animated: Bool) {
347 | for i in 0.. 0 {
357 | var width: CGFloat = 0
358 | var height: CGFloat = -margin
359 |
360 | for button in buttons {
361 | let contentSize = button.intrinsicContentSize
362 | height += self.buttonHeight + margin
363 | if contentSize.width > width {
364 | width = contentSize.width
365 | }
366 | }
367 | return CGSize(width: width, height: height)
368 | }
369 |
370 | return CGSize(width: 0, height: 0)
371 | }
372 |
373 | }
374 |
--------------------------------------------------------------------------------
/EliminationMenu.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 3071A644215E17440058DF42 /* EliminationMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3071A643215E17440058DF42 /* EliminationMenu.swift */; };
11 | 3071A646215E21310058DF42 /* MyCostomType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3071A645215E21310058DF42 /* MyCostomType.swift */; };
12 | 30865F7F215E13A800801C80 /* EliminationMenuItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30E77F631DCDA34E00A2A230 /* EliminationMenuItem.swift */; };
13 | 30865F81215E144300801C80 /* libEliminationMenu.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 30865F77215E139D00801C80 /* libEliminationMenu.a */; };
14 | 30B2D6C21D79E74F00C54A61 /* EliminationMenuTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B2D6C11D79E74F00C54A61 /* EliminationMenuTests.swift */; };
15 | 30C53CF41CC2849B00121273 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30C53CEC1CC2849B00121273 /* AppDelegate.swift */; };
16 | 30C53CF51CC2849B00121273 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 30C53CED1CC2849B00121273 /* Assets.xcassets */; };
17 | 30C53CF61CC2849B00121273 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 30C53CEE1CC2849B00121273 /* LaunchScreen.storyboard */; };
18 | 30C53CF71CC2849B00121273 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 30C53CF01CC2849B00121273 /* Main.storyboard */; };
19 | 30C53CF91CC2849B00121273 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30C53CF31CC2849B00121273 /* ViewController.swift */; };
20 | /* End PBXBuildFile section */
21 |
22 | /* Begin PBXContainerItemProxy section */
23 | 30B2D6C41D79E74F00C54A61 /* PBXContainerItemProxy */ = {
24 | isa = PBXContainerItemProxy;
25 | containerPortal = 302488C91CBF811D002343AE /* Project object */;
26 | proxyType = 1;
27 | remoteGlobalIDString = 302488D01CBF811D002343AE;
28 | remoteInfo = EliminationMenu;
29 | };
30 | /* End PBXContainerItemProxy section */
31 |
32 | /* Begin PBXCopyFilesBuildPhase section */
33 | 30865F75215E139D00801C80 /* CopyFiles */ = {
34 | isa = PBXCopyFilesBuildPhase;
35 | buildActionMask = 2147483647;
36 | dstPath = "include/$(PRODUCT_NAME)";
37 | dstSubfolderSpec = 16;
38 | files = (
39 | );
40 | runOnlyForDeploymentPostprocessing = 0;
41 | };
42 | /* End PBXCopyFilesBuildPhase section */
43 |
44 | /* Begin PBXFileReference section */
45 | 302488D11CBF811D002343AE /* Example App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Example App.app"; sourceTree = BUILT_PRODUCTS_DIR; };
46 | 3071A643215E17440058DF42 /* EliminationMenu.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EliminationMenu.swift; sourceTree = ""; };
47 | 3071A645215E21310058DF42 /* MyCostomType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyCostomType.swift; sourceTree = ""; };
48 | 30865F77215E139D00801C80 /* libEliminationMenu.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libEliminationMenu.a; sourceTree = BUILT_PRODUCTS_DIR; };
49 | 30B2D6BF1D79E74F00C54A61 /* Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
50 | 30B2D6C11D79E74F00C54A61 /* EliminationMenuTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EliminationMenuTests.swift; sourceTree = ""; };
51 | 30B2D6C31D79E74F00C54A61 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
52 | 30C53CEC1CC2849B00121273 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
53 | 30C53CED1CC2849B00121273 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
54 | 30C53CEF1CC2849B00121273 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
55 | 30C53CF11CC2849B00121273 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
56 | 30C53CF21CC2849B00121273 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
57 | 30C53CF31CC2849B00121273 /* ViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
58 | 30E77F631DCDA34E00A2A230 /* EliminationMenuItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EliminationMenuItem.swift; sourceTree = ""; };
59 | /* End PBXFileReference section */
60 |
61 | /* Begin PBXFrameworksBuildPhase section */
62 | 302488CE1CBF811D002343AE /* Frameworks */ = {
63 | isa = PBXFrameworksBuildPhase;
64 | buildActionMask = 2147483647;
65 | files = (
66 | 30865F81215E144300801C80 /* libEliminationMenu.a in Frameworks */,
67 | );
68 | runOnlyForDeploymentPostprocessing = 0;
69 | };
70 | 30865F74215E139D00801C80 /* Frameworks */ = {
71 | isa = PBXFrameworksBuildPhase;
72 | buildActionMask = 2147483647;
73 | files = (
74 | );
75 | runOnlyForDeploymentPostprocessing = 0;
76 | };
77 | 30B2D6BC1D79E74F00C54A61 /* Frameworks */ = {
78 | isa = PBXFrameworksBuildPhase;
79 | buildActionMask = 2147483647;
80 | files = (
81 | );
82 | runOnlyForDeploymentPostprocessing = 0;
83 | };
84 | /* End PBXFrameworksBuildPhase section */
85 |
86 | /* Begin PBXGroup section */
87 | 302488C81CBF811D002343AE = {
88 | isa = PBXGroup;
89 | children = (
90 | 30C53CEB1CC2849B00121273 /* EliminationMenu */,
91 | 308D72EE1CC2851C0031AFCD /* Sources */,
92 | 30B2D6C01D79E74F00C54A61 /* EliminationMenuTests */,
93 | 302488D21CBF811D002343AE /* Products */,
94 | 30865F80215E144300801C80 /* Frameworks */,
95 | );
96 | sourceTree = "";
97 | };
98 | 302488D21CBF811D002343AE /* Products */ = {
99 | isa = PBXGroup;
100 | children = (
101 | 302488D11CBF811D002343AE /* Example App.app */,
102 | 30B2D6BF1D79E74F00C54A61 /* Tests.xctest */,
103 | 30865F77215E139D00801C80 /* libEliminationMenu.a */,
104 | );
105 | name = Products;
106 | sourceTree = "";
107 | };
108 | 30865F80215E144300801C80 /* Frameworks */ = {
109 | isa = PBXGroup;
110 | children = (
111 | );
112 | name = Frameworks;
113 | sourceTree = "";
114 | };
115 | 308D72EE1CC2851C0031AFCD /* Sources */ = {
116 | isa = PBXGroup;
117 | children = (
118 | 3071A643215E17440058DF42 /* EliminationMenu.swift */,
119 | 30E77F631DCDA34E00A2A230 /* EliminationMenuItem.swift */,
120 | );
121 | path = Sources;
122 | sourceTree = "";
123 | };
124 | 30B2D6C01D79E74F00C54A61 /* EliminationMenuTests */ = {
125 | isa = PBXGroup;
126 | children = (
127 | 30B2D6C11D79E74F00C54A61 /* EliminationMenuTests.swift */,
128 | 30B2D6C31D79E74F00C54A61 /* Info.plist */,
129 | );
130 | path = EliminationMenuTests;
131 | sourceTree = "";
132 | };
133 | 30C53CEB1CC2849B00121273 /* EliminationMenu */ = {
134 | isa = PBXGroup;
135 | children = (
136 | 30C53CEC1CC2849B00121273 /* AppDelegate.swift */,
137 | 30C53CF31CC2849B00121273 /* ViewController.swift */,
138 | 3071A645215E21310058DF42 /* MyCostomType.swift */,
139 | 30C53CF01CC2849B00121273 /* Main.storyboard */,
140 | 30C53CED1CC2849B00121273 /* Assets.xcassets */,
141 | 30C53CEE1CC2849B00121273 /* LaunchScreen.storyboard */,
142 | 30C53CF21CC2849B00121273 /* Info.plist */,
143 | );
144 | path = EliminationMenu;
145 | sourceTree = "";
146 | };
147 | /* End PBXGroup section */
148 |
149 | /* Begin PBXNativeTarget section */
150 | 302488D01CBF811D002343AE /* Example App */ = {
151 | isa = PBXNativeTarget;
152 | buildConfigurationList = 302488E31CBF811D002343AE /* Build configuration list for PBXNativeTarget "Example App" */;
153 | buildPhases = (
154 | 302488CD1CBF811D002343AE /* Sources */,
155 | 302488CE1CBF811D002343AE /* Frameworks */,
156 | 302488CF1CBF811D002343AE /* Resources */,
157 | );
158 | buildRules = (
159 | );
160 | dependencies = (
161 | );
162 | name = "Example App";
163 | productName = RGEliminationMenu;
164 | productReference = 302488D11CBF811D002343AE /* Example App.app */;
165 | productType = "com.apple.product-type.application";
166 | };
167 | 30865F76215E139D00801C80 /* EliminationMenu */ = {
168 | isa = PBXNativeTarget;
169 | buildConfigurationList = 30865F7B215E139D00801C80 /* Build configuration list for PBXNativeTarget "EliminationMenu" */;
170 | buildPhases = (
171 | 30865F73215E139D00801C80 /* Sources */,
172 | 30865F74215E139D00801C80 /* Frameworks */,
173 | 30865F75215E139D00801C80 /* CopyFiles */,
174 | );
175 | buildRules = (
176 | );
177 | dependencies = (
178 | );
179 | name = EliminationMenu;
180 | productName = EliminationMenu;
181 | productReference = 30865F77215E139D00801C80 /* libEliminationMenu.a */;
182 | productType = "com.apple.product-type.library.static";
183 | };
184 | 30B2D6BE1D79E74F00C54A61 /* Tests */ = {
185 | isa = PBXNativeTarget;
186 | buildConfigurationList = 30B2D6C81D79E74F00C54A61 /* Build configuration list for PBXNativeTarget "Tests" */;
187 | buildPhases = (
188 | 30B2D6BB1D79E74F00C54A61 /* Sources */,
189 | 30B2D6BC1D79E74F00C54A61 /* Frameworks */,
190 | 30B2D6BD1D79E74F00C54A61 /* Resources */,
191 | );
192 | buildRules = (
193 | );
194 | dependencies = (
195 | 30B2D6C51D79E74F00C54A61 /* PBXTargetDependency */,
196 | );
197 | name = Tests;
198 | productName = EliminationMenuTests;
199 | productReference = 30B2D6BF1D79E74F00C54A61 /* Tests.xctest */;
200 | productType = "com.apple.product-type.bundle.unit-test";
201 | };
202 | /* End PBXNativeTarget section */
203 |
204 | /* Begin PBXProject section */
205 | 302488C91CBF811D002343AE /* Project object */ = {
206 | isa = PBXProject;
207 | attributes = {
208 | LastSwiftUpdateCheck = 1000;
209 | LastUpgradeCheck = 1000;
210 | ORGANIZATIONNAME = "Roman Gille";
211 | TargetAttributes = {
212 | 302488D01CBF811D002343AE = {
213 | CreatedOnToolsVersion = 7.3;
214 | DevelopmentTeam = SBPV56G7LG;
215 | LastSwiftMigration = 0800;
216 | };
217 | 30865F76215E139D00801C80 = {
218 | CreatedOnToolsVersion = 10.0;
219 | DevelopmentTeam = SBPV56G7LG;
220 | ProvisioningStyle = Automatic;
221 | };
222 | 30B2D6BE1D79E74F00C54A61 = {
223 | CreatedOnToolsVersion = 7.3.1;
224 | DevelopmentTeam = SBPV56G7LG;
225 | LastSwiftMigration = 0800;
226 | TestTargetID = 302488D01CBF811D002343AE;
227 | };
228 | };
229 | };
230 | buildConfigurationList = 302488CC1CBF811D002343AE /* Build configuration list for PBXProject "EliminationMenu" */;
231 | compatibilityVersion = "Xcode 3.2";
232 | developmentRegion = English;
233 | hasScannedForEncodings = 0;
234 | knownRegions = (
235 | en,
236 | Base,
237 | );
238 | mainGroup = 302488C81CBF811D002343AE;
239 | productRefGroup = 302488D21CBF811D002343AE /* Products */;
240 | projectDirPath = "";
241 | projectRoot = "";
242 | targets = (
243 | 302488D01CBF811D002343AE /* Example App */,
244 | 30B2D6BE1D79E74F00C54A61 /* Tests */,
245 | 30865F76215E139D00801C80 /* EliminationMenu */,
246 | );
247 | };
248 | /* End PBXProject section */
249 |
250 | /* Begin PBXResourcesBuildPhase section */
251 | 302488CF1CBF811D002343AE /* Resources */ = {
252 | isa = PBXResourcesBuildPhase;
253 | buildActionMask = 2147483647;
254 | files = (
255 | 30C53CF71CC2849B00121273 /* Main.storyboard in Resources */,
256 | 30C53CF51CC2849B00121273 /* Assets.xcassets in Resources */,
257 | 30C53CF61CC2849B00121273 /* LaunchScreen.storyboard in Resources */,
258 | );
259 | runOnlyForDeploymentPostprocessing = 0;
260 | };
261 | 30B2D6BD1D79E74F00C54A61 /* Resources */ = {
262 | isa = PBXResourcesBuildPhase;
263 | buildActionMask = 2147483647;
264 | files = (
265 | );
266 | runOnlyForDeploymentPostprocessing = 0;
267 | };
268 | /* End PBXResourcesBuildPhase section */
269 |
270 | /* Begin PBXSourcesBuildPhase section */
271 | 302488CD1CBF811D002343AE /* Sources */ = {
272 | isa = PBXSourcesBuildPhase;
273 | buildActionMask = 2147483647;
274 | files = (
275 | 30C53CF91CC2849B00121273 /* ViewController.swift in Sources */,
276 | 3071A646215E21310058DF42 /* MyCostomType.swift in Sources */,
277 | 30C53CF41CC2849B00121273 /* AppDelegate.swift in Sources */,
278 | );
279 | runOnlyForDeploymentPostprocessing = 0;
280 | };
281 | 30865F73215E139D00801C80 /* Sources */ = {
282 | isa = PBXSourcesBuildPhase;
283 | buildActionMask = 2147483647;
284 | files = (
285 | 30865F7F215E13A800801C80 /* EliminationMenuItem.swift in Sources */,
286 | 3071A644215E17440058DF42 /* EliminationMenu.swift in Sources */,
287 | );
288 | runOnlyForDeploymentPostprocessing = 0;
289 | };
290 | 30B2D6BB1D79E74F00C54A61 /* Sources */ = {
291 | isa = PBXSourcesBuildPhase;
292 | buildActionMask = 2147483647;
293 | files = (
294 | 30B2D6C21D79E74F00C54A61 /* EliminationMenuTests.swift in Sources */,
295 | );
296 | runOnlyForDeploymentPostprocessing = 0;
297 | };
298 | /* End PBXSourcesBuildPhase section */
299 |
300 | /* Begin PBXTargetDependency section */
301 | 30B2D6C51D79E74F00C54A61 /* PBXTargetDependency */ = {
302 | isa = PBXTargetDependency;
303 | target = 302488D01CBF811D002343AE /* Example App */;
304 | targetProxy = 30B2D6C41D79E74F00C54A61 /* PBXContainerItemProxy */;
305 | };
306 | /* End PBXTargetDependency section */
307 |
308 | /* Begin PBXVariantGroup section */
309 | 30C53CEE1CC2849B00121273 /* LaunchScreen.storyboard */ = {
310 | isa = PBXVariantGroup;
311 | children = (
312 | 30C53CEF1CC2849B00121273 /* Base */,
313 | );
314 | name = LaunchScreen.storyboard;
315 | sourceTree = "";
316 | };
317 | 30C53CF01CC2849B00121273 /* Main.storyboard */ = {
318 | isa = PBXVariantGroup;
319 | children = (
320 | 30C53CF11CC2849B00121273 /* Base */,
321 | );
322 | name = Main.storyboard;
323 | sourceTree = "";
324 | };
325 | /* End PBXVariantGroup section */
326 |
327 | /* Begin XCBuildConfiguration section */
328 | 302488E11CBF811D002343AE /* Debug */ = {
329 | isa = XCBuildConfiguration;
330 | buildSettings = {
331 | ALWAYS_SEARCH_USER_PATHS = NO;
332 | CLANG_ANALYZER_NONNULL = YES;
333 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
334 | CLANG_CXX_LIBRARY = "libc++";
335 | CLANG_ENABLE_MODULES = YES;
336 | CLANG_ENABLE_OBJC_ARC = YES;
337 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
338 | CLANG_WARN_BOOL_CONVERSION = YES;
339 | CLANG_WARN_COMMA = YES;
340 | CLANG_WARN_CONSTANT_CONVERSION = YES;
341 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
342 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
343 | CLANG_WARN_EMPTY_BODY = YES;
344 | CLANG_WARN_ENUM_CONVERSION = YES;
345 | CLANG_WARN_INFINITE_RECURSION = YES;
346 | CLANG_WARN_INT_CONVERSION = YES;
347 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
348 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
349 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
350 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
351 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
352 | CLANG_WARN_STRICT_PROTOTYPES = YES;
353 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
354 | CLANG_WARN_UNREACHABLE_CODE = YES;
355 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
356 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
357 | COPY_PHASE_STRIP = NO;
358 | DEBUG_INFORMATION_FORMAT = dwarf;
359 | ENABLE_STRICT_OBJC_MSGSEND = YES;
360 | ENABLE_TESTABILITY = YES;
361 | GCC_C_LANGUAGE_STANDARD = gnu99;
362 | GCC_DYNAMIC_NO_PIC = NO;
363 | GCC_NO_COMMON_BLOCKS = YES;
364 | GCC_OPTIMIZATION_LEVEL = 0;
365 | GCC_PREPROCESSOR_DEFINITIONS = (
366 | "DEBUG=1",
367 | "$(inherited)",
368 | );
369 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
370 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
371 | GCC_WARN_UNDECLARED_SELECTOR = YES;
372 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
373 | GCC_WARN_UNUSED_FUNCTION = YES;
374 | GCC_WARN_UNUSED_VARIABLE = YES;
375 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
376 | MTL_ENABLE_DEBUG_INFO = YES;
377 | ONLY_ACTIVE_ARCH = YES;
378 | SDKROOT = iphoneos;
379 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
380 | };
381 | name = Debug;
382 | };
383 | 302488E21CBF811D002343AE /* Release */ = {
384 | isa = XCBuildConfiguration;
385 | buildSettings = {
386 | ALWAYS_SEARCH_USER_PATHS = NO;
387 | CLANG_ANALYZER_NONNULL = YES;
388 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
389 | CLANG_CXX_LIBRARY = "libc++";
390 | CLANG_ENABLE_MODULES = YES;
391 | CLANG_ENABLE_OBJC_ARC = YES;
392 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
393 | CLANG_WARN_BOOL_CONVERSION = YES;
394 | CLANG_WARN_COMMA = YES;
395 | CLANG_WARN_CONSTANT_CONVERSION = YES;
396 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
397 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
398 | CLANG_WARN_EMPTY_BODY = YES;
399 | CLANG_WARN_ENUM_CONVERSION = YES;
400 | CLANG_WARN_INFINITE_RECURSION = YES;
401 | CLANG_WARN_INT_CONVERSION = YES;
402 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
403 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
404 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
405 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
406 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
407 | CLANG_WARN_STRICT_PROTOTYPES = YES;
408 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
409 | CLANG_WARN_UNREACHABLE_CODE = YES;
410 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
411 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
412 | COPY_PHASE_STRIP = NO;
413 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
414 | ENABLE_NS_ASSERTIONS = NO;
415 | ENABLE_STRICT_OBJC_MSGSEND = YES;
416 | GCC_C_LANGUAGE_STANDARD = gnu99;
417 | GCC_NO_COMMON_BLOCKS = YES;
418 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
419 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
420 | GCC_WARN_UNDECLARED_SELECTOR = YES;
421 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
422 | GCC_WARN_UNUSED_FUNCTION = YES;
423 | GCC_WARN_UNUSED_VARIABLE = YES;
424 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
425 | MTL_ENABLE_DEBUG_INFO = NO;
426 | SDKROOT = iphoneos;
427 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
428 | VALIDATE_PRODUCT = YES;
429 | };
430 | name = Release;
431 | };
432 | 302488E41CBF811D002343AE /* Debug */ = {
433 | isa = XCBuildConfiguration;
434 | buildSettings = {
435 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
436 | DEVELOPMENT_TEAM = SBPV56G7LG;
437 | INFOPLIST_FILE = EliminationMenu/Info.plist;
438 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
439 | PRODUCT_BUNDLE_IDENTIFIER = rg.test.EliminationMenu;
440 | PRODUCT_NAME = "$(TARGET_NAME)";
441 | SWIFT_VERSION = 4.2;
442 | };
443 | name = Debug;
444 | };
445 | 302488E51CBF811D002343AE /* Release */ = {
446 | isa = XCBuildConfiguration;
447 | buildSettings = {
448 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
449 | DEVELOPMENT_TEAM = SBPV56G7LG;
450 | INFOPLIST_FILE = EliminationMenu/Info.plist;
451 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
452 | PRODUCT_BUNDLE_IDENTIFIER = rg.test.EliminationMenu;
453 | PRODUCT_NAME = "$(TARGET_NAME)";
454 | SWIFT_VERSION = 4.2;
455 | };
456 | name = Release;
457 | };
458 | 30865F7C215E139D00801C80 /* Debug */ = {
459 | isa = XCBuildConfiguration;
460 | buildSettings = {
461 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
462 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
463 | CLANG_ENABLE_OBJC_WEAK = YES;
464 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
465 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
466 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
467 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
468 | CODE_SIGN_IDENTITY = "iPhone Developer";
469 | CODE_SIGN_STYLE = Automatic;
470 | DEVELOPMENT_TEAM = SBPV56G7LG;
471 | GCC_C_LANGUAGE_STANDARD = gnu11;
472 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
473 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
474 | MTL_FAST_MATH = YES;
475 | OTHER_LDFLAGS = "-ObjC";
476 | PRODUCT_NAME = "$(TARGET_NAME)";
477 | SKIP_INSTALL = YES;
478 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
479 | SWIFT_VERSION = 4.2;
480 | TARGETED_DEVICE_FAMILY = "1,2";
481 | };
482 | name = Debug;
483 | };
484 | 30865F7D215E139D00801C80 /* Release */ = {
485 | isa = XCBuildConfiguration;
486 | buildSettings = {
487 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
488 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
489 | CLANG_ENABLE_OBJC_WEAK = YES;
490 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
491 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
492 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
493 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
494 | CODE_SIGN_IDENTITY = "iPhone Developer";
495 | CODE_SIGN_STYLE = Automatic;
496 | DEVELOPMENT_TEAM = SBPV56G7LG;
497 | GCC_C_LANGUAGE_STANDARD = gnu11;
498 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
499 | MTL_FAST_MATH = YES;
500 | OTHER_LDFLAGS = "-ObjC";
501 | PRODUCT_NAME = "$(TARGET_NAME)";
502 | SKIP_INSTALL = YES;
503 | SWIFT_VERSION = 4.2;
504 | TARGETED_DEVICE_FAMILY = "1,2";
505 | };
506 | name = Release;
507 | };
508 | 30B2D6C61D79E74F00C54A61 /* Debug */ = {
509 | isa = XCBuildConfiguration;
510 | buildSettings = {
511 | BUNDLE_LOADER = "$(TEST_HOST)";
512 | DEVELOPMENT_TEAM = SBPV56G7LG;
513 | INFOPLIST_FILE = EliminationMenuTests/Info.plist;
514 | IPHONEOS_DEPLOYMENT_TARGET = 9.3;
515 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
516 | PRODUCT_BUNDLE_IDENTIFIER = rg.EliminationMenuTests;
517 | PRODUCT_NAME = "$(TARGET_NAME)";
518 | SWIFT_VERSION = 4.2;
519 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example App.app/Example App";
520 | };
521 | name = Debug;
522 | };
523 | 30B2D6C71D79E74F00C54A61 /* Release */ = {
524 | isa = XCBuildConfiguration;
525 | buildSettings = {
526 | BUNDLE_LOADER = "$(TEST_HOST)";
527 | DEVELOPMENT_TEAM = SBPV56G7LG;
528 | INFOPLIST_FILE = EliminationMenuTests/Info.plist;
529 | IPHONEOS_DEPLOYMENT_TARGET = 9.3;
530 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
531 | PRODUCT_BUNDLE_IDENTIFIER = rg.EliminationMenuTests;
532 | PRODUCT_NAME = "$(TARGET_NAME)";
533 | SWIFT_VERSION = 4.2;
534 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example App.app/Example App";
535 | };
536 | name = Release;
537 | };
538 | /* End XCBuildConfiguration section */
539 |
540 | /* Begin XCConfigurationList section */
541 | 302488CC1CBF811D002343AE /* Build configuration list for PBXProject "EliminationMenu" */ = {
542 | isa = XCConfigurationList;
543 | buildConfigurations = (
544 | 302488E11CBF811D002343AE /* Debug */,
545 | 302488E21CBF811D002343AE /* Release */,
546 | );
547 | defaultConfigurationIsVisible = 0;
548 | defaultConfigurationName = Release;
549 | };
550 | 302488E31CBF811D002343AE /* Build configuration list for PBXNativeTarget "Example App" */ = {
551 | isa = XCConfigurationList;
552 | buildConfigurations = (
553 | 302488E41CBF811D002343AE /* Debug */,
554 | 302488E51CBF811D002343AE /* Release */,
555 | );
556 | defaultConfigurationIsVisible = 0;
557 | defaultConfigurationName = Release;
558 | };
559 | 30865F7B215E139D00801C80 /* Build configuration list for PBXNativeTarget "EliminationMenu" */ = {
560 | isa = XCConfigurationList;
561 | buildConfigurations = (
562 | 30865F7C215E139D00801C80 /* Debug */,
563 | 30865F7D215E139D00801C80 /* Release */,
564 | );
565 | defaultConfigurationIsVisible = 0;
566 | defaultConfigurationName = Release;
567 | };
568 | 30B2D6C81D79E74F00C54A61 /* Build configuration list for PBXNativeTarget "Tests" */ = {
569 | isa = XCConfigurationList;
570 | buildConfigurations = (
571 | 30B2D6C61D79E74F00C54A61 /* Debug */,
572 | 30B2D6C71D79E74F00C54A61 /* Release */,
573 | );
574 | defaultConfigurationIsVisible = 0;
575 | defaultConfigurationName = Release;
576 | };
577 | /* End XCConfigurationList section */
578 | };
579 | rootObject = 302488C91CBF811D002343AE /* Project object */;
580 | }
581 |
--------------------------------------------------------------------------------