├── .gitignore ├── .swiftlint.yml ├── Configs └── SensorVisualizerKit.plist ├── Example ├── AppDelegate.swift ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── Icon.png │ │ ├── icon_20pt.png │ │ ├── icon_20pt@2x-1.png │ │ ├── icon_20pt@2x.png │ │ ├── icon_20pt@3x.png │ │ ├── icon_29pt.png │ │ ├── icon_29pt@2x-2.png │ │ ├── icon_29pt@2x.png │ │ ├── icon_29pt@3x.png │ │ ├── icon_40pt.png │ │ ├── icon_40pt@2x-1.png │ │ ├── icon_40pt@2x.png │ │ ├── icon_40pt@3x.png │ │ ├── icon_60pt@2x.png │ │ ├── icon_60pt@3x.png │ │ ├── icon_76pt.png │ │ ├── icon_76pt@2x.png │ │ └── icon_83.5@2x.png │ ├── Contents.json │ ├── shake-phone.imageset │ │ ├── Contents.json │ │ └── shake-phone.pdf │ └── shot-on-iphone │ │ ├── Contents.json │ │ ├── shot-on-iphone-0.imageset │ │ ├── Contents.json │ │ └── shot-on-iphone-0.jpg │ │ ├── shot-on-iphone-1.imageset │ │ ├── Contents.json │ │ └── shot-on-iphone-1.jpg │ │ ├── shot-on-iphone-10.imageset │ │ ├── Contents.json │ │ └── shot-on-iphone-10.jpg │ │ ├── shot-on-iphone-11.imageset │ │ ├── Contents.json │ │ └── shot-on-iphone-11.jpg │ │ ├── shot-on-iphone-12.imageset │ │ ├── Contents.json │ │ └── shot-on-iphone-12.jpg │ │ ├── shot-on-iphone-2.imageset │ │ ├── Contents.json │ │ └── shot-on-iphone-2.jpg │ │ ├── shot-on-iphone-3.imageset │ │ ├── Contents.json │ │ └── shot-on-iphone-3.jpg │ │ ├── shot-on-iphone-4.imageset │ │ ├── Contents.json │ │ └── shot-on-iphone-4.jpg │ │ ├── shot-on-iphone-5.imageset │ │ ├── Contents.json │ │ └── shot-on-iphone-5.jpg │ │ ├── shot-on-iphone-6.imageset │ │ ├── Contents.json │ │ └── shot-on-iphone-6.jpg │ │ ├── shot-on-iphone-7.imageset │ │ ├── Contents.json │ │ └── shot-on-iphone-7.jpg │ │ ├── shot-on-iphone-8.imageset │ │ ├── Contents.json │ │ └── shot-on-iphone-8.jpg │ │ └── shot-on-iphone-9.imageset │ │ ├── Contents.json │ │ └── shot-on-iphone-9.jpg ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── Info.plist └── Root │ ├── Map │ └── MapViewController.swift │ ├── OptionsTableViewController.swift │ ├── Pan │ └── PanViewController.swift │ ├── PeekPop │ ├── PeekPopCollectionViewController.swift │ ├── PeekPopDetailViewController.swift │ └── PeekPopPreviewCollectionViewCell.swift │ ├── Tap │ └── TapViewController.swift │ └── Web │ └── WebViewController.swift ├── LICENSE ├── Package.swift ├── README.md ├── SensorVisualizerKit.podspec ├── SensorVisualizerKit.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── xcshareddata │ └── xcschemes │ ├── SensorVisualizerKit-Example.xcscheme │ └── SensorVisualizerKit-iOS.xcscheme └── Sources ├── CAAnimationGroup+Extensions.swift ├── SensorVisualizerWindow+Shake.swift ├── SensorVisualizerWindow+Touch.swift ├── SensorVisualizerWindow.swift ├── UIAttachmentBehavior+Extensions.swift ├── UIPushBehavior+Extensions.swift └── UIView+Extensions.swift /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/swift,swiftpm,macos 3 | # Edit at https://www.gitignore.io/?templates=swift,swiftpm,macos 4 | 5 | ### macOS ### 6 | # General 7 | .DS_Store 8 | .AppleDouble 9 | .LSOverride 10 | 11 | # Icon must end with two \r 12 | Icon 13 | 14 | # Thumbnails 15 | ._* 16 | 17 | # Files that might appear in the root of a volume 18 | .DocumentRevisions-V100 19 | .fseventsd 20 | .Spotlight-V100 21 | .TemporaryItems 22 | .Trashes 23 | .VolumeIcon.icns 24 | .com.apple.timemachine.donotpresent 25 | 26 | # Directories potentially created on remote AFP share 27 | .AppleDB 28 | .AppleDesktop 29 | Network Trash Folder 30 | Temporary Items 31 | .apdisk 32 | 33 | ### Swift ### 34 | # Xcode 35 | # 36 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 37 | 38 | ## Build generated 39 | build/ 40 | DerivedData/ 41 | 42 | ## Various settings 43 | *.pbxuser 44 | !default.pbxuser 45 | *.mode1v3 46 | !default.mode1v3 47 | *.mode2v3 48 | !default.mode2v3 49 | *.perspectivev3 50 | !default.perspectivev3 51 | xcuserdata/ 52 | 53 | ## Other 54 | *.moved-aside 55 | *.xccheckout 56 | *.xcscmblueprint 57 | 58 | ## Obj-C/Swift specific 59 | *.hmap 60 | *.ipa 61 | *.dSYM.zip 62 | *.dSYM 63 | 64 | ## Playgrounds 65 | timeline.xctimeline 66 | playground.xcworkspace 67 | 68 | # Swift Package Manager 69 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 70 | # Packages/ 71 | # Package.pins 72 | # Package.resolved 73 | .build/ 74 | # Add this line if you want to avoid checking in Xcode SPM integration. 75 | .swiftpm/xcode 76 | 77 | # CocoaPods 78 | # We recommend against adding the Pods directory to your .gitignore. However 79 | # you should judge for yourself, the pros and cons are mentioned at: 80 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 81 | # Pods/ 82 | # Add this line if you want to avoid checking in source code from the Xcode workspace 83 | # *.xcworkspace 84 | 85 | # Carthage 86 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 87 | # Carthage/Checkouts 88 | 89 | Carthage/Build 90 | 91 | # Accio dependency management 92 | Dependencies/ 93 | .accio/ 94 | 95 | # fastlane 96 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 97 | # screenshots whenever they are needed. 98 | # For more information about the recommended setup visit: 99 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 100 | 101 | fastlane/report.xml 102 | fastlane/Preview.html 103 | fastlane/screenshots/**/*.png 104 | fastlane/test_output 105 | 106 | # Code Injection 107 | # After new code Injection tools there's a generated folder /iOSInjectionProject 108 | # https://github.com/johnno1962/injectionforxcode 109 | 110 | iOSInjectionProject/ 111 | 112 | ### SwiftPM ### 113 | Packages 114 | xcuserdata 115 | *.xcodeproj 116 | 117 | 118 | # End of https://www.gitignore.io/api/swift,swiftpm,macos 119 | -------------------------------------------------------------------------------- /.swiftlint.yml: -------------------------------------------------------------------------------- 1 | included: 2 | - Source 3 | - Tests 4 | excluded: 5 | - Tests/SwiftLintFrameworkTests/Resources 6 | analyzer_rules: 7 | - unused_import 8 | - unused_private_declaration 9 | opt_in_rules: 10 | - anyobject_protocol 11 | - array_init 12 | - attributes 13 | - closure_end_indentation 14 | - closure_spacing 15 | - collection_alignment 16 | - contains_over_first_not_nil 17 | - empty_count 18 | - empty_string 19 | - empty_xctest_method 20 | - explicit_init 21 | - extension_access_modifier 22 | - fallthrough 23 | - fatal_error_message 24 | - file_header 25 | - file_name 26 | - first_where 27 | - identical_operands 28 | - joined_default_parameter 29 | - let_var_whitespace 30 | - last_where 31 | - literal_expression_end_indentation 32 | - lower_acl_than_parent 33 | - nimble_operator 34 | - number_separator 35 | - object_literal 36 | - operator_usage_whitespace 37 | - overridden_super_call 38 | - override_in_extension 39 | - pattern_matching_keywords 40 | - private_action 41 | - private_outlet 42 | - prohibited_interface_builder 43 | - prohibited_super_call 44 | - quick_discouraged_call 45 | - quick_discouraged_focused_test 46 | - quick_discouraged_pending_test 47 | - redundant_nil_coalescing 48 | - redundant_type_annotation 49 | - single_test_class 50 | - sorted_first_last 51 | - sorted_imports 52 | - static_operator 53 | - unavailable_function 54 | - unneeded_parentheses_in_closure_argument 55 | - untyped_error_in_catch 56 | - vertical_parameter_alignment_on_call 57 | - vertical_whitespace_closing_braces 58 | - vertical_whitespace_opening_braces 59 | - xct_specific_matcher 60 | - yoda_condition 61 | 62 | identifier_name: 63 | excluded: 64 | - id 65 | number_separator: 66 | minimum_length: 5 67 | file_name: 68 | excluded: 69 | - main.swift 70 | - LinuxMain.swift 71 | - TestHelpers.swift 72 | - shim.swift 73 | - AutomaticRuleTests.generated.swift 74 | 75 | custom_rules: 76 | rule_id: 77 | included: Source/SwiftLintFramework/Rules/.+/\w+\.swift 78 | name: Rule ID 79 | message: Rule IDs must be all lowercase, snake case and not end with `rule` 80 | regex: identifier:\s*("\w+_rule"|"\S*[^a-z_]\S*") 81 | severity: error 82 | fatal_error: 83 | name: Fatal Error 84 | excluded: "Tests/*" 85 | message: Prefer using `queuedFatalError` over `fatalError` to avoid leaking compiler host machine paths. 86 | regex: \bfatalError\b 87 | match_kinds: 88 | - identifier 89 | severity: error 90 | rule_test_function: 91 | included: Tests/SwiftLintFrameworkTests/RulesTests.swift 92 | name: Rule Test Function 93 | message: Rule Test Function mustn't end with `rule` 94 | regex: func\s*test\w+(r|R)ule\(\) 95 | severity: error -------------------------------------------------------------------------------- /Configs/SensorVisualizerKit.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 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSHumanReadableCopyright 24 | Copyright © 2016 - 2019 Joe Blau. All rights reserved. 25 | NSPrincipalClass 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Example/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // SensorVisualizerKit-Example 4 | // 5 | // Created by Joe Blau on 4/9/19. 6 | // Copyright © 2019 SensorVisualizerKit. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import SensorVisualizerKit 11 | 12 | @UIApplicationMain 13 | class AppDelegate: UIResponder, UIApplicationDelegate { 14 | 15 | var window: UIWindow? = { 16 | return SensorVisualizerWindow(frame: UIScreen.main.bounds) 17 | }() 18 | 19 | func application(_ application: UIApplication, 20 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 21 | return true 22 | } 23 | } 24 | 25 | -------------------------------------------------------------------------------- /Example/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "icon_20pt@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "icon_20pt@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "icon_29pt@2x-2.png", 19 | "scale" : "2x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "icon_29pt@3x.png", 25 | "scale" : "3x" 26 | }, 27 | { 28 | "size" : "40x40", 29 | "idiom" : "iphone", 30 | "filename" : "icon_40pt@2x-1.png", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "icon_40pt@3x.png", 37 | "scale" : "3x" 38 | }, 39 | { 40 | "size" : "60x60", 41 | "idiom" : "iphone", 42 | "filename" : "icon_60pt@2x.png", 43 | "scale" : "2x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "icon_60pt@3x.png", 49 | "scale" : "3x" 50 | }, 51 | { 52 | "size" : "20x20", 53 | "idiom" : "ipad", 54 | "filename" : "icon_20pt.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "icon_20pt@2x-1.png", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "size" : "29x29", 65 | "idiom" : "ipad", 66 | "filename" : "icon_29pt.png", 67 | "scale" : "1x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "icon_29pt@2x.png", 73 | "scale" : "2x" 74 | }, 75 | { 76 | "size" : "40x40", 77 | "idiom" : "ipad", 78 | "filename" : "icon_40pt.png", 79 | "scale" : "1x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "icon_40pt@2x.png", 85 | "scale" : "2x" 86 | }, 87 | { 88 | "size" : "76x76", 89 | "idiom" : "ipad", 90 | "filename" : "icon_76pt.png", 91 | "scale" : "1x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "icon_76pt@2x.png", 97 | "scale" : "2x" 98 | }, 99 | { 100 | "size" : "83.5x83.5", 101 | "idiom" : "ipad", 102 | "filename" : "icon_83.5@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "1024x1024", 107 | "idiom" : "ios-marketing", 108 | "filename" : "Icon.png", 109 | "scale" : "1x" 110 | } 111 | ], 112 | "info" : { 113 | "version" : 1, 114 | "author" : "xcode" 115 | } 116 | } -------------------------------------------------------------------------------- /Example/Assets.xcassets/AppIcon.appiconset/Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asafkorem/sensor-visualizer-kit/574dbdbc3af11113c288e099bc49e438b80e81b8/Example/Assets.xcassets/AppIcon.appiconset/Icon.png -------------------------------------------------------------------------------- /Example/Assets.xcassets/AppIcon.appiconset/icon_20pt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asafkorem/sensor-visualizer-kit/574dbdbc3af11113c288e099bc49e438b80e81b8/Example/Assets.xcassets/AppIcon.appiconset/icon_20pt.png -------------------------------------------------------------------------------- /Example/Assets.xcassets/AppIcon.appiconset/icon_20pt@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asafkorem/sensor-visualizer-kit/574dbdbc3af11113c288e099bc49e438b80e81b8/Example/Assets.xcassets/AppIcon.appiconset/icon_20pt@2x-1.png -------------------------------------------------------------------------------- /Example/Assets.xcassets/AppIcon.appiconset/icon_20pt@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asafkorem/sensor-visualizer-kit/574dbdbc3af11113c288e099bc49e438b80e81b8/Example/Assets.xcassets/AppIcon.appiconset/icon_20pt@2x.png -------------------------------------------------------------------------------- /Example/Assets.xcassets/AppIcon.appiconset/icon_20pt@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asafkorem/sensor-visualizer-kit/574dbdbc3af11113c288e099bc49e438b80e81b8/Example/Assets.xcassets/AppIcon.appiconset/icon_20pt@3x.png -------------------------------------------------------------------------------- /Example/Assets.xcassets/AppIcon.appiconset/icon_29pt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asafkorem/sensor-visualizer-kit/574dbdbc3af11113c288e099bc49e438b80e81b8/Example/Assets.xcassets/AppIcon.appiconset/icon_29pt.png -------------------------------------------------------------------------------- /Example/Assets.xcassets/AppIcon.appiconset/icon_29pt@2x-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asafkorem/sensor-visualizer-kit/574dbdbc3af11113c288e099bc49e438b80e81b8/Example/Assets.xcassets/AppIcon.appiconset/icon_29pt@2x-2.png -------------------------------------------------------------------------------- /Example/Assets.xcassets/AppIcon.appiconset/icon_29pt@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asafkorem/sensor-visualizer-kit/574dbdbc3af11113c288e099bc49e438b80e81b8/Example/Assets.xcassets/AppIcon.appiconset/icon_29pt@2x.png -------------------------------------------------------------------------------- /Example/Assets.xcassets/AppIcon.appiconset/icon_29pt@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asafkorem/sensor-visualizer-kit/574dbdbc3af11113c288e099bc49e438b80e81b8/Example/Assets.xcassets/AppIcon.appiconset/icon_29pt@3x.png -------------------------------------------------------------------------------- /Example/Assets.xcassets/AppIcon.appiconset/icon_40pt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asafkorem/sensor-visualizer-kit/574dbdbc3af11113c288e099bc49e438b80e81b8/Example/Assets.xcassets/AppIcon.appiconset/icon_40pt.png -------------------------------------------------------------------------------- /Example/Assets.xcassets/AppIcon.appiconset/icon_40pt@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asafkorem/sensor-visualizer-kit/574dbdbc3af11113c288e099bc49e438b80e81b8/Example/Assets.xcassets/AppIcon.appiconset/icon_40pt@2x-1.png -------------------------------------------------------------------------------- /Example/Assets.xcassets/AppIcon.appiconset/icon_40pt@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asafkorem/sensor-visualizer-kit/574dbdbc3af11113c288e099bc49e438b80e81b8/Example/Assets.xcassets/AppIcon.appiconset/icon_40pt@2x.png -------------------------------------------------------------------------------- /Example/Assets.xcassets/AppIcon.appiconset/icon_40pt@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asafkorem/sensor-visualizer-kit/574dbdbc3af11113c288e099bc49e438b80e81b8/Example/Assets.xcassets/AppIcon.appiconset/icon_40pt@3x.png -------------------------------------------------------------------------------- /Example/Assets.xcassets/AppIcon.appiconset/icon_60pt@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asafkorem/sensor-visualizer-kit/574dbdbc3af11113c288e099bc49e438b80e81b8/Example/Assets.xcassets/AppIcon.appiconset/icon_60pt@2x.png -------------------------------------------------------------------------------- /Example/Assets.xcassets/AppIcon.appiconset/icon_60pt@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asafkorem/sensor-visualizer-kit/574dbdbc3af11113c288e099bc49e438b80e81b8/Example/Assets.xcassets/AppIcon.appiconset/icon_60pt@3x.png -------------------------------------------------------------------------------- /Example/Assets.xcassets/AppIcon.appiconset/icon_76pt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asafkorem/sensor-visualizer-kit/574dbdbc3af11113c288e099bc49e438b80e81b8/Example/Assets.xcassets/AppIcon.appiconset/icon_76pt.png -------------------------------------------------------------------------------- /Example/Assets.xcassets/AppIcon.appiconset/icon_76pt@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asafkorem/sensor-visualizer-kit/574dbdbc3af11113c288e099bc49e438b80e81b8/Example/Assets.xcassets/AppIcon.appiconset/icon_76pt@2x.png -------------------------------------------------------------------------------- /Example/Assets.xcassets/AppIcon.appiconset/icon_83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asafkorem/sensor-visualizer-kit/574dbdbc3af11113c288e099bc49e438b80e81b8/Example/Assets.xcassets/AppIcon.appiconset/icon_83.5@2x.png -------------------------------------------------------------------------------- /Example/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Example/Assets.xcassets/shake-phone.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "shake-phone.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Example/Assets.xcassets/shake-phone.imageset/shake-phone.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asafkorem/sensor-visualizer-kit/574dbdbc3af11113c288e099bc49e438b80e81b8/Example/Assets.xcassets/shake-phone.imageset/shake-phone.pdf -------------------------------------------------------------------------------- /Example/Assets.xcassets/shot-on-iphone/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Example/Assets.xcassets/shot-on-iphone/shot-on-iphone-0.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "shot-on-iphone-0.jpg" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Example/Assets.xcassets/shot-on-iphone/shot-on-iphone-0.imageset/shot-on-iphone-0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asafkorem/sensor-visualizer-kit/574dbdbc3af11113c288e099bc49e438b80e81b8/Example/Assets.xcassets/shot-on-iphone/shot-on-iphone-0.imageset/shot-on-iphone-0.jpg -------------------------------------------------------------------------------- /Example/Assets.xcassets/shot-on-iphone/shot-on-iphone-1.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "shot-on-iphone-1.jpg" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Example/Assets.xcassets/shot-on-iphone/shot-on-iphone-1.imageset/shot-on-iphone-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asafkorem/sensor-visualizer-kit/574dbdbc3af11113c288e099bc49e438b80e81b8/Example/Assets.xcassets/shot-on-iphone/shot-on-iphone-1.imageset/shot-on-iphone-1.jpg -------------------------------------------------------------------------------- /Example/Assets.xcassets/shot-on-iphone/shot-on-iphone-10.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "shot-on-iphone-10.jpg" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Example/Assets.xcassets/shot-on-iphone/shot-on-iphone-10.imageset/shot-on-iphone-10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asafkorem/sensor-visualizer-kit/574dbdbc3af11113c288e099bc49e438b80e81b8/Example/Assets.xcassets/shot-on-iphone/shot-on-iphone-10.imageset/shot-on-iphone-10.jpg -------------------------------------------------------------------------------- /Example/Assets.xcassets/shot-on-iphone/shot-on-iphone-11.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "shot-on-iphone-11.jpg" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Example/Assets.xcassets/shot-on-iphone/shot-on-iphone-11.imageset/shot-on-iphone-11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asafkorem/sensor-visualizer-kit/574dbdbc3af11113c288e099bc49e438b80e81b8/Example/Assets.xcassets/shot-on-iphone/shot-on-iphone-11.imageset/shot-on-iphone-11.jpg -------------------------------------------------------------------------------- /Example/Assets.xcassets/shot-on-iphone/shot-on-iphone-12.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "shot-on-iphone-12.jpg" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Example/Assets.xcassets/shot-on-iphone/shot-on-iphone-12.imageset/shot-on-iphone-12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asafkorem/sensor-visualizer-kit/574dbdbc3af11113c288e099bc49e438b80e81b8/Example/Assets.xcassets/shot-on-iphone/shot-on-iphone-12.imageset/shot-on-iphone-12.jpg -------------------------------------------------------------------------------- /Example/Assets.xcassets/shot-on-iphone/shot-on-iphone-2.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "shot-on-iphone-2.jpg" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Example/Assets.xcassets/shot-on-iphone/shot-on-iphone-2.imageset/shot-on-iphone-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asafkorem/sensor-visualizer-kit/574dbdbc3af11113c288e099bc49e438b80e81b8/Example/Assets.xcassets/shot-on-iphone/shot-on-iphone-2.imageset/shot-on-iphone-2.jpg -------------------------------------------------------------------------------- /Example/Assets.xcassets/shot-on-iphone/shot-on-iphone-3.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "shot-on-iphone-3.jpg" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Example/Assets.xcassets/shot-on-iphone/shot-on-iphone-3.imageset/shot-on-iphone-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asafkorem/sensor-visualizer-kit/574dbdbc3af11113c288e099bc49e438b80e81b8/Example/Assets.xcassets/shot-on-iphone/shot-on-iphone-3.imageset/shot-on-iphone-3.jpg -------------------------------------------------------------------------------- /Example/Assets.xcassets/shot-on-iphone/shot-on-iphone-4.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "shot-on-iphone-4.jpg" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Example/Assets.xcassets/shot-on-iphone/shot-on-iphone-4.imageset/shot-on-iphone-4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asafkorem/sensor-visualizer-kit/574dbdbc3af11113c288e099bc49e438b80e81b8/Example/Assets.xcassets/shot-on-iphone/shot-on-iphone-4.imageset/shot-on-iphone-4.jpg -------------------------------------------------------------------------------- /Example/Assets.xcassets/shot-on-iphone/shot-on-iphone-5.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "shot-on-iphone-5.jpg" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Example/Assets.xcassets/shot-on-iphone/shot-on-iphone-5.imageset/shot-on-iphone-5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asafkorem/sensor-visualizer-kit/574dbdbc3af11113c288e099bc49e438b80e81b8/Example/Assets.xcassets/shot-on-iphone/shot-on-iphone-5.imageset/shot-on-iphone-5.jpg -------------------------------------------------------------------------------- /Example/Assets.xcassets/shot-on-iphone/shot-on-iphone-6.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "shot-on-iphone-6.jpg" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Example/Assets.xcassets/shot-on-iphone/shot-on-iphone-6.imageset/shot-on-iphone-6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asafkorem/sensor-visualizer-kit/574dbdbc3af11113c288e099bc49e438b80e81b8/Example/Assets.xcassets/shot-on-iphone/shot-on-iphone-6.imageset/shot-on-iphone-6.jpg -------------------------------------------------------------------------------- /Example/Assets.xcassets/shot-on-iphone/shot-on-iphone-7.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "shot-on-iphone-7.jpg" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Example/Assets.xcassets/shot-on-iphone/shot-on-iphone-7.imageset/shot-on-iphone-7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asafkorem/sensor-visualizer-kit/574dbdbc3af11113c288e099bc49e438b80e81b8/Example/Assets.xcassets/shot-on-iphone/shot-on-iphone-7.imageset/shot-on-iphone-7.jpg -------------------------------------------------------------------------------- /Example/Assets.xcassets/shot-on-iphone/shot-on-iphone-8.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "shot-on-iphone-8.jpg" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Example/Assets.xcassets/shot-on-iphone/shot-on-iphone-8.imageset/shot-on-iphone-8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asafkorem/sensor-visualizer-kit/574dbdbc3af11113c288e099bc49e438b80e81b8/Example/Assets.xcassets/shot-on-iphone/shot-on-iphone-8.imageset/shot-on-iphone-8.jpg -------------------------------------------------------------------------------- /Example/Assets.xcassets/shot-on-iphone/shot-on-iphone-9.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "shot-on-iphone-9.jpg" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Example/Assets.xcassets/shot-on-iphone/shot-on-iphone-9.imageset/shot-on-iphone-9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asafkorem/sensor-visualizer-kit/574dbdbc3af11113c288e099bc49e438b80e81b8/Example/Assets.xcassets/shot-on-iphone/shot-on-iphone-9.imageset/shot-on-iphone-9.jpg -------------------------------------------------------------------------------- /Example/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 | -------------------------------------------------------------------------------- /Example/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | -------------------------------------------------------------------------------- /Example/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | Visualizer 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 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 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /Example/Root/Map/MapViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MapViewController.swift 3 | // SensorVisualizer 4 | // 5 | // Created by Joseph Blau on 6/26/16. 6 | // Copyright © 2016 CocoaPods. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import MapKit 11 | 12 | class MapViewController: UIViewController { 13 | 14 | @IBOutlet weak var mapView: MKMapView! 15 | 16 | override func viewDidLoad() { 17 | super.viewDidLoad() 18 | 19 | mapView.showsBuildings = true 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Example/Root/OptionsTableViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OptionsTableViewController.swift 3 | // 4 | // 5 | // Created by Joseph Blau on 3/22/16. 6 | // 7 | // 8 | 9 | import UIKit 10 | import SafariServices 11 | 12 | class OptionsTableViewController: UITableViewController { 13 | 14 | let resuseIdentifer = "Option Cell" 15 | let options = ["Tap", "Map", "Pan", "Web", "Shake", "Peek & Pop"] 16 | 17 | // MARK: - UITableViewDataSource 18 | 19 | override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 20 | return options.count 21 | } 22 | 23 | override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 24 | let cell = tableView.dequeueReusableCell(withIdentifier: resuseIdentifer, for: indexPath) 25 | cell.textLabel?.text = options[indexPath.row] 26 | return cell 27 | } 28 | 29 | // MARK: - UITableViewDelegate 30 | 31 | override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 32 | let option = options[indexPath.row] 33 | self.performSegue(withIdentifier: "Show \(option)", sender: self) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Example/Root/Pan/PanViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PanViewController.swift 3 | // SensorVisualizer 4 | // 5 | // Created by Joseph Blau on 5/15/16. 6 | // Copyright © 2016 CocoaPods. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class PanViewController: UIViewController { 12 | 13 | @IBOutlet weak var scrollView: UIScrollView! 14 | 15 | override func viewDidLoad() { 16 | super.viewDidLoad() 17 | 18 | scrollView.layoutIfNeeded() 19 | 20 | let scrollViewFrame = CGRect(x: 0, y: 0, width: scrollView.frame.width, height: 10000) 21 | scrollView.contentSize = scrollViewFrame.size 22 | 23 | let gradient = CAGradientLayer() 24 | gradient.frame = scrollViewFrame 25 | gradient.colors = [UIColor(red: 0.149, green: 0.651, blue: 0.604, alpha: 1.0).cgColor, 26 | UIColor(red: 0.400, green: 0.733, blue: 0.416, alpha: 1.0).cgColor, 27 | UIColor(red: 0.612, green: 0.800, blue: 0.396, alpha: 1.0).cgColor, 28 | UIColor(red: 0.831, green: 0.882, blue: 0.341, alpha: 1.0).cgColor, 29 | UIColor(red: 1.000, green: 0.933, blue: 0.345, alpha: 1.0).cgColor, 30 | UIColor(red: 1.000, green: 0.792, blue: 0.157, alpha: 1.0).cgColor, 31 | UIColor(red: 1.000, green: 0.655, blue: 0.149, alpha: 1.0).cgColor, 32 | UIColor(red: 1.000, green: 0.439, blue: 0.263, alpha: 1.0).cgColor, 33 | UIColor(red: 0.937, green: 0.325, blue: 0.314, alpha: 1.0).cgColor, 34 | UIColor(red: 0.925, green: 0.251, blue: 0.478, alpha: 1.0).cgColor, 35 | UIColor(red: 0.671, green: 0.278, blue: 0.737, alpha: 1.0).cgColor, 36 | UIColor(red: 0.494, green: 0.341, blue: 0.761, alpha: 1.0).cgColor, 37 | UIColor(red: 0.361, green: 0.420, blue: 0.753, alpha: 1.0).cgColor, 38 | UIColor(red: 0.259, green: 0.647, blue: 0.961, alpha: 1.0).cgColor, 39 | UIColor(red: 0.161, green: 0.714, blue: 0.965, alpha: 1.0).cgColor, 40 | UIColor(red: 0.149, green: 0.776, blue: 0.855, alpha: 1.0).cgColor] 41 | 42 | scrollView.layer.addSublayer(gradient) 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Example/Root/PeekPop/PeekPopCollectionViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PeekPopCollectionViewController.swift 3 | // SensorVisualizerKit-Example 4 | // 5 | // Created by Joe Blau on 4/9/19. 6 | // Copyright © 2019 SensorVisualizerKit. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class PeekPopCollectionViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout { 12 | 13 | let reuseIdentifier = "PeekPopCell" 14 | let images: [UIImage] = { 15 | return (0..<13).map { index in 16 | UIImage(named: "shot-on-iphone-\(index)")! 17 | } 18 | }() 19 | 20 | override func viewDidLoad() { 21 | super.viewDidLoad() 22 | registerForPreviewing(with: self, sourceView: collectionView) 23 | } 24 | 25 | override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 26 | return images.count 27 | } 28 | 29 | override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 30 | let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! PeekPopPreviewCollectionViewCell 31 | cell.previewImageView.image = images[indexPath.row] 32 | return cell 33 | } 34 | 35 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { 36 | let edge = (UIScreen.main.bounds.width / CGFloat(3.0)) - (2.0 / UIScreen.main.scale) 37 | return CGSize(width: edge, height: edge) 38 | } 39 | 40 | override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { 41 | performSegue(withIdentifier: "Show Detail", sender: self) 42 | } 43 | 44 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 45 | guard let destination = segue.destination as? PeekPopDetailViewController, 46 | let selectedRow = collectionView.indexPathsForSelectedItems?.first?.row else { return } 47 | destination.image = images[selectedRow] 48 | } 49 | } 50 | 51 | extension PeekPopCollectionViewController: UIViewControllerPreviewingDelegate { 52 | func previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? { 53 | 54 | let storyboard = UIStoryboard(name: "Main", bundle: nil) 55 | 56 | guard let selectedIndexPath = collectionView.indexPathForItem(at: location), 57 | let previewViewController = storyboard.instantiateViewController(withIdentifier: "PeekPopDetailViewController") as? PeekPopDetailViewController else { 58 | return nil 59 | } 60 | 61 | collectionView.selectItem(at: selectedIndexPath, animated: false, scrollPosition: .top) 62 | previewViewController.image = images[selectedIndexPath.row] 63 | return previewViewController 64 | } 65 | 66 | func previewingContext(_ previewingContext: UIViewControllerPreviewing, commit viewControllerToCommit: UIViewController) { 67 | performSegue(withIdentifier: "Show Detail", sender: self) 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /Example/Root/PeekPop/PeekPopDetailViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PeekPopDetailViewController.swift 3 | // SensorVisualizerKit-Example 4 | // 5 | // Created by Joe Blau on 4/9/19. 6 | // Copyright © 2019 SensorVisualizerKit. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class PeekPopDetailViewController: UIViewController { 12 | 13 | var image: UIImage? 14 | 15 | @IBOutlet weak var imageView: UIImageView! 16 | 17 | override func viewWillAppear(_ animated: Bool) { 18 | super.viewWillAppear(animated) 19 | imageView.image = image 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /Example/Root/PeekPop/PeekPopPreviewCollectionViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PeekPopPreviewCollectionViewCell.swift 3 | // SensorVisualizerKit-Example 4 | // 5 | // Created by Joe Blau on 4/9/19. 6 | // Copyright © 2019 SensorVisualizerKit. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class PeekPopPreviewCollectionViewCell: UICollectionViewCell { 12 | 13 | @IBOutlet weak var previewImageView: UIImageView! 14 | } 15 | -------------------------------------------------------------------------------- /Example/Root/Tap/TapViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TapViewController.swift 3 | // SensorVisualizer 4 | // 5 | // Created by Joseph Blau on 6/25/16. 6 | // Copyright © 2016 CocoaPods. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class TapViewController: UIViewController { 12 | 13 | @IBAction func touchedButton(_ sender: UIButton) { 14 | if let title = sender.titleLabel?.text { 15 | navigationItem.prompt = "Pressed \(title.capitalized)" 16 | } 17 | } 18 | 19 | @IBAction func selectSegement(_ sender: UISegmentedControl) { 20 | if let selectedTitle = sender.titleForSegment(at: sender.selectedSegmentIndex) { 21 | navigationItem.prompt = "Segment \(selectedTitle.capitalized)" 22 | } 23 | } 24 | 25 | @IBAction func toggleSwitch(_ sender: UISwitch) { 26 | navigationItem.prompt = "Switch \(sender.isOn.description.capitalized)" 27 | } 28 | 29 | @IBAction func pressStepper(_ sender: UIStepper) { 30 | navigationItem.prompt = "Step \(sender.value)" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Example/Root/Web/WebViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // WebViewController.swift 3 | // SensorVisualizer 4 | // 5 | // Created by Joseph Blau on 6/25/16. 6 | // Copyright © 2016 CocoaPods. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import WebKit 11 | 12 | class WebViewController: UIViewController, WKNavigationDelegate { 13 | 14 | @IBOutlet weak var webView: WKWebView! 15 | 16 | override func viewDidLoad() { 17 | super.viewDidLoad() 18 | let url = URL(string: "https://www.apple.com")! 19 | webView.load(URLRequest(url: url)) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 - 2020 Joe Blau 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 | 23 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.1 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "SensorVisualizerKit", 8 | products: [ 9 | .library( 10 | name: "SensorVisualizerKit", 11 | targets: ["SensorVisualizerKit"]), 12 | ], 13 | dependencies: [], 14 | targets: [ 15 | .target( 16 | name: "SensorVisualizerKit", 17 | dependencies: [], 18 | path: "Sources"), 19 | ] 20 | ) 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SensorVisualizerKit 2 | 3 | [![](https://img.shields.io/badge/swift-5-brightgreen.svg?style=flat-square)](https://swift.org) 4 | [![](https://img.shields.io/badge/platform-iOS-brightgreen.svg?style=flat-square)](https://www.apple.com/ios/) 5 | [![](https://img.shields.io/github/license/joeblau/sensor-visualizer-kit.svg?style=flat-square)](https://github.com/joeblau/sensor-visualizer-kit/blob/master/LICENSE) 6 | 7 | Visualize iOS sensors for live presentations, iOS AppStore demos, Apple Store prototypes, design reviews. 8 | 9 | [![](.github/demo.gif)](https://vimeo.com/331486696) 10 | 11 | ## Install 12 | 13 | **Carthage:** To integrate SensorVisualizerKit into your Xcode project using Carthage, specify it in your `Cartfile`: 14 | 15 | ```sh 16 | github "joeblau/sensor-visualizer-kit" ~> 0.1.1 17 | ``` 18 | 19 | **Cocoapods:** To integrate SensorVisualizerKit into your Xcode project using CocoaPods, specify it in your `Podfile`: 20 | 21 | ```sh 22 | pod 'SensorVisualizerKit', '~> 0.1.1' 23 | ``` 24 | 25 | ## Use 26 | 27 | **Storyboards** 28 | 29 | ```swift 30 | import UIKit 31 | import SensorVisualizerKit 32 | 33 | @UIApplicationMain 34 | class AppDelegate: UIResponder, UIApplicationDelegate { 35 | 36 | var window: UIWindow? = { 37 | return SensorVisualizerWindow(frame: UIScreen.main.bounds) 38 | }() 39 | 40 | func application(_ application: UIApplication, 41 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 42 | return true 43 | } 44 | } 45 | 46 | ``` 47 | 48 | **Programatic** 49 | 50 | ```swift 51 | import UIKit 52 | import SensorVisualizerKit 53 | 54 | @UIApplicationMain 55 | class AppDelegate: UIResponder, UIApplicationDelegate { 56 | 57 | var window: UIWindow? 58 | 59 | func application(_ application: UIApplication, 60 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 61 | window = SensorVisualizerWindow(frame: UIScreen.main.bounds) 62 | window?.rootViewController = ViewController() 63 | window?.makeKeyAndVisible() 64 | return true 65 | } 66 | } 67 | ``` 68 | 69 | ## Configure 70 | 71 | The method signature for initializing the SesnorVisuzliserWindow takes 1 required property and 2 optional properties 72 | 73 | - **frame:** The size of the window which is usually the screen bounds 74 | - **primary _(optional)_:** The tap and shake color which defaults to the tint color 75 | - **secondary _(optional)_:** The tap border color which defaults to the tint color 76 | 77 | ## Sensors 78 | 79 | **Sensor Visualizer Kit** 80 | 81 | - [x] **Accelerometer:** An accelerometer measures changes in velocity along one axis. 82 | - [ ] **Bluetooth Radio:** A wireless technology standard for exchanging data between fixed and mobile devices over short distances using short-wavelength. 83 | - [x] **Capacitive pressure sensors (3D Touch):** When you press the display, capacitive sensors instantly measure microscopic changes in the distance between the cover glass and the backlight. iOS uses these measurements to provide fast, accurate, and continuous response to finger pressure. 84 | - [x] **Digitizer:** Thin plastic film attached to the screen. It’s sensitive to your finger movements, and sends information about the position and movements of your fingers to the motherboard. 85 | - [ ] **Linear Actuator (Taptic Engine)** - A device that can reproduce the sensation of motion or generate new and distinct tactile experiences. 86 | - [ ] **Physical Button:** 87 | - [ ] **Physical Switch:** 88 | 89 | **Native iOS** 90 | 91 | - [x] **Battery:** A device consisting of one or more electrochemical cells with external connections provided to power electrical devices. 92 | - [x] **Cellular Network Radio:** A communication network where the last link is wireless. 93 | - [x] **Clock:** An instrument used to measure, keep, and indicate time. 94 | - [x] **Global Positioning System (GPS):** A global navigation satellite system that provides geolocation and time information to a GPS receiver anywhere on or near the Earth where there is an unobstructed line of sight to four or more GPS satellites. 95 | - [x] **Wi-Fi Radio:** A family of radio technologies that is commonly used for the wireless local area networking. 96 | 97 | ## Limitations 98 | 99 | The visualizer does not work with all controllers. The operating system can present controllers above the application window. These controllers do not work with the sensor visualizer. 100 | 101 | - [AVPlayerViewController](https://developer.apple.com/documentation/avkit/avplayerviewcontroller) 102 | - [SFSafariViewController](https://developer.apple.com/documentation/safariservices/sfsafariviewcontroller) 103 | - [UIAlertController](https://developer.apple.com/documentation/uikit/uialertcontroller) 104 | 105 | -------------------------------------------------------------------------------- /SensorVisualizerKit.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "SensorVisualizerKit" 3 | s.version = "0.1" 4 | s.summary = "Visualize iOS sensors" 5 | s.description = <<-DESC 6 | Visualize iOS sensors for live presentations, iOS AppStore demos, Apple Store prototypes, design reviews. 7 | DESC 8 | s.homepage = "https://github.com/joeblau/sensor-visualizer-kit" 9 | s.license = { :type => "MIT", :file => "LICENSE" } 10 | s.author = { "Joe Blau" => "holla@joeblau.com" } 11 | s.social_media_url = "https://twitter.com/joeblau" 12 | s.ios.deployment_target = "9.0" 13 | s.source = { :git => "https://github.com/joeblau/sensor-visualizer-kit.git", :tag => s.version.to_s } 14 | s.swift_version = '5.0' 15 | s.source_files = "Sources/**/*" 16 | s.frameworks = "UIKit" 17 | end 18 | -------------------------------------------------------------------------------- /SensorVisualizerKit.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 47; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | E646A57E225CC18D0086B500 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E646A57D225CC18D0086B500 /* AppDelegate.swift */; }; 11 | E646A583225CC18D0086B500 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E646A581225CC18D0086B500 /* Main.storyboard */; }; 12 | E646A585225CC18E0086B500 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E646A584225CC18E0086B500 /* Assets.xcassets */; }; 13 | E646A588225CC18E0086B500 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E646A586225CC18E0086B500 /* LaunchScreen.storyboard */; }; 14 | E646A58E225CC2470086B500 /* SensorVisualizerWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = E646A58D225CC2470086B500 /* SensorVisualizerWindow.swift */; }; 15 | E646A590225CC7690086B500 /* SensorVisualizerWindow+Touch.swift in Sources */ = {isa = PBXBuildFile; fileRef = E646A58F225CC7690086B500 /* SensorVisualizerWindow+Touch.swift */; }; 16 | E646A594225CE34E0086B500 /* UIView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E646A593225CE34E0086B500 /* UIView+Extensions.swift */; }; 17 | E646A596225D188A0086B500 /* CAAnimationGroup+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E646A595225D188A0086B500 /* CAAnimationGroup+Extensions.swift */; }; 18 | E646A5A7225D32E40086B500 /* OptionsTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E646A5A6225D32E40086B500 /* OptionsTableViewController.swift */; }; 19 | E646A5AE225D333B0086B500 /* TapViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E646A5AD225D333B0086B500 /* TapViewController.swift */; }; 20 | E646A5B0225D33420086B500 /* MapViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E646A5AF225D33420086B500 /* MapViewController.swift */; }; 21 | E646A5B4225D334C0086B500 /* PanViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E646A5B3225D334C0086B500 /* PanViewController.swift */; }; 22 | E646A5B9225D3E0D0086B500 /* PeekPopDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E646A5B8225D3E0D0086B500 /* PeekPopDetailViewController.swift */; }; 23 | E646A5BB225D48470086B500 /* PeekPopCollectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E646A5BA225D48470086B500 /* PeekPopCollectionViewController.swift */; }; 24 | E646A5BD225D49E00086B500 /* PeekPopPreviewCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = E646A5BC225D49E00086B500 /* PeekPopPreviewCollectionViewCell.swift */; }; 25 | E646A5BF225D59360086B500 /* WebViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E646A5BE225D59360086B500 /* WebViewController.swift */; }; 26 | E646A5C3225D5B200086B500 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E646A5C2225D5B200086B500 /* WebKit.framework */; }; 27 | E646A5C5225D87BD0086B500 /* SensorVisualizerWindow+Shake.swift in Sources */ = {isa = PBXBuildFile; fileRef = E646A5C4225D87BD0086B500 /* SensorVisualizerWindow+Shake.swift */; }; 28 | E646A5C8225E42A70086B500 /* UIPushBehavior+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E646A5C7225E42A70086B500 /* UIPushBehavior+Extensions.swift */; }; 29 | E646A5CB225E43A00086B500 /* UIAttachmentBehavior+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E646A5CA225E43A00086B500 /* UIAttachmentBehavior+Extensions.swift */; }; 30 | E646A5D0225E633A0086B500 /* SensorVisualizerKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52D6D97C1BEFF229002C0205 /* SensorVisualizerKit.framework */; }; 31 | E646A5D1225E633A0086B500 /* SensorVisualizerKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 52D6D97C1BEFF229002C0205 /* SensorVisualizerKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 32 | /* End PBXBuildFile section */ 33 | 34 | /* Begin PBXContainerItemProxy section */ 35 | E646A5D2225E633A0086B500 /* PBXContainerItemProxy */ = { 36 | isa = PBXContainerItemProxy; 37 | containerPortal = 52D6D9731BEFF229002C0205 /* Project object */; 38 | proxyType = 1; 39 | remoteGlobalIDString = 52D6D97B1BEFF229002C0205; 40 | remoteInfo = "SensorVisualizerKit-iOS"; 41 | }; 42 | /* End PBXContainerItemProxy section */ 43 | 44 | /* Begin PBXCopyFilesBuildPhase section */ 45 | E646A5D4225E633B0086B500 /* Embed Frameworks */ = { 46 | isa = PBXCopyFilesBuildPhase; 47 | buildActionMask = 2147483647; 48 | dstPath = ""; 49 | dstSubfolderSpec = 10; 50 | files = ( 51 | E646A5D1225E633A0086B500 /* SensorVisualizerKit.framework in Embed Frameworks */, 52 | ); 53 | name = "Embed Frameworks"; 54 | runOnlyForDeploymentPostprocessing = 0; 55 | }; 56 | /* End PBXCopyFilesBuildPhase section */ 57 | 58 | /* Begin PBXFileReference section */ 59 | 52D6D97C1BEFF229002C0205 /* SensorVisualizerKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SensorVisualizerKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 60 | AD2FAA261CD0B6D800659CF4 /* SensorVisualizerKit.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = SensorVisualizerKit.plist; sourceTree = ""; }; 61 | E646A57B225CC18D0086B500 /* SensorVisualizerKit-Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "SensorVisualizerKit-Example.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 62 | E646A57D225CC18D0086B500 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 63 | E646A582225CC18D0086B500 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 64 | E646A584225CC18E0086B500 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 65 | E646A587225CC18E0086B500 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 66 | E646A589225CC18E0086B500 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 67 | E646A58D225CC2470086B500 /* SensorVisualizerWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SensorVisualizerWindow.swift; sourceTree = ""; }; 68 | E646A58F225CC7690086B500 /* SensorVisualizerWindow+Touch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SensorVisualizerWindow+Touch.swift"; sourceTree = ""; }; 69 | E646A593225CE34E0086B500 /* UIView+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+Extensions.swift"; sourceTree = ""; }; 70 | E646A595225D188A0086B500 /* CAAnimationGroup+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CAAnimationGroup+Extensions.swift"; sourceTree = ""; }; 71 | E646A5A6225D32E40086B500 /* OptionsTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OptionsTableViewController.swift; sourceTree = ""; }; 72 | E646A5AD225D333B0086B500 /* TapViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TapViewController.swift; sourceTree = ""; }; 73 | E646A5AF225D33420086B500 /* MapViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MapViewController.swift; sourceTree = ""; }; 74 | E646A5B3225D334C0086B500 /* PanViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PanViewController.swift; sourceTree = ""; }; 75 | E646A5B8225D3E0D0086B500 /* PeekPopDetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PeekPopDetailViewController.swift; sourceTree = ""; }; 76 | E646A5BA225D48470086B500 /* PeekPopCollectionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PeekPopCollectionViewController.swift; sourceTree = ""; }; 77 | E646A5BC225D49E00086B500 /* PeekPopPreviewCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PeekPopPreviewCollectionViewCell.swift; sourceTree = ""; }; 78 | E646A5BE225D59360086B500 /* WebViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WebViewController.swift; sourceTree = ""; }; 79 | E646A5C2225D5B200086B500 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; }; 80 | E646A5C4225D87BD0086B500 /* SensorVisualizerWindow+Shake.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SensorVisualizerWindow+Shake.swift"; sourceTree = ""; }; 81 | E646A5C7225E42A70086B500 /* UIPushBehavior+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIPushBehavior+Extensions.swift"; sourceTree = ""; }; 82 | E646A5CA225E43A00086B500 /* UIAttachmentBehavior+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIAttachmentBehavior+Extensions.swift"; sourceTree = ""; }; 83 | /* End PBXFileReference section */ 84 | 85 | /* Begin PBXFrameworksBuildPhase section */ 86 | 52D6D9781BEFF229002C0205 /* Frameworks */ = { 87 | isa = PBXFrameworksBuildPhase; 88 | buildActionMask = 2147483647; 89 | files = ( 90 | ); 91 | runOnlyForDeploymentPostprocessing = 0; 92 | }; 93 | E646A578225CC18D0086B500 /* Frameworks */ = { 94 | isa = PBXFrameworksBuildPhase; 95 | buildActionMask = 2147483647; 96 | files = ( 97 | E646A5C3225D5B200086B500 /* WebKit.framework in Frameworks */, 98 | E646A5D0225E633A0086B500 /* SensorVisualizerKit.framework in Frameworks */, 99 | ); 100 | runOnlyForDeploymentPostprocessing = 0; 101 | }; 102 | /* End PBXFrameworksBuildPhase section */ 103 | 104 | /* Begin PBXGroup section */ 105 | 52D6D9721BEFF229002C0205 = { 106 | isa = PBXGroup; 107 | children = ( 108 | E646A57C225CC18D0086B500 /* Example */, 109 | 8933C7811EB5B7E0000D00A4 /* Sources */, 110 | 52D6D99C1BEFF38C002C0205 /* Configs */, 111 | 52D6D97D1BEFF229002C0205 /* Products */, 112 | E646A5C1225D5B200086B500 /* Frameworks */, 113 | ); 114 | sourceTree = ""; 115 | }; 116 | 52D6D97D1BEFF229002C0205 /* Products */ = { 117 | isa = PBXGroup; 118 | children = ( 119 | 52D6D97C1BEFF229002C0205 /* SensorVisualizerKit.framework */, 120 | E646A57B225CC18D0086B500 /* SensorVisualizerKit-Example.app */, 121 | ); 122 | name = Products; 123 | sourceTree = ""; 124 | }; 125 | 52D6D99C1BEFF38C002C0205 /* Configs */ = { 126 | isa = PBXGroup; 127 | children = ( 128 | DD7502721C68FC1B006590AF /* Frameworks */, 129 | ); 130 | path = Configs; 131 | sourceTree = ""; 132 | }; 133 | 8933C7811EB5B7E0000D00A4 /* Sources */ = { 134 | isa = PBXGroup; 135 | children = ( 136 | E646A58D225CC2470086B500 /* SensorVisualizerWindow.swift */, 137 | E646A58F225CC7690086B500 /* SensorVisualizerWindow+Touch.swift */, 138 | E646A5C4225D87BD0086B500 /* SensorVisualizerWindow+Shake.swift */, 139 | E646A593225CE34E0086B500 /* UIView+Extensions.swift */, 140 | E646A595225D188A0086B500 /* CAAnimationGroup+Extensions.swift */, 141 | E646A5C7225E42A70086B500 /* UIPushBehavior+Extensions.swift */, 142 | E646A5CA225E43A00086B500 /* UIAttachmentBehavior+Extensions.swift */, 143 | ); 144 | path = Sources; 145 | sourceTree = ""; 146 | }; 147 | DD7502721C68FC1B006590AF /* Frameworks */ = { 148 | isa = PBXGroup; 149 | children = ( 150 | AD2FAA261CD0B6D800659CF4 /* SensorVisualizerKit.plist */, 151 | ); 152 | name = Frameworks; 153 | sourceTree = ""; 154 | }; 155 | E646A57C225CC18D0086B500 /* Example */ = { 156 | isa = PBXGroup; 157 | children = ( 158 | E646A57D225CC18D0086B500 /* AppDelegate.swift */, 159 | E646A5A5225D32CB0086B500 /* Root */, 160 | E646A581225CC18D0086B500 /* Main.storyboard */, 161 | E646A584225CC18E0086B500 /* Assets.xcassets */, 162 | E646A586225CC18E0086B500 /* LaunchScreen.storyboard */, 163 | E646A589225CC18E0086B500 /* Info.plist */, 164 | ); 165 | path = Example; 166 | sourceTree = ""; 167 | }; 168 | E646A5A5225D32CB0086B500 /* Root */ = { 169 | isa = PBXGroup; 170 | children = ( 171 | E646A5A6225D32E40086B500 /* OptionsTableViewController.swift */, 172 | E646A5AA225D33180086B500 /* Pan */, 173 | E646A5C0225D59400086B500 /* Web */, 174 | E646A5A9225D330E0086B500 /* Map */, 175 | E646A5A8225D32F70086B500 /* Tap */, 176 | E646A5B5225D3C6E0086B500 /* PeekPop */, 177 | ); 178 | path = Root; 179 | sourceTree = ""; 180 | }; 181 | E646A5A8225D32F70086B500 /* Tap */ = { 182 | isa = PBXGroup; 183 | children = ( 184 | E646A5AD225D333B0086B500 /* TapViewController.swift */, 185 | ); 186 | path = Tap; 187 | sourceTree = ""; 188 | }; 189 | E646A5A9225D330E0086B500 /* Map */ = { 190 | isa = PBXGroup; 191 | children = ( 192 | E646A5AF225D33420086B500 /* MapViewController.swift */, 193 | ); 194 | path = Map; 195 | sourceTree = ""; 196 | }; 197 | E646A5AA225D33180086B500 /* Pan */ = { 198 | isa = PBXGroup; 199 | children = ( 200 | E646A5B3225D334C0086B500 /* PanViewController.swift */, 201 | ); 202 | path = Pan; 203 | sourceTree = ""; 204 | }; 205 | E646A5B5225D3C6E0086B500 /* PeekPop */ = { 206 | isa = PBXGroup; 207 | children = ( 208 | E646A5BA225D48470086B500 /* PeekPopCollectionViewController.swift */, 209 | E646A5B8225D3E0D0086B500 /* PeekPopDetailViewController.swift */, 210 | E646A5BC225D49E00086B500 /* PeekPopPreviewCollectionViewCell.swift */, 211 | ); 212 | path = PeekPop; 213 | sourceTree = ""; 214 | }; 215 | E646A5C0225D59400086B500 /* Web */ = { 216 | isa = PBXGroup; 217 | children = ( 218 | E646A5BE225D59360086B500 /* WebViewController.swift */, 219 | ); 220 | path = Web; 221 | sourceTree = ""; 222 | }; 223 | E646A5C1225D5B200086B500 /* Frameworks */ = { 224 | isa = PBXGroup; 225 | children = ( 226 | E646A5C2225D5B200086B500 /* WebKit.framework */, 227 | ); 228 | name = Frameworks; 229 | sourceTree = ""; 230 | }; 231 | /* End PBXGroup section */ 232 | 233 | /* Begin PBXHeadersBuildPhase section */ 234 | 52D6D9791BEFF229002C0205 /* Headers */ = { 235 | isa = PBXHeadersBuildPhase; 236 | buildActionMask = 2147483647; 237 | files = ( 238 | ); 239 | runOnlyForDeploymentPostprocessing = 0; 240 | }; 241 | /* End PBXHeadersBuildPhase section */ 242 | 243 | /* Begin PBXNativeTarget section */ 244 | 52D6D97B1BEFF229002C0205 /* SensorVisualizerKit-iOS */ = { 245 | isa = PBXNativeTarget; 246 | buildConfigurationList = 52D6D9901BEFF229002C0205 /* Build configuration list for PBXNativeTarget "SensorVisualizerKit-iOS" */; 247 | buildPhases = ( 248 | 52D6D9771BEFF229002C0205 /* Sources */, 249 | 52D6D9781BEFF229002C0205 /* Frameworks */, 250 | 52D6D9791BEFF229002C0205 /* Headers */, 251 | 52D6D97A1BEFF229002C0205 /* Resources */, 252 | ); 253 | buildRules = ( 254 | ); 255 | dependencies = ( 256 | ); 257 | name = "SensorVisualizerKit-iOS"; 258 | productName = SensorVisualizerKit; 259 | productReference = 52D6D97C1BEFF229002C0205 /* SensorVisualizerKit.framework */; 260 | productType = "com.apple.product-type.framework"; 261 | }; 262 | E646A57A225CC18D0086B500 /* SensorVisualizerKit-Example */ = { 263 | isa = PBXNativeTarget; 264 | buildConfigurationList = E646A58A225CC18E0086B500 /* Build configuration list for PBXNativeTarget "SensorVisualizerKit-Example" */; 265 | buildPhases = ( 266 | E646A577225CC18D0086B500 /* Sources */, 267 | E646A578225CC18D0086B500 /* Frameworks */, 268 | E646A579225CC18D0086B500 /* Resources */, 269 | E646A5D4225E633B0086B500 /* Embed Frameworks */, 270 | ); 271 | buildRules = ( 272 | ); 273 | dependencies = ( 274 | E646A5D3225E633A0086B500 /* PBXTargetDependency */, 275 | ); 276 | name = "SensorVisualizerKit-Example"; 277 | productName = "SensorVisualizerKit-Example"; 278 | productReference = E646A57B225CC18D0086B500 /* SensorVisualizerKit-Example.app */; 279 | productType = "com.apple.product-type.application"; 280 | }; 281 | /* End PBXNativeTarget section */ 282 | 283 | /* Begin PBXProject section */ 284 | 52D6D9731BEFF229002C0205 /* Project object */ = { 285 | isa = PBXProject; 286 | attributes = { 287 | LastSwiftUpdateCheck = 1020; 288 | LastUpgradeCheck = 1020; 289 | ORGANIZATIONNAME = SensorVisualizerKit; 290 | TargetAttributes = { 291 | 52D6D97B1BEFF229002C0205 = { 292 | CreatedOnToolsVersion = 7.1; 293 | DevelopmentTeam = K78G42H4U2; 294 | LastSwiftMigration = 1020; 295 | }; 296 | E646A57A225CC18D0086B500 = { 297 | CreatedOnToolsVersion = 10.2; 298 | DevelopmentTeam = K78G42H4U2; 299 | ProvisioningStyle = Automatic; 300 | }; 301 | }; 302 | }; 303 | buildConfigurationList = 52D6D9761BEFF229002C0205 /* Build configuration list for PBXProject "SensorVisualizerKit" */; 304 | compatibilityVersion = "Xcode 6.3"; 305 | developmentRegion = en; 306 | hasScannedForEncodings = 0; 307 | knownRegions = ( 308 | en, 309 | Base, 310 | ); 311 | mainGroup = 52D6D9721BEFF229002C0205; 312 | productRefGroup = 52D6D97D1BEFF229002C0205 /* Products */; 313 | projectDirPath = ""; 314 | projectRoot = ""; 315 | targets = ( 316 | 52D6D97B1BEFF229002C0205 /* SensorVisualizerKit-iOS */, 317 | E646A57A225CC18D0086B500 /* SensorVisualizerKit-Example */, 318 | ); 319 | }; 320 | /* End PBXProject section */ 321 | 322 | /* Begin PBXResourcesBuildPhase section */ 323 | 52D6D97A1BEFF229002C0205 /* Resources */ = { 324 | isa = PBXResourcesBuildPhase; 325 | buildActionMask = 2147483647; 326 | files = ( 327 | ); 328 | runOnlyForDeploymentPostprocessing = 0; 329 | }; 330 | E646A579225CC18D0086B500 /* Resources */ = { 331 | isa = PBXResourcesBuildPhase; 332 | buildActionMask = 2147483647; 333 | files = ( 334 | E646A588225CC18E0086B500 /* LaunchScreen.storyboard in Resources */, 335 | E646A585225CC18E0086B500 /* Assets.xcassets in Resources */, 336 | E646A583225CC18D0086B500 /* Main.storyboard in Resources */, 337 | ); 338 | runOnlyForDeploymentPostprocessing = 0; 339 | }; 340 | /* End PBXResourcesBuildPhase section */ 341 | 342 | /* Begin PBXSourcesBuildPhase section */ 343 | 52D6D9771BEFF229002C0205 /* Sources */ = { 344 | isa = PBXSourcesBuildPhase; 345 | buildActionMask = 2147483647; 346 | files = ( 347 | E646A596225D188A0086B500 /* CAAnimationGroup+Extensions.swift in Sources */, 348 | E646A5C8225E42A70086B500 /* UIPushBehavior+Extensions.swift in Sources */, 349 | E646A5C5225D87BD0086B500 /* SensorVisualizerWindow+Shake.swift in Sources */, 350 | E646A594225CE34E0086B500 /* UIView+Extensions.swift in Sources */, 351 | E646A58E225CC2470086B500 /* SensorVisualizerWindow.swift in Sources */, 352 | E646A590225CC7690086B500 /* SensorVisualizerWindow+Touch.swift in Sources */, 353 | E646A5CB225E43A00086B500 /* UIAttachmentBehavior+Extensions.swift in Sources */, 354 | ); 355 | runOnlyForDeploymentPostprocessing = 0; 356 | }; 357 | E646A577225CC18D0086B500 /* Sources */ = { 358 | isa = PBXSourcesBuildPhase; 359 | buildActionMask = 2147483647; 360 | files = ( 361 | E646A5BB225D48470086B500 /* PeekPopCollectionViewController.swift in Sources */, 362 | E646A5AE225D333B0086B500 /* TapViewController.swift in Sources */, 363 | E646A5B9225D3E0D0086B500 /* PeekPopDetailViewController.swift in Sources */, 364 | E646A5BD225D49E00086B500 /* PeekPopPreviewCollectionViewCell.swift in Sources */, 365 | E646A5B0225D33420086B500 /* MapViewController.swift in Sources */, 366 | E646A57E225CC18D0086B500 /* AppDelegate.swift in Sources */, 367 | E646A5A7225D32E40086B500 /* OptionsTableViewController.swift in Sources */, 368 | E646A5B4225D334C0086B500 /* PanViewController.swift in Sources */, 369 | E646A5BF225D59360086B500 /* WebViewController.swift in Sources */, 370 | ); 371 | runOnlyForDeploymentPostprocessing = 0; 372 | }; 373 | /* End PBXSourcesBuildPhase section */ 374 | 375 | /* Begin PBXTargetDependency section */ 376 | E646A5D3225E633A0086B500 /* PBXTargetDependency */ = { 377 | isa = PBXTargetDependency; 378 | target = 52D6D97B1BEFF229002C0205 /* SensorVisualizerKit-iOS */; 379 | targetProxy = E646A5D2225E633A0086B500 /* PBXContainerItemProxy */; 380 | }; 381 | /* End PBXTargetDependency section */ 382 | 383 | /* Begin PBXVariantGroup section */ 384 | E646A581225CC18D0086B500 /* Main.storyboard */ = { 385 | isa = PBXVariantGroup; 386 | children = ( 387 | E646A582225CC18D0086B500 /* Base */, 388 | ); 389 | name = Main.storyboard; 390 | sourceTree = ""; 391 | }; 392 | E646A586225CC18E0086B500 /* LaunchScreen.storyboard */ = { 393 | isa = PBXVariantGroup; 394 | children = ( 395 | E646A587225CC18E0086B500 /* Base */, 396 | ); 397 | name = LaunchScreen.storyboard; 398 | sourceTree = ""; 399 | }; 400 | /* End PBXVariantGroup section */ 401 | 402 | /* Begin XCBuildConfiguration section */ 403 | 52D6D98E1BEFF229002C0205 /* Debug */ = { 404 | isa = XCBuildConfiguration; 405 | buildSettings = { 406 | ALWAYS_SEARCH_USER_PATHS = NO; 407 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 408 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 409 | CLANG_CXX_LIBRARY = "libc++"; 410 | CLANG_ENABLE_MODULES = YES; 411 | CLANG_ENABLE_OBJC_ARC = YES; 412 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 413 | CLANG_WARN_BOOL_CONVERSION = YES; 414 | CLANG_WARN_COMMA = YES; 415 | CLANG_WARN_CONSTANT_CONVERSION = YES; 416 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 417 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 418 | CLANG_WARN_EMPTY_BODY = YES; 419 | CLANG_WARN_ENUM_CONVERSION = YES; 420 | CLANG_WARN_INFINITE_RECURSION = YES; 421 | CLANG_WARN_INT_CONVERSION = YES; 422 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 423 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 424 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 425 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 426 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 427 | CLANG_WARN_STRICT_PROTOTYPES = YES; 428 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 429 | CLANG_WARN_UNREACHABLE_CODE = YES; 430 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 431 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 432 | COPY_PHASE_STRIP = NO; 433 | CURRENT_PROJECT_VERSION = 1; 434 | DEBUG_INFORMATION_FORMAT = dwarf; 435 | ENABLE_STRICT_OBJC_MSGSEND = YES; 436 | ENABLE_TESTABILITY = YES; 437 | GCC_C_LANGUAGE_STANDARD = gnu99; 438 | GCC_DYNAMIC_NO_PIC = NO; 439 | GCC_NO_COMMON_BLOCKS = YES; 440 | GCC_OPTIMIZATION_LEVEL = 0; 441 | GCC_PREPROCESSOR_DEFINITIONS = ( 442 | "DEBUG=1", 443 | "$(inherited)", 444 | ); 445 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 446 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 447 | GCC_WARN_UNDECLARED_SELECTOR = YES; 448 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 449 | GCC_WARN_UNUSED_FUNCTION = YES; 450 | GCC_WARN_UNUSED_VARIABLE = YES; 451 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 452 | MTL_ENABLE_DEBUG_INFO = YES; 453 | ONLY_ACTIVE_ARCH = YES; 454 | SDKROOT = iphoneos; 455 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 456 | SWIFT_VERSION = 5.0; 457 | TARGETED_DEVICE_FAMILY = "1,2"; 458 | VERSIONING_SYSTEM = "apple-generic"; 459 | VERSION_INFO_PREFIX = ""; 460 | }; 461 | name = Debug; 462 | }; 463 | 52D6D98F1BEFF229002C0205 /* Release */ = { 464 | isa = XCBuildConfiguration; 465 | buildSettings = { 466 | ALWAYS_SEARCH_USER_PATHS = NO; 467 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 468 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 469 | CLANG_CXX_LIBRARY = "libc++"; 470 | CLANG_ENABLE_MODULES = YES; 471 | CLANG_ENABLE_OBJC_ARC = YES; 472 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 473 | CLANG_WARN_BOOL_CONVERSION = YES; 474 | CLANG_WARN_COMMA = YES; 475 | CLANG_WARN_CONSTANT_CONVERSION = YES; 476 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 477 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 478 | CLANG_WARN_EMPTY_BODY = YES; 479 | CLANG_WARN_ENUM_CONVERSION = YES; 480 | CLANG_WARN_INFINITE_RECURSION = YES; 481 | CLANG_WARN_INT_CONVERSION = YES; 482 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 483 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 484 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 485 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 486 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 487 | CLANG_WARN_STRICT_PROTOTYPES = YES; 488 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 489 | CLANG_WARN_UNREACHABLE_CODE = YES; 490 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 491 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 492 | COPY_PHASE_STRIP = NO; 493 | CURRENT_PROJECT_VERSION = 1; 494 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 495 | ENABLE_NS_ASSERTIONS = NO; 496 | ENABLE_STRICT_OBJC_MSGSEND = YES; 497 | GCC_C_LANGUAGE_STANDARD = gnu99; 498 | GCC_NO_COMMON_BLOCKS = YES; 499 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 500 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 501 | GCC_WARN_UNDECLARED_SELECTOR = YES; 502 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 503 | GCC_WARN_UNUSED_FUNCTION = YES; 504 | GCC_WARN_UNUSED_VARIABLE = YES; 505 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 506 | MTL_ENABLE_DEBUG_INFO = NO; 507 | SDKROOT = iphoneos; 508 | SWIFT_VERSION = 5.0; 509 | TARGETED_DEVICE_FAMILY = "1,2"; 510 | VALIDATE_PRODUCT = YES; 511 | VERSIONING_SYSTEM = "apple-generic"; 512 | VERSION_INFO_PREFIX = ""; 513 | }; 514 | name = Release; 515 | }; 516 | 52D6D9911BEFF229002C0205 /* Debug */ = { 517 | isa = XCBuildConfiguration; 518 | buildSettings = { 519 | APPLICATION_EXTENSION_API_ONLY = YES; 520 | CLANG_ENABLE_MODULES = YES; 521 | CODE_SIGN_IDENTITY = "iPhone Developer"; 522 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 523 | DEFINES_MODULE = YES; 524 | DEVELOPMENT_TEAM = K78G42H4U2; 525 | DYLIB_COMPATIBILITY_VERSION = 1; 526 | DYLIB_CURRENT_VERSION = 1; 527 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 528 | INFOPLIST_FILE = Configs/SensorVisualizerKit.plist; 529 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 530 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 531 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 532 | ONLY_ACTIVE_ARCH = NO; 533 | PRODUCT_BUNDLE_IDENTIFIER = "com.SensorVisualizerKit.SensorVisualizerKit-iOS"; 534 | PRODUCT_NAME = SensorVisualizerKit; 535 | SKIP_INSTALL = YES; 536 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 537 | SWIFT_VERSION = 5.0; 538 | }; 539 | name = Debug; 540 | }; 541 | 52D6D9921BEFF229002C0205 /* Release */ = { 542 | isa = XCBuildConfiguration; 543 | buildSettings = { 544 | APPLICATION_EXTENSION_API_ONLY = YES; 545 | CLANG_ENABLE_MODULES = YES; 546 | CODE_SIGN_IDENTITY = "iPhone Developer"; 547 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 548 | DEFINES_MODULE = YES; 549 | DEVELOPMENT_TEAM = K78G42H4U2; 550 | DYLIB_COMPATIBILITY_VERSION = 1; 551 | DYLIB_CURRENT_VERSION = 1; 552 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 553 | INFOPLIST_FILE = Configs/SensorVisualizerKit.plist; 554 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 555 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 556 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 557 | PRODUCT_BUNDLE_IDENTIFIER = "com.SensorVisualizerKit.SensorVisualizerKit-iOS"; 558 | PRODUCT_NAME = SensorVisualizerKit; 559 | SKIP_INSTALL = YES; 560 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 561 | SWIFT_VERSION = 5.0; 562 | }; 563 | name = Release; 564 | }; 565 | E646A58B225CC18E0086B500 /* Debug */ = { 566 | isa = XCBuildConfiguration; 567 | buildSettings = { 568 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 569 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 570 | CLANG_ANALYZER_NONNULL = YES; 571 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 572 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 573 | CLANG_ENABLE_OBJC_WEAK = YES; 574 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 575 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 576 | CODE_SIGN_IDENTITY = "iPhone Developer"; 577 | CODE_SIGN_STYLE = Automatic; 578 | DEVELOPMENT_TEAM = K78G42H4U2; 579 | GCC_C_LANGUAGE_STANDARD = gnu11; 580 | INFOPLIST_FILE = Example/Info.plist; 581 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 582 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 583 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 584 | MTL_FAST_MATH = YES; 585 | PRODUCT_BUNDLE_IDENTIFIER = "com.joeblau.SensorVisualizerKit-Example"; 586 | PRODUCT_NAME = "$(TARGET_NAME)"; 587 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 588 | SWIFT_VERSION = 5.0; 589 | TARGETED_DEVICE_FAMILY = "1,2"; 590 | }; 591 | name = Debug; 592 | }; 593 | E646A58C225CC18E0086B500 /* Release */ = { 594 | isa = XCBuildConfiguration; 595 | buildSettings = { 596 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 597 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 598 | CLANG_ANALYZER_NONNULL = YES; 599 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 600 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 601 | CLANG_ENABLE_OBJC_WEAK = YES; 602 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 603 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 604 | CODE_SIGN_IDENTITY = "iPhone Developer"; 605 | CODE_SIGN_STYLE = Automatic; 606 | DEVELOPMENT_TEAM = K78G42H4U2; 607 | GCC_C_LANGUAGE_STANDARD = gnu11; 608 | INFOPLIST_FILE = Example/Info.plist; 609 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 610 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 611 | MTL_FAST_MATH = YES; 612 | PRODUCT_BUNDLE_IDENTIFIER = "com.joeblau.SensorVisualizerKit-Example"; 613 | PRODUCT_NAME = "$(TARGET_NAME)"; 614 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 615 | SWIFT_VERSION = 5.0; 616 | TARGETED_DEVICE_FAMILY = "1,2"; 617 | }; 618 | name = Release; 619 | }; 620 | /* End XCBuildConfiguration section */ 621 | 622 | /* Begin XCConfigurationList section */ 623 | 52D6D9761BEFF229002C0205 /* Build configuration list for PBXProject "SensorVisualizerKit" */ = { 624 | isa = XCConfigurationList; 625 | buildConfigurations = ( 626 | 52D6D98E1BEFF229002C0205 /* Debug */, 627 | 52D6D98F1BEFF229002C0205 /* Release */, 628 | ); 629 | defaultConfigurationIsVisible = 0; 630 | defaultConfigurationName = Release; 631 | }; 632 | 52D6D9901BEFF229002C0205 /* Build configuration list for PBXNativeTarget "SensorVisualizerKit-iOS" */ = { 633 | isa = XCConfigurationList; 634 | buildConfigurations = ( 635 | 52D6D9911BEFF229002C0205 /* Debug */, 636 | 52D6D9921BEFF229002C0205 /* Release */, 637 | ); 638 | defaultConfigurationIsVisible = 0; 639 | defaultConfigurationName = Release; 640 | }; 641 | E646A58A225CC18E0086B500 /* Build configuration list for PBXNativeTarget "SensorVisualizerKit-Example" */ = { 642 | isa = XCConfigurationList; 643 | buildConfigurations = ( 644 | E646A58B225CC18E0086B500 /* Debug */, 645 | E646A58C225CC18E0086B500 /* Release */, 646 | ); 647 | defaultConfigurationIsVisible = 0; 648 | defaultConfigurationName = Release; 649 | }; 650 | /* End XCConfigurationList section */ 651 | }; 652 | rootObject = 52D6D9731BEFF229002C0205 /* Project object */; 653 | } 654 | -------------------------------------------------------------------------------- /SensorVisualizerKit.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SensorVisualizerKit.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /SensorVisualizerKit.xcodeproj/xcshareddata/xcschemes/SensorVisualizerKit-Example.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 | -------------------------------------------------------------------------------- /SensorVisualizerKit.xcodeproj/xcshareddata/xcschemes/SensorVisualizerKit-iOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 34 | 40 | 41 | 42 | 43 | 44 | 50 | 51 | 52 | 53 | 54 | 55 | 65 | 66 | 72 | 73 | 74 | 75 | 76 | 77 | 83 | 84 | 90 | 91 | 92 | 93 | 95 | 96 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /Sources/CAAnimationGroup+Extensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CAAnimationGroup+Extensions.swift 3 | // SensorVisualizerKit-iOS 4 | // 5 | // Created by Joe Blau on 4/9/19. 6 | // Copyright © 2019 SensorVisualizerKit. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | extension CAAnimationGroup { 12 | static var createTouchAnimation: CAAnimationGroup { 13 | let opacityAnimation = CABasicAnimation(keyPath: "opacity") 14 | opacityAnimation.toValue = 0.7 15 | 16 | let borderAnimation = CABasicAnimation(keyPath: "borderWidth") 17 | borderAnimation.toValue = 4 18 | 19 | let scaleAnimation = CABasicAnimation(keyPath: "transform.scale") 20 | scaleAnimation.toValue = 0.4 21 | 22 | return buildGroup(animations: [borderAnimation, scaleAnimation, opacityAnimation]) 23 | } 24 | 25 | static var removeTouchAnimation: CAAnimationGroup { 26 | let opacityAnimation = CABasicAnimation(keyPath: "opacity") 27 | opacityAnimation.toValue = 0.0 28 | 29 | let borderAnimation = CABasicAnimation(keyPath: "borderWidth") 30 | borderAnimation.toValue = 0 31 | 32 | let scaleAnimation = CABasicAnimation(keyPath: "transform.scale") 33 | scaleAnimation.toValue = 1.4 34 | 35 | return buildGroup(animations: [borderAnimation, scaleAnimation, opacityAnimation]) 36 | } 37 | 38 | static var pressTouchAnimation: CAAnimationGroup { 39 | let opacityAnimation = CABasicAnimation(keyPath: "opacity") 40 | opacityAnimation.toValue = 0.7 41 | 42 | let borderAnimation = CABasicAnimation(keyPath: "borderWidth") 43 | borderAnimation.toValue = 4 44 | 45 | let scaleAnimation = CABasicAnimation(keyPath: "transform.scale") 46 | scaleAnimation.toValue = 0.4 47 | 48 | return buildGroup(animations: [borderAnimation, scaleAnimation, opacityAnimation]) 49 | } 50 | 51 | static var peekTouchAnimation: CAAnimationGroup { 52 | let opacityAnimation = CABasicAnimation(keyPath: "opacity") 53 | opacityAnimation.toValue = 0.7 54 | 55 | let borderAnimation = CABasicAnimation(keyPath: "borderWidth") 56 | borderAnimation.toValue = 4 57 | 58 | let scaleAnimation = CABasicAnimation(keyPath: "transform.scale") 59 | scaleAnimation.toValue = 0.8 60 | 61 | return buildGroup(animations: [borderAnimation, scaleAnimation, opacityAnimation]) 62 | } 63 | 64 | static var popTouchAnimation: CAAnimationGroup { 65 | let opacityAnimation = CABasicAnimation(keyPath: "opacity") 66 | opacityAnimation.toValue = 0.7 67 | 68 | let borderAnimation = CABasicAnimation(keyPath: "borderWidth") 69 | borderAnimation.toValue = 4 70 | 71 | let scaleAnimation = CABasicAnimation(keyPath: "transform.scale") 72 | scaleAnimation.toValue = 1.2 73 | 74 | return buildGroup(animations: [borderAnimation, scaleAnimation, opacityAnimation]) 75 | } 76 | 77 | // MARK: - Private 78 | 79 | private static func buildGroup(animations: [CAAnimation]) -> CAAnimationGroup { 80 | let group = CAAnimationGroup() 81 | group.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeOut) 82 | group.isRemovedOnCompletion = false 83 | group.fillMode = CAMediaTimingFillMode.forwards 84 | group.duration = 0.3 85 | group.animations = animations 86 | return group 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /Sources/SensorVisualizerWindow+Shake.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SensorVisualizerWindow+Shake.swift 3 | // SensorVisualizerKit 4 | // 5 | // Created by Joe Blau on 4/9/19. 6 | // Copyright © 2019 SensorVisualizerKit. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | fileprivate protocol ShakeVisualizable { 12 | func shake(intensity: CGFloat) 13 | } 14 | 15 | extension SensorVisualizerWindow: ShakeVisualizable { 16 | 17 | public override func motionEnded(_ motion: UIEvent.EventSubtype, with event: UIEvent?) { 18 | if event?.subtype == .motionShake { 19 | shake(intensity: 1800) 20 | shake(intensity: -1800) 21 | } 22 | } 23 | 24 | fileprivate func shake(intensity: CGFloat) { 25 | guard let windowView = visualizationWindow.rootViewController?.view else { return } 26 | let shakeView = UIView.buildShakeView(rootView: windowView, shakeColor: primaryColor) 27 | 28 | windowView.addSubview(shakeView) 29 | animator?.addBehavior(UIAttachmentBehavior.shake(item: shakeView, anchor: windowView.center)) 30 | animator?.addBehavior(UIPushBehavior.shake(items: [shakeView], intensity: intensity)) 31 | 32 | DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) { 33 | shakeView.removeFromSuperview() 34 | } 35 | } 36 | 37 | } 38 | 39 | -------------------------------------------------------------------------------- /Sources/SensorVisualizerWindow+Touch.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SensorVisualizerWindow+Touch.swift 3 | // SensorVisualizerKit-iOS 4 | // 5 | // Created by Joe Blau on 4/9/19. 6 | // Copyright © 2019 SensorVisualizerKit. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | fileprivate protocol TouchVisualizable { 12 | func create(touch: UITouch) 13 | func move(touch: UITouch) 14 | func remove(touch: UITouch) 15 | func peek(touch: UITouch) 16 | func pop(touch: UITouch) 17 | } 18 | 19 | extension SensorVisualizerWindow: TouchVisualizable { 20 | 21 | public override func sendEvent(_ event: UIEvent) { 22 | super.sendEvent(event) 23 | event.allTouches? 24 | .forEach { touch in 25 | 26 | switch touch.phase { 27 | case .began: create(touch: touch) 28 | case .moved: move(touch: touch) 29 | case .ended, .cancelled: remove(touch: touch) 30 | case .stationary: break 31 | @unknown default: break 32 | } 33 | 34 | if #available(iOS 9.0, *) { 35 | switch touch.force / touch.maximumPossibleForce { 36 | case 0.45..<0.9: peek(touch: touch) 37 | case 0.9..<1.0: pop(touch: touch) 38 | default: break 39 | } 40 | } 41 | } 42 | } 43 | 44 | fileprivate func create(touch: UITouch) { 45 | guard let windowView = visualizationWindow.rootViewController?.view else { return } 46 | 47 | let touchView = UIView.buildTouchView(touchColor: primaryColor, borderColor: secondaryColor) 48 | touchView.center = touch.location(in: windowView) 49 | 50 | windowView.addSubview(touchView) 51 | touchPointViews[touch] = touchView 52 | touchView.layer.add(CAAnimationGroup.createTouchAnimation, forKey: "addTouch") 53 | } 54 | 55 | fileprivate func move(touch: UITouch) { 56 | guard let windowView = visualizationWindow.rootViewController?.view else { return } 57 | touchPointViews[touch]?.center = touch.location(in: windowView) 58 | } 59 | 60 | fileprivate func remove(touch: UITouch) { 61 | CATransaction.begin() 62 | CATransaction.setCompletionBlock { 63 | self.touchPointViews 64 | .removeValue(forKey: touch)? 65 | .removeFromSuperview() 66 | } 67 | touchPointViews[touch]?.layer.add(CAAnimationGroup.removeTouchAnimation, forKey: "removeTouch") 68 | CATransaction.commit() 69 | } 70 | 71 | fileprivate func peek(touch: UITouch) { 72 | touchPointViews[touch]?.layer.removeAnimation(forKey: "addTouch") 73 | if touchPointViews[touch]?.layer.animationKeys()?.contains("peekTouch") ?? false { 74 | return 75 | } 76 | touchPointViews[touch]?.layer.add(CAAnimationGroup.peekTouchAnimation, forKey: "peekTouch") 77 | } 78 | 79 | fileprivate func pop(touch: UITouch) { 80 | touchPointViews[touch]?.layer.removeAnimation(forKey: "peekTouch") 81 | if touchPointViews[touch]?.layer.animationKeys()?.contains("popTouch") ?? false { 82 | return 83 | } 84 | touchPointViews[touch]?.layer.add(CAAnimationGroup.popTouchAnimation, forKey: "popTouch") 85 | } 86 | 87 | } 88 | -------------------------------------------------------------------------------- /Sources/SensorVisualizerWindow.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SensorVisualizerWindow.swift 3 | // SensorVisualizerKit-iOS 4 | // 5 | // Created by Joe Blau on 4/9/19. 6 | // Copyright © 2019 SensorVisualizerKit. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public class SensorVisualizerWindow: UIWindow { 12 | 13 | let primaryColor: UIColor 14 | let secondaryColor: UIColor 15 | var animator: UIDynamicAnimator? 16 | 17 | var touchPointViews = [UITouch: UIView]() 18 | 19 | internal let visualizationWindow: UIWindow = { 20 | let window = UIWindow(frame: UIScreen.main.bounds) 21 | window.isUserInteractionEnabled = false 22 | window.windowLevel = UIWindow.Level.statusBar 23 | window.backgroundColor = .clear 24 | window.isHidden = false 25 | window.rootViewController = UIViewController() 26 | window.rootViewController?.view.frame = UIScreen.main.bounds 27 | return window 28 | }() 29 | 30 | /// Initialize a sensor visualizer window 31 | /// 32 | /// - Parameters: 33 | /// - frame: The size of the window which is usually the screen bounds 34 | /// - primary (optional): The tap and shake color which defaults to the tint color 35 | /// - secondary (optional): The tap border color which defaults to the tint color 36 | public init(frame: CGRect, 37 | primary: UIColor = UIView().tintColor, 38 | secondary: UIColor = UIView().tintColor) { 39 | self.primaryColor = primary 40 | self.secondaryColor = secondary 41 | 42 | super.init(frame: frame) 43 | if let windowView = visualizationWindow.rootViewController?.view { 44 | self.animator = UIDynamicAnimator(referenceView: windowView) 45 | } 46 | } 47 | 48 | @available(iOSApplicationExtension 13.0, *) 49 | public init(windowScene: UIWindowScene, 50 | primary: UIColor = UIView().tintColor, 51 | secondary: UIColor = UIView().tintColor) { 52 | self.primaryColor = primary 53 | self.secondaryColor = secondary 54 | 55 | super.init(windowScene: windowScene) 56 | if let windowView = visualizationWindow.rootViewController?.view { 57 | self.animator = UIDynamicAnimator(referenceView: windowView) 58 | } 59 | } 60 | 61 | required init?(coder aDecoder: NSCoder) { 62 | fatalError("init(coder:) has not been implemented") 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /Sources/UIAttachmentBehavior+Extensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIAttachmentBehavior+Extensions.swift 3 | // SensorVisualizerKit 4 | // 5 | // Created by Joe Blau on 4/10/19. 6 | // Copyright © 2019 SensorVisualizerKit. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | extension UIAttachmentBehavior { 12 | static func shake(item: UIDynamicItem, anchor: CGPoint) -> UIAttachmentBehavior { 13 | let attachmentBehavior = UIAttachmentBehavior(item: item, attachedToAnchor: anchor) 14 | attachmentBehavior.damping = 0.1 15 | attachmentBehavior.frequency = 4.0 16 | return attachmentBehavior 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Sources/UIPushBehavior+Extensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIPushBehavior+Extensions.swift 3 | // SensorVisualizerKit 4 | // 5 | // Created by Joe Blau on 4/10/19. 6 | // Copyright © 2019 SensorVisualizerKit. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | extension UIPushBehavior { 12 | static func shake(items: [UIDynamicItem], intensity: CGFloat) -> UIPushBehavior { 13 | let pushBehavior = UIPushBehavior(items: items, mode: .instantaneous) 14 | pushBehavior.pushDirection = CGVector(dx: intensity, dy: 0) 15 | return pushBehavior 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Sources/UIView+Extensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+Touch.swift 3 | // SensorVisualizerKit-iOS 4 | // 5 | // Created by Joe Blau on 4/9/19. 6 | // Copyright © 2019 SensorVisualizerKit. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | extension UIView { 12 | static func buildTouchView(touchColor: UIColor, borderColor: UIColor) -> UIView { 13 | let view = UIView(frame: CGRect(x: 0, y: 0, width: 64, height: 64)) 14 | view.layer.backgroundColor = touchColor.cgColor 15 | view.layer.borderWidth = 1 16 | view.layer.borderColor = borderColor.cgColor 17 | view.layer.cornerRadius = view.frame.height / 2 18 | view.layer.opacity = 1.0 19 | return view 20 | } 21 | 22 | static func buildShakeView(rootView: UIView, shakeColor: UIColor) -> UIView { 23 | let shakePath = UIBezierPath(rect: UIScreen.main.bounds.insetBy(dx: -100, dy: -100)) 24 | let maskPath = UIBezierPath(rect: UIScreen.main.bounds) 25 | shakePath.append(maskPath) 26 | shakePath.usesEvenOddFillRule = true 27 | 28 | let layer = CAShapeLayer() 29 | layer.path = shakePath.cgPath 30 | layer.fillRule = CAShapeLayerFillRule.evenOdd 31 | layer.fillColor = shakeColor.cgColor 32 | layer.opacity = 0.4 33 | 34 | let view = UIView(frame: rootView.bounds) 35 | view.layer.addSublayer(layer) 36 | return view 37 | } 38 | } 39 | --------------------------------------------------------------------------------