├── .gitignore ├── BJDraggable.podspec ├── BJDraggable ├── 1.0 │ └── BJDraggable.podspec ├── 1.1 │ └── BJDraggable.podspec └── 1.2 │ └── BJDraggable.podspec ├── BJDraggableDemo.xcodeproj ├── project.pbxproj └── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ └── IDEWorkspaceChecks.plist ├── BJDraggableDemo ├── AppDelegate.swift ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── Contents.json ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── Info.plist ├── Source │ └── BJDraggable.swift └── ViewController.swift ├── LICENSE ├── README.md └── Resources └── BJDraggable.gif /.gitignore: -------------------------------------------------------------------------------- 1 | # xcode noise 2 | build/ 3 | *.pbxuser 4 | *.mode1v3 5 | *.mode2v3 6 | *.perspectivev3 7 | xcuserdata/ 8 | *.xccheckout 9 | 10 | # old skool 11 | .svn 12 | 13 | # osx noise 14 | .DS_Store 15 | profile 16 | 17 | # vim noise 18 | *~ 19 | *.swp 20 | 21 | # AppCode noise 22 | .idea/ 23 | 24 | # Ruby 25 | .ruby-version 26 | 27 | # Carthage 28 | Carthage/Build -------------------------------------------------------------------------------- /BJDraggable.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod spec lint BJDraggable.podspec' to ensure this is a 3 | # valid spec and to remove all comments including this before submitting the spec. 4 | # 5 | # To learn more about Podspec attributes see http://docs.cocoapods.org/specification.html 6 | # To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/ 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | 11 | # ――― Spec Metadata ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 12 | # 13 | # These will help people to find your library, and whilst it 14 | # can feel like a chore to fill in it's definitely to your advantage. The 15 | # summary should be tweet-length, and the description more in depth. 16 | # 17 | 18 | s.name = "BJDraggable" 19 | s.version = "1.4" 20 | s.summary = "Enables any UIView to be dragged and dropped within a boundary view." 21 | 22 | s.description = "A simple protocol utilising the powerful UIKitDynamics API, which makes ANY UIView draggable within a boundary view that acts as collision body, with a single method call. Works for any UIView." 23 | 24 | s.homepage = "https://github.com/BadhanGanesh/BJDraggable.git" 25 | # s.screenshots = "https://github.com/BadhanGanesh/BJDraggable/blob/master/Resources/BJDraggable.gif" 26 | 27 | 28 | # ――― Spec License ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 29 | # 30 | # Licensing your code is important. See http://choosealicense.com for more info. 31 | # CocoaPods will detect a license file if there is a named LICENSE* 32 | # Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'. 33 | # 34 | 35 | s.license = { :type => "MIT", :file => "LICENSE" } 36 | 37 | 38 | # ――― Author Metadata ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 39 | # 40 | # Specify the authors of the library, with email addresses. Email addresses 41 | # of the authors are extracted from the SCM log. E.g. $ git log. CocoaPods also 42 | # accepts just a name if you'd rather not provide an email address. 43 | # 44 | # Specify a social_media_url where others can refer to, for example a twitter 45 | # profile URL. 46 | # 47 | 48 | s.author = { "BadhanGanesh" => "ganesh_randy@yahoo.com" } 49 | # Or just: s.author = "BadhanGanesh" 50 | # s.authors = { "BadhanGanesh" => "ganesh_randy@yahoo.com" } 51 | # s.social_media_url = "http://twitter.com/badhanganesh" 52 | 53 | # ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 54 | # 55 | # If this Pod runs only on iOS or OS X, then specify the platform and 56 | # the deployment target. You can optionally include the target after the platform. 57 | # 58 | 59 | s.platform = :ios 60 | s.platform = :ios, "9.0" 61 | s.swift_version = "5.0" 62 | 63 | # When using multiple platforms 64 | # s.ios.deployment_target = "5.0" 65 | # s.osx.deployment_target = "10.7" 66 | # s.watchos.deployment_target = "2.0" 67 | # s.tvos.deployment_target = "9.0" 68 | 69 | 70 | # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 71 | # 72 | # Specify the location from where the source should be retrieved. 73 | # Supports git, hg, bzr, svn and HTTP. 74 | # 75 | 76 | s.source = { :git => "https://github.com/BadhanGanesh/BJDraggable.git", :tag => "#{s.version}" } 77 | 78 | 79 | # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 80 | # 81 | # CocoaPods is smart about how it includes source code. For source files 82 | # giving a folder will include any swift, h, m, mm, c & cpp files. 83 | # For header files it will include any header in the folder. 84 | # Not including the public_header_files will make all headers public. 85 | # 86 | 87 | s.source_files = "BJDraggableDemo/Source/*.{swift}" 88 | s.exclude_files = "Classes/Exclude" 89 | 90 | # s.public_header_files = "Classes/**/*.h" 91 | 92 | 93 | # ――― Resources ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 94 | # 95 | # A list of resources included with the Pod. These are copied into the 96 | # target bundle with a build phase script. Anything else will be cleaned. 97 | # You can preserve files from being cleaned, please don't preserve 98 | # non-essential files like tests, examples and documentation. 99 | # 100 | 101 | # s.resource = "icon.png" 102 | s.resources = "Resources/*.gif" 103 | 104 | # s.preserve_paths = "FilesToSave", "MoreFilesToSave" 105 | 106 | 107 | # ――― Project Linking ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 108 | # 109 | # Link your library with frameworks, or libraries. Libraries do not include 110 | # the lib prefix of their name. 111 | # 112 | 113 | # s.framework = "SomeFramework" 114 | # s.frameworks = "SomeFramework", "AnotherFramework" 115 | 116 | # s.library = "iconv" 117 | # s.libraries = "iconv", "xml2" 118 | 119 | 120 | # ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 121 | # 122 | # If your library depends on compiler flags you can set them in the xcconfig hash 123 | # where they will only apply to your library. If you depend on other Podspecs 124 | # you can include multiple dependencies to ensure it works. 125 | 126 | # s.requires_arc = true 127 | 128 | # s.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" } 129 | # s.dependency "JSONKit", "~> 1.4" 130 | 131 | end 132 | -------------------------------------------------------------------------------- /BJDraggable/1.0/BJDraggable.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod spec lint BJDraggable.podspec' to ensure this is a 3 | # valid spec and to remove all comments including this before submitting the spec. 4 | # 5 | # To learn more about Podspec attributes see http://docs.cocoapods.org/specification.html 6 | # To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/ 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | 11 | # ――― Spec Metadata ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 12 | # 13 | # These will help people to find your library, and whilst it 14 | # can feel like a chore to fill in it's definitely to your advantage. The 15 | # summary should be tweet-length, and the description more in depth. 16 | # 17 | 18 | s.name = "BJDraggable" 19 | s.version = "1.0" 20 | s.summary = "Enables any UIView to be dragged and dropped within a boundary view." 21 | 22 | s.description = "A simple protocol utilising the powerful UIKitDynamics API, which makes ANY UIView draggable within a boundary view that acts as collision body, with a single method call. Works for any UIView." 23 | 24 | s.homepage = "https://github.com/BadhanGanesh/BJDraggable.git" 25 | # s.screenshots = "https://github.com/BadhanGanesh/BJDraggable/blob/master/Resources/BJDraggable.gif" 26 | 27 | 28 | # ――― Spec License ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 29 | # 30 | # Licensing your code is important. See http://choosealicense.com for more info. 31 | # CocoaPods will detect a license file if there is a named LICENSE* 32 | # Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'. 33 | # 34 | 35 | s.license = { :type => "MIT", :file => "LICENSE" } 36 | 37 | 38 | # ――― Author Metadata ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 39 | # 40 | # Specify the authors of the library, with email addresses. Email addresses 41 | # of the authors are extracted from the SCM log. E.g. $ git log. CocoaPods also 42 | # accepts just a name if you'd rather not provide an email address. 43 | # 44 | # Specify a social_media_url where others can refer to, for example a twitter 45 | # profile URL. 46 | # 47 | 48 | s.author = { "BadhanGanesh" => "ganesh_randy@yahoo.com" } 49 | # Or just: s.author = "BadhanGanesh" 50 | # s.authors = { "BadhanGanesh" => "ganesh_randy@yahoo.com" } 51 | # s.social_media_url = "http://twitter.com/badhanganesh" 52 | 53 | # ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 54 | # 55 | # If this Pod runs only on iOS or OS X, then specify the platform and 56 | # the deployment target. You can optionally include the target after the platform. 57 | # 58 | 59 | s.platform = :ios 60 | s.platform = :ios, "10.0" 61 | s.swift_version = "4.1" 62 | 63 | # When using multiple platforms 64 | # s.ios.deployment_target = "5.0" 65 | # s.osx.deployment_target = "10.7" 66 | # s.watchos.deployment_target = "2.0" 67 | # s.tvos.deployment_target = "9.0" 68 | 69 | 70 | # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 71 | # 72 | # Specify the location from where the source should be retrieved. 73 | # Supports git, hg, bzr, svn and HTTP. 74 | # 75 | 76 | s.source = { :git => "https://github.com/BadhanGanesh/BJDraggable.git", :tag => "#{s.version}" } 77 | 78 | 79 | # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 80 | # 81 | # CocoaPods is smart about how it includes source code. For source files 82 | # giving a folder will include any swift, h, m, mm, c & cpp files. 83 | # For header files it will include any header in the folder. 84 | # Not including the public_header_files will make all headers public. 85 | # 86 | 87 | s.source_files = "BJDraggableDemo/Source/*.{swift}" 88 | s.exclude_files = "Classes/Exclude" 89 | 90 | # s.public_header_files = "Classes/**/*.h" 91 | 92 | 93 | # ――― Resources ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 94 | # 95 | # A list of resources included with the Pod. These are copied into the 96 | # target bundle with a build phase script. Anything else will be cleaned. 97 | # You can preserve files from being cleaned, please don't preserve 98 | # non-essential files like tests, examples and documentation. 99 | # 100 | 101 | # s.resource = "icon.png" 102 | s.resources = "Resources/*.gif" 103 | 104 | # s.preserve_paths = "FilesToSave", "MoreFilesToSave" 105 | 106 | 107 | # ――― Project Linking ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 108 | # 109 | # Link your library with frameworks, or libraries. Libraries do not include 110 | # the lib prefix of their name. 111 | # 112 | 113 | # s.framework = "SomeFramework" 114 | # s.frameworks = "SomeFramework", "AnotherFramework" 115 | 116 | # s.library = "iconv" 117 | # s.libraries = "iconv", "xml2" 118 | 119 | 120 | # ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 121 | # 122 | # If your library depends on compiler flags you can set them in the xcconfig hash 123 | # where they will only apply to your library. If you depend on other Podspecs 124 | # you can include multiple dependencies to ensure it works. 125 | 126 | # s.requires_arc = true 127 | 128 | # s.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" } 129 | # s.dependency "JSONKit", "~> 1.4" 130 | 131 | end 132 | -------------------------------------------------------------------------------- /BJDraggable/1.1/BJDraggable.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod spec lint BJDraggable.podspec' to ensure this is a 3 | # valid spec and to remove all comments including this before submitting the spec. 4 | # 5 | # To learn more about Podspec attributes see http://docs.cocoapods.org/specification.html 6 | # To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/ 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | 11 | # ――― Spec Metadata ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 12 | # 13 | # These will help people to find your library, and whilst it 14 | # can feel like a chore to fill in it's definitely to your advantage. The 15 | # summary should be tweet-length, and the description more in depth. 16 | # 17 | 18 | s.name = "BJDraggable" 19 | s.version = "1.1" 20 | s.summary = "Enables any UIView to be dragged and dropped within a boundary view." 21 | 22 | s.description = "A simple protocol utilising the powerful UIKitDynamics API, which makes ANY UIView draggable within a boundary view that acts as collision body, with a single method call. Works for any UIView." 23 | 24 | s.homepage = "https://github.com/BadhanGanesh/BJDraggable.git" 25 | # s.screenshots = "https://github.com/BadhanGanesh/BJDraggable/blob/master/Resources/BJDraggable.gif" 26 | 27 | 28 | # ――― Spec License ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 29 | # 30 | # Licensing your code is important. See http://choosealicense.com for more info. 31 | # CocoaPods will detect a license file if there is a named LICENSE* 32 | # Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'. 33 | # 34 | 35 | s.license = { :type => "MIT", :file => "LICENSE" } 36 | 37 | 38 | # ――― Author Metadata ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 39 | # 40 | # Specify the authors of the library, with email addresses. Email addresses 41 | # of the authors are extracted from the SCM log. E.g. $ git log. CocoaPods also 42 | # accepts just a name if you'd rather not provide an email address. 43 | # 44 | # Specify a social_media_url where others can refer to, for example a twitter 45 | # profile URL. 46 | # 47 | 48 | s.author = { "BadhanGanesh" => "ganesh_randy@yahoo.com" } 49 | # Or just: s.author = "BadhanGanesh" 50 | # s.authors = { "BadhanGanesh" => "ganesh_randy@yahoo.com" } 51 | # s.social_media_url = "http://twitter.com/badhanganesh" 52 | 53 | # ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 54 | # 55 | # If this Pod runs only on iOS or OS X, then specify the platform and 56 | # the deployment target. You can optionally include the target after the platform. 57 | # 58 | 59 | s.platform = :ios 60 | s.platform = :ios, "10.0" 61 | s.swift_version = "4.1" 62 | 63 | # When using multiple platforms 64 | # s.ios.deployment_target = "5.0" 65 | # s.osx.deployment_target = "10.7" 66 | # s.watchos.deployment_target = "2.0" 67 | # s.tvos.deployment_target = "9.0" 68 | 69 | 70 | # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 71 | # 72 | # Specify the location from where the source should be retrieved. 73 | # Supports git, hg, bzr, svn and HTTP. 74 | # 75 | 76 | s.source = { :git => "https://github.com/BadhanGanesh/BJDraggable.git", :tag => "#{s.version}" } 77 | 78 | 79 | # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 80 | # 81 | # CocoaPods is smart about how it includes source code. For source files 82 | # giving a folder will include any swift, h, m, mm, c & cpp files. 83 | # For header files it will include any header in the folder. 84 | # Not including the public_header_files will make all headers public. 85 | # 86 | 87 | s.source_files = "BJDraggableDemo/Source/*.{swift}" 88 | s.exclude_files = "Classes/Exclude" 89 | 90 | # s.public_header_files = "Classes/**/*.h" 91 | 92 | 93 | # ――― Resources ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 94 | # 95 | # A list of resources included with the Pod. These are copied into the 96 | # target bundle with a build phase script. Anything else will be cleaned. 97 | # You can preserve files from being cleaned, please don't preserve 98 | # non-essential files like tests, examples and documentation. 99 | # 100 | 101 | # s.resource = "icon.png" 102 | s.resources = "Resources/*.gif" 103 | 104 | # s.preserve_paths = "FilesToSave", "MoreFilesToSave" 105 | 106 | 107 | # ――― Project Linking ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 108 | # 109 | # Link your library with frameworks, or libraries. Libraries do not include 110 | # the lib prefix of their name. 111 | # 112 | 113 | # s.framework = "SomeFramework" 114 | # s.frameworks = "SomeFramework", "AnotherFramework" 115 | 116 | # s.library = "iconv" 117 | # s.libraries = "iconv", "xml2" 118 | 119 | 120 | # ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 121 | # 122 | # If your library depends on compiler flags you can set them in the xcconfig hash 123 | # where they will only apply to your library. If you depend on other Podspecs 124 | # you can include multiple dependencies to ensure it works. 125 | 126 | # s.requires_arc = true 127 | 128 | # s.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" } 129 | # s.dependency "JSONKit", "~> 1.4" 130 | 131 | end 132 | -------------------------------------------------------------------------------- /BJDraggable/1.2/BJDraggable.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod spec lint BJDraggable.podspec' to ensure this is a 3 | # valid spec and to remove all comments including this before submitting the spec. 4 | # 5 | # To learn more about Podspec attributes see http://docs.cocoapods.org/specification.html 6 | # To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/ 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | 11 | # ――― Spec Metadata ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 12 | # 13 | # These will help people to find your library, and whilst it 14 | # can feel like a chore to fill in it's definitely to your advantage. The 15 | # summary should be tweet-length, and the description more in depth. 16 | # 17 | 18 | s.name = "BJDraggable" 19 | s.version = "1.2" 20 | s.summary = "Enables any UIView to be dragged and dropped within a boundary view." 21 | 22 | s.description = "A simple protocol utilising the powerful UIKitDynamics API, which makes ANY UIView draggable within a boundary view that acts as collision body, with a single method call. Works for any UIView." 23 | 24 | s.homepage = "https://github.com/BadhanGanesh/BJDraggable.git" 25 | # s.screenshots = "https://github.com/BadhanGanesh/BJDraggable/blob/master/Resources/BJDraggable.gif" 26 | 27 | 28 | # ――― Spec License ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 29 | # 30 | # Licensing your code is important. See http://choosealicense.com for more info. 31 | # CocoaPods will detect a license file if there is a named LICENSE* 32 | # Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'. 33 | # 34 | 35 | s.license = { :type => "MIT", :file => "LICENSE" } 36 | 37 | 38 | # ――― Author Metadata ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 39 | # 40 | # Specify the authors of the library, with email addresses. Email addresses 41 | # of the authors are extracted from the SCM log. E.g. $ git log. CocoaPods also 42 | # accepts just a name if you'd rather not provide an email address. 43 | # 44 | # Specify a social_media_url where others can refer to, for example a twitter 45 | # profile URL. 46 | # 47 | 48 | s.author = { "BadhanGanesh" => "ganesh_randy@yahoo.com" } 49 | # Or just: s.author = "BadhanGanesh" 50 | # s.authors = { "BadhanGanesh" => "ganesh_randy@yahoo.com" } 51 | # s.social_media_url = "http://twitter.com/badhanganesh" 52 | 53 | # ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 54 | # 55 | # If this Pod runs only on iOS or OS X, then specify the platform and 56 | # the deployment target. You can optionally include the target after the platform. 57 | # 58 | 59 | s.platform = :ios 60 | s.platform = :ios, "9.0" 61 | s.swift_version = "4.0" 62 | 63 | # When using multiple platforms 64 | s.ios.deployment_target = "9.0" 65 | # s.osx.deployment_target = "10.7" 66 | # s.watchos.deployment_target = "2.0" 67 | # s.tvos.deployment_target = "9.0" 68 | 69 | 70 | # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 71 | # 72 | # Specify the location from where the source should be retrieved. 73 | # Supports git, hg, bzr, svn and HTTP. 74 | # 75 | 76 | s.source = { :git => "https://github.com/BadhanGanesh/BJDraggable.git", :tag => "#{s.version}" } 77 | 78 | 79 | # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 80 | # 81 | # CocoaPods is smart about how it includes source code. For source files 82 | # giving a folder will include any swift, h, m, mm, c & cpp files. 83 | # For header files it will include any header in the folder. 84 | # Not including the public_header_files will make all headers public. 85 | # 86 | 87 | s.source_files = "BJDraggableDemo/Source/*.{swift}" 88 | s.exclude_files = "Classes/Exclude" 89 | 90 | # s.public_header_files = "Classes/**/*.h" 91 | 92 | 93 | # ――― Resources ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 94 | # 95 | # A list of resources included with the Pod. These are copied into the 96 | # target bundle with a build phase script. Anything else will be cleaned. 97 | # You can preserve files from being cleaned, please don't preserve 98 | # non-essential files like tests, examples and documentation. 99 | # 100 | 101 | # s.resource = "icon.png" 102 | s.resources = "Resources/*.gif" 103 | 104 | # s.preserve_paths = "FilesToSave", "MoreFilesToSave" 105 | 106 | 107 | # ――― Project Linking ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 108 | # 109 | # Link your library with frameworks, or libraries. Libraries do not include 110 | # the lib prefix of their name. 111 | # 112 | 113 | # s.framework = "SomeFramework" 114 | # s.frameworks = "SomeFramework", "AnotherFramework" 115 | 116 | # s.library = "iconv" 117 | # s.libraries = "iconv", "xml2" 118 | 119 | 120 | # ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 121 | # 122 | # If your library depends on compiler flags you can set them in the xcconfig hash 123 | # where they will only apply to your library. If you depend on other Podspecs 124 | # you can include multiple dependencies to ensure it works. 125 | 126 | # s.requires_arc = true 127 | 128 | # s.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" } 129 | # s.dependency "JSONKit", "~> 1.4" 130 | 131 | end 132 | -------------------------------------------------------------------------------- /BJDraggableDemo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 53BC1A0820AF6E4A00121C13 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53BC1A0720AF6E4A00121C13 /* AppDelegate.swift */; }; 11 | 53BC1A0A20AF6E4A00121C13 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53BC1A0920AF6E4A00121C13 /* ViewController.swift */; }; 12 | 53BC1A0D20AF6E4A00121C13 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 53BC1A0B20AF6E4A00121C13 /* Main.storyboard */; }; 13 | 53BC1A0F20AF6E4C00121C13 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 53BC1A0E20AF6E4C00121C13 /* Assets.xcassets */; }; 14 | 53BC1A1220AF6E4C00121C13 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 53BC1A1020AF6E4C00121C13 /* LaunchScreen.storyboard */; }; 15 | A6E8892320EB96A70014B5D8 /* BJDraggable.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6E8892220EB96A60014B5D8 /* BJDraggable.swift */; }; 16 | /* End PBXBuildFile section */ 17 | 18 | /* Begin PBXFileReference section */ 19 | 53BC1A0420AF6E4A00121C13 /* BJDraggableDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = BJDraggableDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 20 | 53BC1A0720AF6E4A00121C13 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 21 | 53BC1A0920AF6E4A00121C13 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 22 | 53BC1A0C20AF6E4A00121C13 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 23 | 53BC1A0E20AF6E4C00121C13 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 24 | 53BC1A1120AF6E4C00121C13 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 25 | 53BC1A1320AF6E4C00121C13 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 26 | A6E8892220EB96A60014B5D8 /* BJDraggable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BJDraggable.swift; sourceTree = ""; }; 27 | /* End PBXFileReference section */ 28 | 29 | /* Begin PBXFrameworksBuildPhase section */ 30 | 53BC1A0120AF6E4A00121C13 /* Frameworks */ = { 31 | isa = PBXFrameworksBuildPhase; 32 | buildActionMask = 2147483647; 33 | files = ( 34 | ); 35 | runOnlyForDeploymentPostprocessing = 0; 36 | }; 37 | /* End PBXFrameworksBuildPhase section */ 38 | 39 | /* Begin PBXGroup section */ 40 | 53BC19FB20AF6E4A00121C13 = { 41 | isa = PBXGroup; 42 | children = ( 43 | 53BC1A0620AF6E4A00121C13 /* BJDraggableDemo */, 44 | 53BC1A0520AF6E4A00121C13 /* Products */, 45 | ); 46 | sourceTree = ""; 47 | }; 48 | 53BC1A0520AF6E4A00121C13 /* Products */ = { 49 | isa = PBXGroup; 50 | children = ( 51 | 53BC1A0420AF6E4A00121C13 /* BJDraggableDemo.app */, 52 | ); 53 | name = Products; 54 | sourceTree = ""; 55 | }; 56 | 53BC1A0620AF6E4A00121C13 /* BJDraggableDemo */ = { 57 | isa = PBXGroup; 58 | children = ( 59 | 53BC1A1920AF6E5600121C13 /* Source */, 60 | 53BC1A0720AF6E4A00121C13 /* AppDelegate.swift */, 61 | 53BC1A0920AF6E4A00121C13 /* ViewController.swift */, 62 | 53BC1A0B20AF6E4A00121C13 /* Main.storyboard */, 63 | 53BC1A0E20AF6E4C00121C13 /* Assets.xcassets */, 64 | 53BC1A1020AF6E4C00121C13 /* LaunchScreen.storyboard */, 65 | 53BC1A1320AF6E4C00121C13 /* Info.plist */, 66 | ); 67 | path = BJDraggableDemo; 68 | sourceTree = ""; 69 | }; 70 | 53BC1A1920AF6E5600121C13 /* Source */ = { 71 | isa = PBXGroup; 72 | children = ( 73 | A6E8892220EB96A60014B5D8 /* BJDraggable.swift */, 74 | ); 75 | path = Source; 76 | sourceTree = ""; 77 | }; 78 | /* End PBXGroup section */ 79 | 80 | /* Begin PBXNativeTarget section */ 81 | 53BC1A0320AF6E4A00121C13 /* BJDraggableDemo */ = { 82 | isa = PBXNativeTarget; 83 | buildConfigurationList = 53BC1A1620AF6E4C00121C13 /* Build configuration list for PBXNativeTarget "BJDraggableDemo" */; 84 | buildPhases = ( 85 | 53BC1A0020AF6E4A00121C13 /* Sources */, 86 | 53BC1A0120AF6E4A00121C13 /* Frameworks */, 87 | 53BC1A0220AF6E4A00121C13 /* Resources */, 88 | ); 89 | buildRules = ( 90 | ); 91 | dependencies = ( 92 | ); 93 | name = BJDraggableDemo; 94 | productName = BJDraggableDemo; 95 | productReference = 53BC1A0420AF6E4A00121C13 /* BJDraggableDemo.app */; 96 | productType = "com.apple.product-type.application"; 97 | }; 98 | /* End PBXNativeTarget section */ 99 | 100 | /* Begin PBXProject section */ 101 | 53BC19FC20AF6E4A00121C13 /* Project object */ = { 102 | isa = PBXProject; 103 | attributes = { 104 | LastSwiftUpdateCheck = 0940; 105 | LastUpgradeCheck = 0940; 106 | ORGANIZATIONNAME = "Badhan Ganesh"; 107 | TargetAttributes = { 108 | 53BC1A0320AF6E4A00121C13 = { 109 | CreatedOnToolsVersion = 9.4; 110 | LastSwiftMigration = 1000; 111 | }; 112 | }; 113 | }; 114 | buildConfigurationList = 53BC19FF20AF6E4A00121C13 /* Build configuration list for PBXProject "BJDraggableDemo" */; 115 | compatibilityVersion = "Xcode 9.3"; 116 | developmentRegion = en; 117 | hasScannedForEncodings = 0; 118 | knownRegions = ( 119 | en, 120 | Base, 121 | ); 122 | mainGroup = 53BC19FB20AF6E4A00121C13; 123 | productRefGroup = 53BC1A0520AF6E4A00121C13 /* Products */; 124 | projectDirPath = ""; 125 | projectRoot = ""; 126 | targets = ( 127 | 53BC1A0320AF6E4A00121C13 /* BJDraggableDemo */, 128 | ); 129 | }; 130 | /* End PBXProject section */ 131 | 132 | /* Begin PBXResourcesBuildPhase section */ 133 | 53BC1A0220AF6E4A00121C13 /* Resources */ = { 134 | isa = PBXResourcesBuildPhase; 135 | buildActionMask = 2147483647; 136 | files = ( 137 | 53BC1A1220AF6E4C00121C13 /* LaunchScreen.storyboard in Resources */, 138 | 53BC1A0F20AF6E4C00121C13 /* Assets.xcassets in Resources */, 139 | 53BC1A0D20AF6E4A00121C13 /* Main.storyboard in Resources */, 140 | ); 141 | runOnlyForDeploymentPostprocessing = 0; 142 | }; 143 | /* End PBXResourcesBuildPhase section */ 144 | 145 | /* Begin PBXSourcesBuildPhase section */ 146 | 53BC1A0020AF6E4A00121C13 /* Sources */ = { 147 | isa = PBXSourcesBuildPhase; 148 | buildActionMask = 2147483647; 149 | files = ( 150 | 53BC1A0A20AF6E4A00121C13 /* ViewController.swift in Sources */, 151 | A6E8892320EB96A70014B5D8 /* BJDraggable.swift in Sources */, 152 | 53BC1A0820AF6E4A00121C13 /* AppDelegate.swift in Sources */, 153 | ); 154 | runOnlyForDeploymentPostprocessing = 0; 155 | }; 156 | /* End PBXSourcesBuildPhase section */ 157 | 158 | /* Begin PBXVariantGroup section */ 159 | 53BC1A0B20AF6E4A00121C13 /* Main.storyboard */ = { 160 | isa = PBXVariantGroup; 161 | children = ( 162 | 53BC1A0C20AF6E4A00121C13 /* Base */, 163 | ); 164 | name = Main.storyboard; 165 | sourceTree = ""; 166 | }; 167 | 53BC1A1020AF6E4C00121C13 /* LaunchScreen.storyboard */ = { 168 | isa = PBXVariantGroup; 169 | children = ( 170 | 53BC1A1120AF6E4C00121C13 /* Base */, 171 | ); 172 | name = LaunchScreen.storyboard; 173 | sourceTree = ""; 174 | }; 175 | /* End PBXVariantGroup section */ 176 | 177 | /* Begin XCBuildConfiguration section */ 178 | 53BC1A1420AF6E4C00121C13 /* Debug */ = { 179 | isa = XCBuildConfiguration; 180 | buildSettings = { 181 | ALWAYS_SEARCH_USER_PATHS = NO; 182 | CLANG_ANALYZER_NONNULL = YES; 183 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 184 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 185 | CLANG_CXX_LIBRARY = "libc++"; 186 | CLANG_ENABLE_MODULES = YES; 187 | CLANG_ENABLE_OBJC_ARC = YES; 188 | CLANG_ENABLE_OBJC_WEAK = YES; 189 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 190 | CLANG_WARN_BOOL_CONVERSION = YES; 191 | CLANG_WARN_COMMA = YES; 192 | CLANG_WARN_CONSTANT_CONVERSION = YES; 193 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 194 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 195 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 196 | CLANG_WARN_EMPTY_BODY = YES; 197 | CLANG_WARN_ENUM_CONVERSION = YES; 198 | CLANG_WARN_INFINITE_RECURSION = YES; 199 | CLANG_WARN_INT_CONVERSION = YES; 200 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 201 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 202 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 203 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 204 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 205 | CLANG_WARN_STRICT_PROTOTYPES = YES; 206 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 207 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 208 | CLANG_WARN_UNREACHABLE_CODE = YES; 209 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 210 | CODE_SIGN_IDENTITY = "iPhone Developer"; 211 | COPY_PHASE_STRIP = NO; 212 | DEBUG_INFORMATION_FORMAT = dwarf; 213 | ENABLE_STRICT_OBJC_MSGSEND = YES; 214 | ENABLE_TESTABILITY = YES; 215 | GCC_C_LANGUAGE_STANDARD = gnu11; 216 | GCC_DYNAMIC_NO_PIC = NO; 217 | GCC_NO_COMMON_BLOCKS = YES; 218 | GCC_OPTIMIZATION_LEVEL = 0; 219 | GCC_PREPROCESSOR_DEFINITIONS = ( 220 | "DEBUG=1", 221 | "$(inherited)", 222 | ); 223 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 224 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 225 | GCC_WARN_UNDECLARED_SELECTOR = YES; 226 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 227 | GCC_WARN_UNUSED_FUNCTION = YES; 228 | GCC_WARN_UNUSED_VARIABLE = YES; 229 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 230 | MTL_ENABLE_DEBUG_INFO = YES; 231 | ONLY_ACTIVE_ARCH = YES; 232 | SDKROOT = iphoneos; 233 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 234 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 235 | SWIFT_VERSION = 5.0; 236 | }; 237 | name = Debug; 238 | }; 239 | 53BC1A1520AF6E4C00121C13 /* Release */ = { 240 | isa = XCBuildConfiguration; 241 | buildSettings = { 242 | ALWAYS_SEARCH_USER_PATHS = NO; 243 | CLANG_ANALYZER_NONNULL = YES; 244 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 245 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 246 | CLANG_CXX_LIBRARY = "libc++"; 247 | CLANG_ENABLE_MODULES = YES; 248 | CLANG_ENABLE_OBJC_ARC = YES; 249 | CLANG_ENABLE_OBJC_WEAK = YES; 250 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 251 | CLANG_WARN_BOOL_CONVERSION = YES; 252 | CLANG_WARN_COMMA = YES; 253 | CLANG_WARN_CONSTANT_CONVERSION = YES; 254 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 255 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 256 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 257 | CLANG_WARN_EMPTY_BODY = YES; 258 | CLANG_WARN_ENUM_CONVERSION = YES; 259 | CLANG_WARN_INFINITE_RECURSION = YES; 260 | CLANG_WARN_INT_CONVERSION = YES; 261 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 262 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 263 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 264 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 265 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 266 | CLANG_WARN_STRICT_PROTOTYPES = YES; 267 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 268 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 269 | CLANG_WARN_UNREACHABLE_CODE = YES; 270 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 271 | CODE_SIGN_IDENTITY = "iPhone Developer"; 272 | COPY_PHASE_STRIP = NO; 273 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 274 | ENABLE_NS_ASSERTIONS = NO; 275 | ENABLE_STRICT_OBJC_MSGSEND = YES; 276 | GCC_C_LANGUAGE_STANDARD = gnu11; 277 | GCC_NO_COMMON_BLOCKS = YES; 278 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 279 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 280 | GCC_WARN_UNDECLARED_SELECTOR = YES; 281 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 282 | GCC_WARN_UNUSED_FUNCTION = YES; 283 | GCC_WARN_UNUSED_VARIABLE = YES; 284 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 285 | MTL_ENABLE_DEBUG_INFO = NO; 286 | SDKROOT = iphoneos; 287 | SWIFT_COMPILATION_MODE = wholemodule; 288 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 289 | SWIFT_VERSION = 5.0; 290 | VALIDATE_PRODUCT = YES; 291 | }; 292 | name = Release; 293 | }; 294 | 53BC1A1720AF6E4C00121C13 /* Debug */ = { 295 | isa = XCBuildConfiguration; 296 | buildSettings = { 297 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 298 | CLANG_ENABLE_MODULES = YES; 299 | CODE_SIGN_STYLE = Manual; 300 | DEVELOPMENT_TEAM = ""; 301 | INFOPLIST_FILE = BJDraggableDemo/Info.plist; 302 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 303 | LD_RUNPATH_SEARCH_PATHS = ( 304 | "$(inherited)", 305 | "@executable_path/Frameworks", 306 | ); 307 | PRODUCT_BUNDLE_IDENTIFIER = com.bj.BJDraggableDemo; 308 | PRODUCT_NAME = "$(TARGET_NAME)"; 309 | PROVISIONING_PROFILE_SPECIFIER = ""; 310 | SWIFT_OBJC_BRIDGING_HEADER = ""; 311 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 312 | SWIFT_VERSION = 5.0; 313 | TARGETED_DEVICE_FAMILY = 1; 314 | }; 315 | name = Debug; 316 | }; 317 | 53BC1A1820AF6E4C00121C13 /* Release */ = { 318 | isa = XCBuildConfiguration; 319 | buildSettings = { 320 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 321 | CLANG_ENABLE_MODULES = YES; 322 | CODE_SIGN_STYLE = Manual; 323 | DEVELOPMENT_TEAM = ""; 324 | INFOPLIST_FILE = BJDraggableDemo/Info.plist; 325 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 326 | LD_RUNPATH_SEARCH_PATHS = ( 327 | "$(inherited)", 328 | "@executable_path/Frameworks", 329 | ); 330 | PRODUCT_BUNDLE_IDENTIFIER = com.bj.BJDraggableDemo; 331 | PRODUCT_NAME = "$(TARGET_NAME)"; 332 | PROVISIONING_PROFILE_SPECIFIER = ""; 333 | SWIFT_OBJC_BRIDGING_HEADER = ""; 334 | SWIFT_VERSION = 5.0; 335 | TARGETED_DEVICE_FAMILY = 1; 336 | }; 337 | name = Release; 338 | }; 339 | /* End XCBuildConfiguration section */ 340 | 341 | /* Begin XCConfigurationList section */ 342 | 53BC19FF20AF6E4A00121C13 /* Build configuration list for PBXProject "BJDraggableDemo" */ = { 343 | isa = XCConfigurationList; 344 | buildConfigurations = ( 345 | 53BC1A1420AF6E4C00121C13 /* Debug */, 346 | 53BC1A1520AF6E4C00121C13 /* Release */, 347 | ); 348 | defaultConfigurationIsVisible = 0; 349 | defaultConfigurationName = Release; 350 | }; 351 | 53BC1A1620AF6E4C00121C13 /* Build configuration list for PBXNativeTarget "BJDraggableDemo" */ = { 352 | isa = XCConfigurationList; 353 | buildConfigurations = ( 354 | 53BC1A1720AF6E4C00121C13 /* Debug */, 355 | 53BC1A1820AF6E4C00121C13 /* Release */, 356 | ); 357 | defaultConfigurationIsVisible = 0; 358 | defaultConfigurationName = Release; 359 | }; 360 | /* End XCConfigurationList section */ 361 | }; 362 | rootObject = 53BC19FC20AF6E4A00121C13 /* Project object */; 363 | } 364 | -------------------------------------------------------------------------------- /BJDraggableDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /BJDraggableDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /BJDraggableDemo/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // BJDraggableDemo 4 | // 5 | // Created by BadhanGanesh on 19/05/18. 6 | // Copyright © 2018 Badhan Ganesh. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { return true } 17 | 18 | } 19 | 20 | -------------------------------------------------------------------------------- /BJDraggableDemo/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /BJDraggableDemo/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /BJDraggableDemo/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 | -------------------------------------------------------------------------------- /BJDraggableDemo/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 | 41 | 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 | 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 | 145 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 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 | -------------------------------------------------------------------------------- /BJDraggableDemo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.3 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /BJDraggableDemo/Source/BJDraggable.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BJDraggable 3 | // Created by Badhan Ganesh on 28-05-2018 4 | // 5 | 6 | // This code is distributed under the terms and conditions of the MIT license. 7 | 8 | // Copyright © 2018 Badhan Ganesh 9 | // 10 | // Permission is hereby granted, free of charge, to any person obtaining a copy 11 | // of this software and associated documentation files (the "Software"), to deal 12 | // in the Software without restriction, including without limitation the rights 13 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | // copies of the Software, and to permit persons to whom the Software is 15 | // furnished to do so, subject to the following conditions: 16 | // 17 | // The above copyright notice and this permission notice shall be included in 18 | // all copies or substantial portions of the Software. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE 23 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | // THE SOFTWARE. 27 | 28 | import UIKit 29 | 30 | fileprivate var kReferenceViewKey: UInt8 = 0 31 | fileprivate var kDynamicAnimatorKey: UInt8 = 0 32 | fileprivate var kAttachmentBehaviourKey: UInt8 = 0 33 | fileprivate var kPanGestureKey: UInt8 = 0 34 | fileprivate var kResetPositionKey: UInt8 = 0 35 | fileprivate var kDebugModeEnabledKey: UInt8 = 0 36 | 37 | fileprivate enum BehaviourName { 38 | case main 39 | case border 40 | case collision 41 | case attachment 42 | } 43 | 44 | fileprivate enum UniqueBorderViewTag:Int { 45 | case left = 223420 46 | case right = 223421 47 | case top = 223422 48 | case bottom = 223423 49 | } 50 | 51 | /**A simple protocol *(No need to implement methods and properties yourself. Just drop-in the BJDraggable file to your project and all done)* utilizing the powerful `UIKitDynamics` API, which makes **ANY** `UIView` draggable within a boundary view that acts as collision body, with a single method call. 52 | */ 53 | @objc protocol BJDraggable: class { 54 | 55 | /** 56 | Gives you the power to drag your `UIView` anywhere within a specified view, and collide within its bounds. 57 | - parameter referenceView: The boundary view which acts as a wall, and your view will collide with it and would never fall out of bounds hopefully. **Note that the reference view should contain the view that you're trying to add draggability to in its view hierarchy. The app would crash otherwise.** 58 | */ 59 | @objc func addDraggability(withinView referenceView: UIView) 60 | 61 | /** 62 | This single method call will give you the power to drag your `UIView` anywhere within a specified view, and collide within its bounds. 63 | - parameter referenceView: This is the boundary view which acts as a wall, and your view will collide with it and would never fall out of bounds hopefully. **Note that the reference view should contain the view that you're trying to add draggability to in its view hierarchy. The app would crash otherwise.** 64 | - parameter insets: If you want to make the boundary to be offset positively or negatively, you can specify that here. This is nothing but a margin for the boundary. 65 | */ 66 | @objc func addDraggability(withinView referenceView: UIView, withMargin insets:UIEdgeInsets) 67 | 68 | /** 69 | Removes the power from you, to drag the view in question 70 | */ 71 | @objc func removeDraggability() 72 | 73 | } 74 | 75 | extension UIView: BJDraggable { 76 | 77 | // 78 | ////////////////////////////////////////////////////////////////////////////////////////// 79 | //MARK:- 80 | //MARK: Properties 81 | //MARK:- 82 | ////////////////////////////////////////////////////////////////////////////////////////// 83 | // 84 | 85 | /** 86 | * This will highlight the boundary views in red color for having an idea with which area you are dragging your view(s) in. 87 | */ 88 | public var isDraggableDebugModeEnabled: Bool { 89 | get { 90 | return objc_getAssociatedObject(self, &kDebugModeEnabledKey) as? Bool ?? false 91 | } 92 | set { 93 | objc_setAssociatedObject(self, &kDebugModeEnabledKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) 94 | self.highlightBoundaryViews(newValue) 95 | } 96 | } 97 | 98 | public var shouldResetViewPositionAfterRemovingDraggability: Bool { 99 | get { 100 | return objc_getAssociatedObject(self, &kResetPositionKey) as? Bool ?? false 101 | } 102 | set { 103 | objc_setAssociatedObject(self, &kResetPositionKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) 104 | self.translatesAutoresizingMaskIntoConstraints = !newValue 105 | } 106 | } 107 | 108 | fileprivate var referenceView: UIView? { 109 | get { 110 | return objc_getAssociatedObject(self, &kReferenceViewKey) as? UIView 111 | } 112 | set { 113 | objc_setAssociatedObject(self, &kReferenceViewKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) 114 | } 115 | } 116 | 117 | fileprivate var animator: UIDynamicAnimator? { 118 | get { 119 | return objc_getAssociatedObject(self, &kDynamicAnimatorKey) as? UIDynamicAnimator 120 | } 121 | set { 122 | objc_setAssociatedObject(self, &kDynamicAnimatorKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) 123 | } 124 | } 125 | 126 | fileprivate var attachmentBehaviour: UIAttachmentBehavior? { 127 | get { 128 | return objc_getAssociatedObject(self, &kAttachmentBehaviourKey) as? UIAttachmentBehavior 129 | } 130 | set { 131 | objc_setAssociatedObject(self, &kAttachmentBehaviourKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) 132 | } 133 | } 134 | 135 | fileprivate var panGestureRecognizer: UIPanGestureRecognizer? { 136 | get { 137 | return objc_getAssociatedObject(self, &kPanGestureKey) as? UIPanGestureRecognizer 138 | } 139 | set { 140 | objc_setAssociatedObject(self, &kPanGestureKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) 141 | } 142 | } 143 | 144 | // 145 | ////////////////////////////////////////////////////////////////////////////////////////// 146 | //MARK:- 147 | //MARK: Method Implementations 148 | //MARK:- 149 | ////////////////////////////////////////////////////////////////////////////////////////// 150 | // 151 | 152 | public final func addDraggability(withinView referenceView: UIView) { 153 | self.addDraggability(withinView: referenceView, withMargin: UIEdgeInsets.init(top: 0, left: 0, bottom: 0, right: 0)) 154 | } 155 | 156 | public final func addDraggability(withinView referenceView: UIView, withMargin insets:UIEdgeInsets) { 157 | 158 | guard self.animator == nil else { return } 159 | 160 | /////////////////////// 161 | /////Configuration///// 162 | /////////////////////// 163 | 164 | performInitialConfiguration() 165 | addPanGestureRecognizer() 166 | 167 | //////////////////////////////////////////// 168 | /////Get Collision Items For Behaviours///// 169 | //////////////////////////////////////////// 170 | 171 | let collisionItems = self.drawAndGetCollisionViewsAround(referenceView, withInsets: insets) 172 | 173 | //////////////////////// 174 | /////Get Behaviours///// 175 | //////////////////////// 176 | 177 | let mainItemBehaviour = get(behaviour: .main, for: referenceView, withInsets: insets, configuredWith: collisionItems)! 178 | let borderItemsBehaviour = get(behaviour: .border, for: referenceView, withInsets: insets, configuredWith: collisionItems)! 179 | let collisionBehaviour = get(behaviour: .collision, for: referenceView, withInsets: insets, configuredWith: collisionItems)! 180 | let attachmentBehaviour = get(behaviour: .attachment, for: referenceView, withInsets: insets, configuredWith: collisionItems)! 181 | 182 | //////////////////////////////////// 183 | /////Add Behaviours to Animator///// 184 | //////////////////////////////////// 185 | 186 | let animator = UIDynamicAnimator.init(referenceView: referenceView) 187 | animator.addBehavior(mainItemBehaviour) 188 | animator.addBehavior(borderItemsBehaviour) 189 | animator.addBehavior(collisionBehaviour) 190 | animator.addBehavior(attachmentBehaviour) 191 | 192 | ///////////////////// 193 | /////Persistence///// 194 | ///////////////////// 195 | 196 | self.animator = animator 197 | self.referenceView = referenceView 198 | self.attachmentBehaviour = attachmentBehaviour as? UIAttachmentBehavior 199 | 200 | } 201 | 202 | public final func removeDraggability() { 203 | 204 | if let recognizer = self.panGestureRecognizer { self.removeGestureRecognizer(recognizer) } 205 | self.translatesAutoresizingMaskIntoConstraints = !self.shouldResetViewPositionAfterRemovingDraggability 206 | self.animator?.removeAllBehaviors() 207 | 208 | if let subviews = self.referenceView?.subviews { 209 | for view in subviews { 210 | if view.isKind(of: BoundaryCollisionView.self) { 211 | view.removeFromSuperview() 212 | } 213 | } 214 | } 215 | 216 | self.referenceView = nil 217 | self.attachmentBehaviour = nil 218 | self.animator = nil 219 | self.panGestureRecognizer = nil 220 | } 221 | 222 | // 223 | ////////////////////////////////////////////////////////////////////////////////////////// 224 | //MARK:- 225 | //MARK: Helpers 1 226 | //MARK:- 227 | ////////////////////////////////////////////////////////////////////////////////////////// 228 | // 229 | 230 | fileprivate func performInitialConfiguration() { 231 | self.isUserInteractionEnabled = true 232 | } 233 | 234 | fileprivate func addPanGestureRecognizer() { 235 | let panGestureRecognizer = UIPanGestureRecognizer.init(target: self, action: #selector(self.panGestureHandler(_:))) 236 | self.addGestureRecognizer(panGestureRecognizer) 237 | self.panGestureRecognizer = panGestureRecognizer 238 | } 239 | 240 | @objc final func panGestureHandler(_ gesture: UIPanGestureRecognizer) { 241 | guard let referenceView = self.referenceView else { return } 242 | let touchPoint = gesture.location(in: referenceView) 243 | self.attachmentBehaviour?.anchorPoint = touchPoint 244 | } 245 | 246 | fileprivate func get(behaviour:BehaviourName, for referenceView:UIView, withInsets insets:UIEdgeInsets, configuredWith boundaryCollisionItems:[UIDynamicItem]) -> UIDynamicBehavior? { 247 | 248 | let allItems = [self] + boundaryCollisionItems 249 | 250 | switch behaviour { 251 | case .border: 252 | let borderItemsBehaviour = UIDynamicItemBehavior.init(items: boundaryCollisionItems) 253 | borderItemsBehaviour.allowsRotation = false 254 | borderItemsBehaviour.isAnchored = true 255 | borderItemsBehaviour.elasticity = 100 256 | return borderItemsBehaviour 257 | case .main: 258 | let mainItemBehaviour = UIDynamicItemBehavior.init(items: [self]) 259 | mainItemBehaviour.allowsRotation = false 260 | mainItemBehaviour.isAnchored = false 261 | mainItemBehaviour.elasticity = 100 262 | return mainItemBehaviour 263 | case .collision: 264 | let collisionBehaviour = UICollisionBehavior.init(items: allItems) 265 | collisionBehaviour.collisionMode = .items 266 | collisionBehaviour.setTranslatesReferenceBoundsIntoBoundary(with: insets) 267 | return collisionBehaviour 268 | case .attachment: 269 | let attachmentBehaviour = UIAttachmentBehavior.init(item: self, attachedToAnchor: self.center) 270 | return attachmentBehaviour 271 | } 272 | } 273 | 274 | // 275 | ////////////////////////////////////////////////////////////////////////////////////////// 276 | //MARK:- 277 | //MARK: Helpers 2 278 | //MARK:- 279 | ////////////////////////////////////////////////////////////////////////////////////////// 280 | // 281 | 282 | func alteredFrameByPoints(_ point:CGFloat) -> CGRect { 283 | return self.frame.insetBy(dx: -point, dy: -point) 284 | } 285 | 286 | fileprivate func boundaryPathFor(_ view:UIView, withInsets insets:UIEdgeInsets) -> UIBezierPath { 287 | 288 | let frameWithInsets = view.frame.inset(by: insets) 289 | var rect = frameWithInsets.insetBy(dx: -3, dy: -3) 290 | 291 | rect.origin.x = -3.0 - insets.left 292 | rect.origin.y = -3.0 - insets.top 293 | rect.size.width = -3.0 - insets.right 294 | rect.size.height = -3.0 - insets.bottom 295 | 296 | let path = UIBezierPath.init(rect: rect) 297 | return path 298 | } 299 | 300 | fileprivate func highlightBoundaryViews(_ yes:Bool) { 301 | guard let referenceView = self.referenceView else { return } 302 | referenceView.viewWithTag(UniqueBorderViewTag.left.rawValue)?.backgroundColor = yes ? .red : .clear 303 | referenceView.viewWithTag(UniqueBorderViewTag.right.rawValue)?.backgroundColor = yes ? .red : .clear 304 | referenceView.viewWithTag(UniqueBorderViewTag.top.rawValue)?.backgroundColor = yes ? .red : .clear 305 | referenceView.viewWithTag(UniqueBorderViewTag.bottom.rawValue)?.backgroundColor = yes ? .red : .clear 306 | } 307 | 308 | @discardableResult fileprivate func drawAndGetCollisionViewsAround(_ referenceView:UIView, withInsets insets:UIEdgeInsets) -> ([UIView]) { 309 | 310 | let boundaryViewWidth = CGFloat(1) 311 | let boundaryViewHeight = CGFloat(1) 312 | 313 | ////////////////////// 314 | /////Get New Rect///// 315 | ////////////////////// 316 | 317 | let newReferenceViewRect = referenceView.alteredFrameByPoints(1).inset(by: insets) 318 | 319 | ///////////////////////////// 320 | /////Fabricate Left View///// 321 | ///////////////////////////// 322 | 323 | let leftView = BoundaryCollisionView(frame: CGRect.init(x: -0.0 + insets.left, y: -0.0 + insets.top, width: boundaryViewWidth, height: newReferenceViewRect.size.height)) 324 | leftView.isUserInteractionEnabled = false 325 | leftView.tag = UniqueBorderViewTag.left.rawValue 326 | leftView.backgroundColor = isDraggableDebugModeEnabled ? .red : .clear 327 | 328 | ////////////////////////////// 329 | /////Fabricate Right View///// 330 | ////////////////////////////// 331 | 332 | let rightView = BoundaryCollisionView(frame: CGRect.init(x: newReferenceViewRect.size.width + insets.left - 3.0, y:-0.0 + insets.top, width: boundaryViewWidth, height: newReferenceViewRect.size.height)) 333 | rightView.isUserInteractionEnabled = false 334 | rightView.tag = UniqueBorderViewTag.right.rawValue 335 | rightView.backgroundColor = isDraggableDebugModeEnabled ? .red : .clear 336 | 337 | //////////////////////////// 338 | /////Fabricate Top View///// 339 | //////////////////////////// 340 | 341 | let topView = BoundaryCollisionView(frame: CGRect.init(x: -0.0 + insets.left, y: -0.0 + insets.top, width:newReferenceViewRect.size.width - 1.0, height: boundaryViewHeight)) 342 | topView.isUserInteractionEnabled = false 343 | topView.tag = UniqueBorderViewTag.top.rawValue 344 | topView.backgroundColor = isDraggableDebugModeEnabled ? .red : .clear 345 | 346 | /////////////////////////////// 347 | /////Fabricate Bottom View///// 348 | /////////////////////////////// 349 | 350 | let bottomView = BoundaryCollisionView(frame: CGRect.init(x: -0.0 + insets.left, y: insets.top + newReferenceViewRect.size.height - 3.0, width: newReferenceViewRect.size.width - 1.0, height: boundaryViewHeight)) 351 | bottomView.isUserInteractionEnabled = false 352 | bottomView.tag = UniqueBorderViewTag.bottom.rawValue 353 | bottomView.backgroundColor = isDraggableDebugModeEnabled ? .red : .clear 354 | 355 | ///////////////////// 356 | /////Add Subview///// 357 | ///////////////////// 358 | 359 | referenceView.addSubview(leftView) 360 | referenceView.addSubview(rightView) 361 | referenceView.addSubview(topView) 362 | referenceView.addSubview(bottomView) 363 | 364 | return [leftView, rightView, topView, bottomView] 365 | } 366 | 367 | } 368 | 369 | /** 370 | This is a special view for unique identification that gets invisibly added as a subview to the reference view for creating boundary around it. 371 | */ 372 | class BoundaryCollisionView: UIView { } 373 | -------------------------------------------------------------------------------- /BJDraggableDemo/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // BJDraggableDemo 4 | // 5 | // Created by BadhanGanesh on 19/05/18. 6 | // Copyright © 2018 Badhan Ganesh. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ViewController: UIViewController { 12 | 13 | @IBOutlet weak var loginView: UIView! 14 | @IBOutlet weak var omegaView: UIView! 15 | @IBOutlet weak var omegaContainerView: UIView! 16 | @IBOutlet weak var signupButton: UIButton! 17 | 18 | fileprivate func configureDraggabilities() { 19 | self.omegaView.shouldResetViewPositionAfterRemovingDraggability = true 20 | self.loginView.shouldResetViewPositionAfterRemovingDraggability = true 21 | self.omegaContainerView.shouldResetViewPositionAfterRemovingDraggability = true 22 | self.signupButton.shouldResetViewPositionAfterRemovingDraggability = true 23 | } 24 | 25 | override func viewDidLoad() { 26 | super.viewDidLoad() 27 | configureDraggabilities() 28 | } 29 | 30 | @IBAction func addDraggabilityButtonTouched(_ sender: UIButton) { 31 | self.loginView.addDraggability(withinView: self.view) 32 | self.omegaView.addDraggability(withinView: self.omegaContainerView) 33 | self.omegaContainerView.addDraggability(withinView: self.view) 34 | self.signupButton.addDraggability(withinView: self.view) 35 | } 36 | 37 | @IBAction func removeDraggabilityButtonTouched(_ sender: UIButton) { 38 | self.loginView.removeDraggability() 39 | self.omegaView.removeDraggability() 40 | self.omegaContainerView.removeDraggability() 41 | self.signupButton.removeDraggability() 42 | } 43 | 44 | override func touchesBegan(_ touches: Set, with event: UIEvent?) { 45 | self.view.endEditing(true) 46 | } 47 | 48 | } 49 | 50 | extension UIView { 51 | @IBInspectable var cornerRadius: CGFloat { 52 | get { 53 | return layer.cornerRadius 54 | } 55 | set { 56 | layer.cornerRadius = newValue 57 | layer.masksToBounds = newValue > 0 58 | } 59 | } 60 | } 61 | 62 | extension UITextField { 63 | open override func awakeFromNib() { 64 | self.layer.sublayerTransform = CATransform3DMakeTranslation(5, 0, 0) 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Badhan Ganesh 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 NON-INFRINGEMENT. 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 SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BJDraggable 2 | A simple protocol *(No need to subclass, no need to implement methods and properties yourself. Just drop the BJDraggable file into your project)* utilizing the powerful `UIKitDynamics` API, which makes **ANY** `UIView` draggable within a boundary view that acts as collision body, with a single method call. 3 | 4 | BJDraggable Demo 5 | 6 | ## Installation 7 | 8 | Use `pod 'BJDraggable'` 9 | 10 | **OR** 11 | 12 | Drag and Drop the **BJDraggable.swift** file (Located inside the Source folder in repo.) into your Xcode project. 13 | 14 | ## Usage 15 | 16 | - Just call the `addDraggability` method on your view and pass in a boundary view and that's it: 17 | 18 | ```swift 19 | override func viewDidLoad() { 20 | super.viewDidLoad() 21 | self.loginView.addDraggability(withinView: self.view) 22 | self.omegaView.addDraggability(withinView: self.omegaContainerView) 23 | self.omegaContainerView.addDraggability(withinView: self.view) 24 | self.signupButton.addDraggability(withinView: self.view) 25 | } 26 | ``` 27 | 28 | - You can also add margin to your boundary view by passing in a `UIEdgeInsets` parameter: 29 | 30 | ```swift 31 | self.loginView.addDraggability(withinView: self.view, withMargin: UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)) 32 | ``` 33 | 34 | 35 | - To stop the dragging ability, simply call `removeDraggability` method: 36 | 37 | ```swift 38 | @IBAction func removeDraggabilityButtonTouched(_ sender: UIButton) { 39 | self.loginView.removeDraggability() 40 | self.omegaView.removeDraggability() 41 | self.omegaContainerView.removeDraggability() 42 | self.signupButton.removeDraggability() 43 | } 44 | ``` 45 | **Note:** Call `removeDraggability()` in the `deinit` of your `UIViewController` or `UIView` if your think you're done with it. This does the cleanup of memory and other variables used. 46 | 47 | ## Optional Usage 48 | 49 | - If you want the view to move to its original position (respecting its autolayout constraints) after removing draggability like in the example GIF above, set the `shouldResetViewPositionAfterRemovingDraggability` property to `true`. Default value is `false`. 50 | 51 | 52 | - To visually highlight the boundary lines within which the drag will happen, you can make `isDraggableDebugModeEnabled` property to `true`. The effective boundary (with margins applied) will be highlighted in red color. Specifying your own color will be added in the next or subsequent commits. 53 | 54 | ## Limitations 55 | - Currently, due to the nature of the implementation, the draggability will not work well with rounded-corner views, since invisible walls are drawn around the superview separately in the manner like `left`, `right`, `top`, `bottom` to simulate boundary. 56 | - This could be overcome by eliminating the use of imaginary special views and instead, using real boundaries with paths. BUT this method comes with one little caveat that, the view that you're dragging will not slide against the walls, they just stick to it. 57 | 58 | ## License 59 | 60 | This code is distributed under the terms and conditions of the [MIT license](LICENSE). 61 | -------------------------------------------------------------------------------- /Resources/BJDraggable.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BadhanGanesh/BJDraggable/79a1c8911c83e618037e7d589942ec727cd9f97d/Resources/BJDraggable.gif --------------------------------------------------------------------------------