├── CHANGELOG.md
├── Examples
├── AtkDragAndDrop_Examples
│ ├── en.lproj
│ │ └── InfoPlist.strings
│ ├── AtkSampleViewController.h
│ ├── Sample01
│ │ ├── AtkSampleOneViewController.h
│ │ ├── AtkSampleOneDropZoneView.h
│ │ ├── AtkSampleOneDragSourceView.h
│ │ ├── AtkSampleOneDropZoneScrollView.h
│ │ ├── AtkSampleOneDragSourceView.m
│ │ ├── AtkSampleOneViewController.m
│ │ ├── AtkSampleOneDropZoneScrollView.m
│ │ ├── AtkSampleOneDropZoneView.m
│ │ └── AtkSampleOneViewController.xib
│ ├── Sample02
│ │ ├── AtkSampleTwoViewController.h
│ │ ├── AtkSampleTwoDropZoneWrapper.h
│ │ ├── AtkSampleTwoDragSourceWrapper.h
│ │ ├── AtkSampleTwoDropZoneScrollViewWrapper.h
│ │ ├── AtkSampleTwoDragSourceWrapper.m
│ │ ├── AtkSampleTwoDropZoneScrollViewWrapper.m
│ │ ├── AtkSampleTwoDropZoneWrapper.m
│ │ ├── AtkSampleTwoViewController.m
│ │ └── AtkSampleTwoViewController.xib
│ ├── AtkAppDelegate.h
│ ├── AtkDragAndDrop_Examples-Prefix.pch
│ ├── main.m
│ ├── Images.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── LaunchImage.launchimage
│ │ │ └── Contents.json
│ ├── AtkDragAndDrop_Examples-Info.plist
│ ├── AtkSampleViewController.m
│ ├── AtkAppDelegate.m
│ └── AtkSampleViewController.xib
└── AtkDragAndDrop_Examples.xcodeproj
│ ├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── AtkDragAndDrop_Examples.xccheckout
│ └── project.pbxproj
├── .gitignore
├── Classes
├── UIView+AtkImage.h
├── AtkDragAndDrop.h
├── AtkDefaultDragAndDropManagerDelegate.h
├── AtkDropZoneWrapper.h
├── AtkDropZoneWrapper.m
├── UIView+AtkDragAndDrop.h
├── UIView+AtkImage.m
├── AtkDragSourceProtocol.h
├── UIScrollView+AtkDragAndDrop.h
├── UIView+AtkDragAndDrop.m
├── AtkDragAndDropLifecycleProtocol.h
├── AtkDropZoneProtocol.h
├── AtkDefaultDragAndDropManagerDelegate.m
├── AtkDragAndDropManager.h
├── UIScrollView+AtkDragAndDrop.m
└── AtkDragAndDropManager.m
├── LICENSE
├── AtkDragAndDrop.podspec
├── Rakefile
└── README.md
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # AtkDragAndDrop CHANGELOG
2 |
3 | ## 0.1.0
4 |
5 | Initial release.
6 |
--------------------------------------------------------------------------------
/Examples/AtkDragAndDrop_Examples/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/Examples/AtkDragAndDrop_Examples.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | .DS_Store
3 | */build/*
4 | *.pbxuser
5 | !default.pbxuser
6 | *.mode1v3
7 | !default.mode1v3
8 | *.mode2v3
9 | !default.mode2v3
10 | *.perspectivev3
11 | !default.perspectivev3
12 | xcuserdata
13 | profile
14 | *.moved-aside
15 | DerivedData
16 | .idea/
17 | *.hmap
18 |
19 | #CocoaPods
20 | Pods
21 |
--------------------------------------------------------------------------------
/Examples/AtkDragAndDrop_Examples/AtkSampleViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // AtkSampleViewController.h
3 | // Atkdrogen_DragAndDrop
4 | //
5 | // Created by Rick Boykin on 1/20/14.
6 | // Copyright (c) 2014 Asymptotik Limited. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AtkSampleViewController : UIViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/Examples/AtkDragAndDrop_Examples/Sample01/AtkSampleOneViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // AtkSampleOneViewController.h
3 | // AtkDragAndDrop
4 | //
5 | // Created by Rick Boykin on 1/15/14.
6 | // Copyright (c) 2014 Asymptotik Limited. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AtkSampleOneViewController : UIViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/Examples/AtkDragAndDrop_Examples/Sample02/AtkSampleTwoViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // AtkSampleTwoViewController.h
3 | // AtkDragAndDrop
4 | //
5 | // Created by Rick Boykin on 1/15/14.
6 | // Copyright (c) 2014 Asymptotik Limited. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AtkSampleTwoViewController : UIViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/Classes/UIView+AtkImage.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIView+Image.h
3 | // AtkDragAndDrop
4 | //
5 | // Created by Rick Boykin on 1/17/14.
6 | // Copyright (c) 2014 Asymptotik Limited. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface UIView (Image)
12 |
13 | /**
14 | * Creates and autoreleased image from self.
15 | */
16 | - (UIImage*)imageFromView;
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/Classes/AtkDragAndDrop.h:
--------------------------------------------------------------------------------
1 | //
2 | // AtkDragAndDrop.h
3 | // AtkDragAndDrop
4 | //
5 | // Created by Rick Boykin on 1/17/14.
6 | // Copyright (c) 2014 Asymptotik Limited. All rights reserved.
7 | //
8 |
9 | #import "AtkDragAndDropManager.h"
10 | #import "AtkDragSourceProtocol.h"
11 | #import "AtkDropZoneProtocol.h"
12 | #import "UIView+AtkDragAndDrop.h"
13 | #import "UIScrollView+AtkDragAndDrop.h"
--------------------------------------------------------------------------------
/Examples/AtkDragAndDrop_Examples/AtkAppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AtkAppDelegate.h
3 | // AtkDragAndDrop
4 | //
5 | // Created by Rick Boykin on 1/15/14.
6 | // Copyright (c) 2014 Rick Boykin. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AtkAppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/Examples/AtkDragAndDrop_Examples/Sample01/AtkSampleOneDropZoneView.h:
--------------------------------------------------------------------------------
1 | //
2 | // AtkDropZoneView.h
3 | // AtkDragAndDrop
4 | //
5 | // Created by Rick Boykin on 1/17/14.
6 | // Copyright (c) 2014 Asymptotik Limited. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AtkDragAndDrop.h"
11 |
12 | @interface AtkSampleOneDropZoneView : UIView
13 |
14 | @end
15 |
--------------------------------------------------------------------------------
/Examples/AtkDragAndDrop_Examples/Sample01/AtkSampleOneDragSourceView.h:
--------------------------------------------------------------------------------
1 | //
2 | // AtkSampleOneDragSourceView.h
3 | // AtkDragAndDrop
4 | //
5 | // Created by Rick Boykin on 1/17/14.
6 | // Copyright (c) 2014 Asymptotik Limited. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AtkDragAndDrop.h"
11 |
12 | @interface AtkSampleOneDragSourceView : UIView
13 |
14 | @end
15 |
--------------------------------------------------------------------------------
/Examples/AtkDragAndDrop_Examples/Sample01/AtkSampleOneDropZoneScrollView.h:
--------------------------------------------------------------------------------
1 | //
2 | // AtkSampleOneDropZoneScrollView.h
3 | // AtkDragAndDrop
4 | //
5 | // Created by Rick Boykin on 1/17/14.
6 | // Copyright (c) 2014 Asymptotik Limited. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AtkDragAndDrop.h"
11 |
12 | @interface AtkSampleOneDropZoneScrollView : UIScrollView
13 |
14 | @end
15 |
--------------------------------------------------------------------------------
/Classes/AtkDefaultDragAndDropManagerDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AtkDefaultDragAndDropManagerDelegate.h
3 | // Atkdrogen_DragAndDrop
4 | //
5 | // Created by Rick Boykin on 1/20/14.
6 | // Copyright (c) 2014 Asymptotik Limited. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AtkDragAndDropManager.h"
11 |
12 | @interface AtkDefaultDragAndDropManagerDelegate : NSObject
13 |
14 | @end
15 |
--------------------------------------------------------------------------------
/Examples/AtkDragAndDrop_Examples/AtkDragAndDrop_Examples-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header
3 | //
4 | // The contents of this file are implicitly included at the beginning of every source file.
5 | //
6 |
7 | #import
8 |
9 | #ifndef __IPHONE_3_0
10 | #warning "This project uses features only available in iOS SDK 3.0 and later."
11 | #endif
12 |
13 | #ifdef __OBJC__
14 | #import
15 | #import
16 | #endif
17 |
--------------------------------------------------------------------------------
/Examples/AtkDragAndDrop_Examples/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // AtkDragAndDrop_Examples
4 | //
5 | // Created by Rick Boykin on 1/28/14.
6 | // Copyright (c) 2014 Asymptotik Limited. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #import "AtkAppDelegate.h"
12 |
13 | int main(int argc, char * argv[])
14 | {
15 | @autoreleasepool {
16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AtkAppDelegate class]));
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/Examples/AtkDragAndDrop_Examples/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "40x40",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "60x60",
16 | "scale" : "2x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/Examples/AtkDragAndDrop_Examples/Sample02/AtkSampleTwoDropZoneWrapper.h:
--------------------------------------------------------------------------------
1 | //
2 | // AtkSampleTwoDropZoneWrapper.h
3 | // Atkdrogen_DragAndDrop
4 | //
5 | // Created by Rick Boykin on 1/21/14.
6 | // Copyright (c) 2014 Asymptotik Limited. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AtkDragAndDrop.h"
11 |
12 | @interface AtkSampleTwoDropZoneWrapper : NSObject
13 |
14 | @property (nonatomic, strong) UIView *view;
15 |
16 | - (id)initWithView:(UIView *)view;
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/Examples/AtkDragAndDrop_Examples/Sample02/AtkSampleTwoDragSourceWrapper.h:
--------------------------------------------------------------------------------
1 | //
2 | // AtkSampleTwoDragSourceWrapper.h
3 | // Atkdrogen_DragAndDrop
4 | //
5 | // Created by Rick Boykin on 1/21/14.
6 | // Copyright (c) 2014 Asymptotik Limited. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AtkDragAndDrop.h"
11 |
12 | @interface AtkSampleTwoDragSourceWrapper : NSObject
13 |
14 | @property (nonatomic, strong) UIView *view;
15 |
16 | - (id)initWithView:(UIView *)view;
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/Examples/AtkDragAndDrop_Examples/Sample02/AtkSampleTwoDropZoneScrollViewWrapper.h:
--------------------------------------------------------------------------------
1 | //
2 | // AtkSampleTwoDropZoneScrollViewWrapper.h
3 | // Atkdrogen_DragAndDrop
4 | //
5 | // Created by Rick Boykin on 1/21/14.
6 | // Copyright (c) 2014 Asymptotik Limited. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AtkDragAndDrop.h"
11 |
12 | @interface AtkSampleTwoDropZoneScrollViewWrapper : NSObject
13 |
14 | @property (nonatomic, strong) UIScrollView *view;
15 |
16 | - (id)initWithScrollView:(UIScrollView *)view;
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/Classes/AtkDropZoneWrapper.h:
--------------------------------------------------------------------------------
1 | //
2 | // AtkDropZoneWrapper.h
3 | // AtkDragAndDrop
4 | //
5 | // Created by Rick Boykin on 1/18/14.
6 | // Copyright (c) 2014 Asymptotik Limited. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AtkDropZoneProtocol.h"
11 |
12 | @interface AtkDropZoneWrapper : NSObject
13 |
14 | @property (nonatomic, strong) id dropZone;
15 | @property (nonatomic, assign) BOOL isActive;
16 | @property (nonatomic, assign) BOOL isInterested;
17 |
18 | - (id)initWithDropZone:(id)dropZone interested:(BOOL)interested;
19 |
20 | @end
21 |
--------------------------------------------------------------------------------
/Examples/AtkDragAndDrop_Examples/Images.xcassets/LaunchImage.launchimage/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "orientation" : "portrait",
5 | "idiom" : "iphone",
6 | "extent" : "full-screen",
7 | "minimum-system-version" : "7.0",
8 | "scale" : "2x"
9 | },
10 | {
11 | "orientation" : "portrait",
12 | "idiom" : "iphone",
13 | "subtype" : "retina4",
14 | "extent" : "full-screen",
15 | "minimum-system-version" : "7.0",
16 | "scale" : "2x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/Classes/AtkDropZoneWrapper.m:
--------------------------------------------------------------------------------
1 | //
2 | // AtkDropZoneWrapper.m
3 | // AtkDragAndDrop
4 | //
5 | // Created by Rick Boykin on 1/18/14.
6 | // Copyright (c) 2014 Asymptotik Limited. All rights reserved.
7 | //
8 |
9 | #import "AtkDropZoneWrapper.h"
10 |
11 | @implementation AtkDropZoneWrapper
12 |
13 | - (id)initWithDropZone:(id)dropZone interested:(BOOL)interested;
14 | {
15 | if((self = [super init]))
16 | {
17 | self.dropZone = dropZone;
18 | self.isActive = NO;
19 | self.isInterested = interested;
20 | }
21 |
22 | return self;
23 | }
24 |
25 |
26 | @end
27 |
--------------------------------------------------------------------------------
/Examples/AtkDragAndDrop_Examples/Sample01/AtkSampleOneDragSourceView.m:
--------------------------------------------------------------------------------
1 | //
2 | // AtkSampleOneDragSourceView.m
3 | // AtkDragAndDrop
4 | //
5 | // Created by Rick Boykin on 1/17/14.
6 | // Copyright (c) 2014 Asymptotik Limited. All rights reserved.
7 | //
8 |
9 | #import "AtkSampleOneDragSourceView.h"
10 | #import "AtkDragAndDropManager.h"
11 |
12 | @interface AtkSampleOneDragSourceView()
13 |
14 | @end
15 |
16 | @implementation AtkSampleOneDragSourceView
17 |
18 | - (id)initWithFrame:(CGRect)frame
19 | {
20 | self = [super initWithFrame:frame];
21 | if (self) {
22 | // Initialization code
23 | }
24 | return self;
25 | }
26 |
27 | - (void)dragWillStart:(AtkDragAndDropManager *)manager
28 | {
29 | manager.pasteboard.string = [NSString stringWithFormat:@"val-%ld", (long)self.tag];
30 | }
31 |
32 | @end
33 |
--------------------------------------------------------------------------------
/Classes/UIView+AtkDragAndDrop.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIView+DragAndDrop.h
3 | // AtkDragAndDrop
4 | //
5 | // Created by Rick Boykin on 1/17/14.
6 | // Copyright (c) 2014 Asymptotik Limited. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AtkDragAndDrop.h"
11 |
12 | @interface UIView (AtkDragAndDrop)
13 |
14 | /**
15 | * Creates a UIView based on self that is a UIImageView with an image
16 | * of self to be used as the drag shadow for self.
17 | */
18 | - (UIView *)createDefaultDragShadowView:(AtkDragAndDropManager *)manager;
19 |
20 | /**
21 | * determine if this view can be considered active by the AtkDragAndDropManager based on the location of point
22 | * point is give relative to manager.rootView, not this view.
23 | */
24 | - (BOOL)isActiveDropZone:(AtkDragAndDropManager *)manager point:(CGPoint)point;
25 |
26 | @end
27 |
--------------------------------------------------------------------------------
/Classes/UIView+AtkImage.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIView+Image.m
3 | // AtkDragAndDrop
4 | //
5 | // Created by Rick Boykin on 1/17/14.
6 | // Copyright (c) 2014 Asymptotik Limited. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "UIView+AtkImage.h"
11 |
12 | @implementation UIView (Image)
13 |
14 | - (UIImage*)imageFromView
15 | {
16 | UIGraphicsBeginImageContextWithOptions(self.bounds.size, self.opaque, 0.0);
17 |
18 | if ([self respondsToSelector:@selector(drawViewHierarchyInRect:afterScreenUpdates:)]) {
19 | [self drawViewHierarchyInRect:self.bounds afterScreenUpdates:YES];
20 | } else {
21 | [self.layer renderInContext:UIGraphicsGetCurrentContext()];
22 | }
23 |
24 | UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
25 |
26 | UIGraphicsEndImageContext();
27 |
28 | return img;
29 | }
30 |
31 | @end
32 |
--------------------------------------------------------------------------------
/Classes/AtkDragSourceProtocol.h:
--------------------------------------------------------------------------------
1 | //
2 | // AtkDragSourceProtocol.h
3 | // AtkDragAndDrop
4 | //
5 | // Created by Rick Boykin on 1/17/14.
6 | // Copyright (c) 2014 Asymptotik Limited. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AtkDropZoneProtocol.h"
11 | #import "AtkDragAndDropLifecycleProtocol.h"
12 |
13 | @class AtkDragAndDropManager;
14 |
15 | @protocol AtkDragSourceProtocol
16 |
17 | @optional
18 |
19 | - (UIView *)createDragShadowView:(AtkDragAndDropManager *)manager;
20 |
21 | /**
22 | * Called to determine if dragging should start on this drag source.
23 | */
24 | - (BOOL)shouldDragStart:(AtkDragAndDropManager *)manager point:(CGPoint)point;
25 |
26 | /**
27 | * Called when a drag source has been found, but before searching for drop zones.
28 | */
29 | - (void)dragWillStart:(AtkDragAndDropManager *)manager;
30 |
31 | @end
32 |
--------------------------------------------------------------------------------
/Examples/AtkDragAndDrop_Examples/Sample02/AtkSampleTwoDragSourceWrapper.m:
--------------------------------------------------------------------------------
1 | //
2 | // AtkSampleTwoDragSourceWrapper.m
3 | // Atkdrogen_DragAndDrop
4 | //
5 | // Created by Rick Boykin on 1/21/14.
6 | // Copyright (c) 2014 Asymptotik Limited. All rights reserved.
7 | //
8 |
9 | #import "AtkSampleTwoDragSourceWrapper.h"
10 | #import "UIView+AtkDragAndDrop.h"
11 |
12 | @implementation AtkSampleTwoDragSourceWrapper
13 |
14 | - (id)initWithView:(UIView *)view
15 | {
16 | self = [super init];
17 | if(self)
18 | {
19 | self.view = view;
20 | }
21 | return self;
22 | }
23 |
24 | - (BOOL)shouldDragStart:(AtkDragAndDropManager *)manager point:(CGPoint)point
25 | {
26 | return YES;
27 | }
28 |
29 | - (void)dragWillStart:(AtkDragAndDropManager *)manager
30 | {
31 | manager.pasteboard.string = [NSString stringWithFormat:@"val-%ld", (long)self.view.tag];
32 | }
33 |
34 | - (UIView *)createDragShadowView:(AtkDragAndDropManager *)manager
35 | {
36 | return [self.view createDefaultDragShadowView:manager];
37 | }
38 |
39 | @end
40 |
--------------------------------------------------------------------------------
/Classes/UIScrollView+AtkDragAndDrop.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIScrollView+AtkDragAndDrop.h
3 | // Atkdrogen_DragAndDrop
4 | //
5 | // Created by Rick Boykin on 1/21/14.
6 | // Copyright (c) 2014 Asymptotik Limited. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface UIScrollView (AtkDragAndDrop)
12 |
13 | @property (nonatomic, assign) CGFloat autoScrollEdgeTollerance;
14 | @property (nonatomic, assign) CGFloat autoScrollVelocity;
15 | @property (nonatomic, assign) CGFloat autoScrollMaxVelocity;
16 |
17 | // Notifies the UIScrollView that dragging has started.
18 | - (void)autoScrollDragStarted;
19 |
20 | // allows the UIScrollView to monitor the drag movemment and scroll appropriately
21 | // point should be converted to the UIScrollView coordinates using
22 | // [rootView convertPoint:point toView:uiScrollView] from whatever rootView
23 | // coordinate system point was originally in.
24 | - (void)autoScrollDragMoved:(CGPoint)point;
25 |
26 | // Notifies the UIScrollView that dragging has ended.
27 | - (void)autoScrollDragEnded;
28 |
29 | @end
30 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2014 Rick Boykin
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/AtkDragAndDrop.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = "AtkDragAndDrop"
3 | s.version = "0.2.2"
4 | s.summary = "A drag and drop toolkit for iOS."
5 | s.description = <<-DESC
6 | iOS drag and drop toolkit with support for:
7 |
8 | * Drag Source and Drop Zones by either subclassing or wrapping UIView and subclasses
9 | * Drag shadow generation for UIView
10 | * UIScrollView drag target auto scrolling
11 | * AtkDragAndDropManager uses the delegate pattern to allow a wide varienty of drag and drop scenarios
12 | * Accepts any continuous UIGestureRecognizer class for drag recognition
13 | * Works with the UIPasteboard as a means of data passing for the drag and drop operation.
14 | * Complete set of lifecycle handlers.
15 | DESC
16 | s.homepage = "https://github.com/ptoinson/asymptotik-drag-and-drop"
17 | s.license = 'MIT'
18 | s.author = { "Rick Boykin" => "info@asymptotik.com" }
19 | s.source = { :git => "https://github.com/ptoinson/asymptotik-drag-and-drop.git", :tag => "v#{s.version.to_s}" }
20 | s.platform = :ios, '5.0'
21 | s.requires_arc = true
22 | s.source_files = 'Classes'
23 | s.frameworks = 'UIKit'
24 | end
25 |
--------------------------------------------------------------------------------
/Classes/UIView+AtkDragAndDrop.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIView+DragAndDrop.m
3 | // AtkDragAndDrop
4 | //
5 | // Created by Rick Boykin on 1/17/14.
6 | // Copyright (c) 2014 Asymptotik Limited. All rights reserved.
7 | //
8 |
9 | #import "UIView+AtkDragAndDrop.h"
10 | #import "UIView+AtkImage.h"
11 | #import "AtkDragAndDropManager.h"
12 |
13 | @implementation UIView (DragAndDrop)
14 |
15 | - (UIView *)createDefaultDragShadowView:(AtkDragAndDropManager *)manager
16 | {
17 | UIImage *image = [self imageFromView];
18 | UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
19 | CGRect frame = imageView.frame;
20 | frame.origin = [self convertPoint:self.bounds.origin toView:manager.rootView];
21 | imageView.frame = frame;
22 | imageView.alpha = 0.5;
23 | return imageView;
24 | }
25 |
26 | - (BOOL)isActiveDropZone:(AtkDragAndDropManager *)manager point:(CGPoint)point
27 | {
28 | UIView *view = self;
29 | BOOL ret = YES;
30 |
31 | // We can safely assume point is within rootView.
32 |
33 | while(ret == YES && manager.rootView != view)
34 | {
35 | CGPoint pointRelativeToView = [manager.rootView convertPoint:point toView:view];
36 | ret = ret && [view pointInside:pointRelativeToView withEvent:nil];
37 | view = view.superview;
38 | }
39 |
40 | return ret;
41 | }
42 |
43 | @end
44 |
--------------------------------------------------------------------------------
/Examples/AtkDragAndDrop_Examples/AtkDragAndDrop_Examples-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | ${PRODUCT_NAME}
9 | CFBundleExecutable
10 | ${EXECUTABLE_NAME}
11 | CFBundleIdentifier
12 | com.asymptotik.${PRODUCT_NAME:rfc1034identifier}
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | ${PRODUCT_NAME}
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1.0
25 | LSRequiresIPhoneOS
26 |
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/Classes/AtkDragAndDropLifecycleProtocol.h:
--------------------------------------------------------------------------------
1 | //
2 | // AtkDragAndDropLifecycleProtocol.h
3 | // AtkDragAndDrop_Examples
4 | //
5 | // Created by Rick Boykin on 4/29/14.
6 | // Copyright (c) 2014 Asymptotik Limited. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @class AtkDragAndDropManager;
12 | @protocol AtkDropZoneProtocol;
13 |
14 |
15 | @protocol AtkDragAndDropLifecycleProtocol
16 |
17 | @optional
18 |
19 | /**
20 | * Called when a drag has started. All of the interested drop zoned have been found.
21 | */
22 | - (void)dragStarted:(AtkDragAndDropManager *)manager;
23 |
24 | /**
25 | * Called when a drag has ended.
26 | */
27 | - (void)dragEnded:(AtkDragAndDropManager *)manager;
28 |
29 | /**
30 | * Called when a drag has entered a drop zone.
31 | */
32 | - (void)dragEntered:(AtkDragAndDropManager *)manager dropZone:(id) dropZone point:(CGPoint)point;
33 |
34 | /**
35 | * Called when a drag has exited a drop zone.
36 | */
37 | - (void)dragExited:(AtkDragAndDropManager *)manager dropZone:(id) dropZone point:(CGPoint)point;
38 |
39 | /**
40 | * Called when a drag has moved within a drop zone. Only called after dragEntered and before dragExited.
41 | */
42 | - (void)dragMoved:(AtkDragAndDropManager *)manager dropZone:(id) dropZone point:(CGPoint)point;
43 |
44 | /**
45 | * Called when a drag is dropped onto a drop zone.
46 | */
47 | - (void)dragDropped:(AtkDragAndDropManager *)manager dropZone:(id) dropZone point:(CGPoint)point;
48 |
49 |
50 | @end
51 |
--------------------------------------------------------------------------------
/Examples/AtkDragAndDrop_Examples.xcodeproj/project.xcworkspace/xcshareddata/AtkDragAndDrop_Examples.xccheckout:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDESourceControlProjectFavoriteDictionaryKey
6 |
7 | IDESourceControlProjectIdentifier
8 | 78B10556-4EA7-482E-9876-CECBC2DCF540
9 | IDESourceControlProjectName
10 | AtkDragAndDrop_Examples
11 | IDESourceControlProjectOriginsDictionary
12 |
13 | 9C2B6D92-48ED-46C9-8815-CAB5193B9A07
14 | ssh://github.com/ptoinson/asymptotik-drag-and-drop.git
15 |
16 | IDESourceControlProjectPath
17 | Examples/AtkDragAndDrop_Examples.xcodeproj/project.xcworkspace
18 | IDESourceControlProjectRelativeInstallPathDictionary
19 |
20 | 9C2B6D92-48ED-46C9-8815-CAB5193B9A07
21 | ../../..
22 |
23 | IDESourceControlProjectURL
24 | ssh://github.com/ptoinson/asymptotik-drag-and-drop.git
25 | IDESourceControlProjectVersion
26 | 110
27 | IDESourceControlProjectWCCIdentifier
28 | 9C2B6D92-48ED-46C9-8815-CAB5193B9A07
29 | IDESourceControlProjectWCConfigurations
30 |
31 |
32 | IDESourceControlRepositoryExtensionIdentifierKey
33 | public.vcs.git
34 | IDESourceControlWCCIdentifierKey
35 | 9C2B6D92-48ED-46C9-8815-CAB5193B9A07
36 | IDESourceControlWCCName
37 | Asymptotik_AtkDragAndDrop
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/Examples/AtkDragAndDrop_Examples/AtkSampleViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // AtkSampleViewController.m
3 | // Atkdrogen_DragAndDrop
4 | //
5 | // Created by Rick Boykin on 1/20/14.
6 | // Copyright (c) 2014 Asymptotik Limited. All rights reserved.
7 | //
8 |
9 | #import "AtkSampleViewController.h"
10 | #import "AtkSampleOneViewController.h"
11 | #import "AtkSampleTwoViewController.h"
12 |
13 | @interface AtkSampleViewController ()
14 |
15 | @end
16 |
17 | @implementation AtkSampleViewController
18 |
19 | - (id)init
20 | {
21 | self = [super init];
22 | if (self) {
23 | [self initialize];
24 | }
25 | return self;
26 | }
27 |
28 | - (id)initWithCoder:(NSCoder *)aDecoder
29 | {
30 | self = [super initWithCoder:aDecoder];
31 | if (self) {
32 | [self initialize];
33 | }
34 | return self;
35 | }
36 |
37 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
38 | {
39 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
40 | if (self) {
41 | [self initialize];
42 | }
43 | return self;
44 | }
45 |
46 | - (void)initialize
47 | {
48 | self.navigationItem.title = @"Samples";
49 | }
50 |
51 | - (void)viewDidLoad
52 | {
53 | [super viewDidLoad];
54 | // Do any additional setup after loading the view from its nib.
55 | }
56 |
57 | - (void)didReceiveMemoryWarning
58 | {
59 | [super didReceiveMemoryWarning];
60 | // Dispose of any resources that can be recreated.
61 | }
62 |
63 | - (IBAction)sampleOneFired:(id)sender
64 | {
65 | [self.navigationController pushViewController:[[AtkSampleOneViewController alloc] initWithNibName:@"AtkSampleOneViewController" bundle:nil] animated: YES];
66 | }
67 |
68 | - (IBAction)sampleTwoFired:(id)sender
69 | {
70 | [self.navigationController pushViewController:[[AtkSampleTwoViewController alloc] initWithNibName:@"AtkSampleTwoViewController" bundle:nil] animated: YES];
71 | }
72 |
73 | - (IBAction)sampleThreeFired:(id)sender
74 | {
75 | //[self.navigationController pushViewController:[[AtkSampleThreeViewController alloc] initWithNibName:@"AtkSampleThreeViewController" bundle:nil] animated: YES];
76 | }
77 |
78 | @end
79 |
--------------------------------------------------------------------------------
/Classes/AtkDropZoneProtocol.h:
--------------------------------------------------------------------------------
1 | //
2 | // AtkDropZoneProtocol.h
3 | // AtkDragAndDrop
4 | //
5 | // Created by Rick Boykin on 1/17/14.
6 | // Copyright (c) 2014 Asymptotik Limited. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @class AtkDragAndDropManager;
12 |
13 | @protocol AtkDropZoneProtocol
14 |
15 | @optional
16 |
17 | /**
18 | * Should the drop zone be considered active for the manager and point.
19 | */
20 | - (BOOL)dropZoneIsActive:(AtkDragAndDropManager *)manager point:(CGPoint)point;
21 |
22 | /**
23 | * A drag has started, should we consider this drop zone. A drop zone that is considered
24 | * will receive calls, as appropriate, to isInterested, dragStarted and dragEnded but not
25 | * dragEntered, dragExited, dragMoved and dragDropped
26 | */
27 | - (BOOL)dropZoneShouldDragStart:(AtkDragAndDropManager *)manager;
28 |
29 | /**
30 | * A drag has started and shouldDropStart returned YES. Should we consider this drop zone interested in receiving
31 | * the following calls dragEntered, dragExited, dragMoved, dragDropped in addition to dragStarted and dragEnded.
32 | */
33 | - (BOOL)dropZoneIsInterested:(AtkDragAndDropManager *)manager;
34 |
35 | /*
36 | * Called on all drop zones that responded YES to dragStarted when the drag operation has started. This will
37 | * be soon after shouldDropStart responds YES.
38 | */
39 | - (void)dropZoneDragStarted:(AtkDragAndDropManager *)manager;
40 |
41 | /*
42 | * Called on all drop zones that responded YES to dragStarted when the drag operation has ended. This will
43 | * be called last in the lifecycle of AtkDragAndDrop.
44 | */
45 | - (void)dropZoneDragEnded:(AtkDragAndDropManager *)manager;
46 |
47 | /*
48 | * Called when the drag has entered the drop zone.
49 | */
50 | - (void)dropZoneDragEntered:(AtkDragAndDropManager *)manager point:(CGPoint)point;
51 |
52 | /*
53 | * Called when the drag has exited the drop zone.
54 | */
55 | - (void)dropZoneDragExited:(AtkDragAndDropManager *)manager point:(CGPoint)point;
56 |
57 | /*
58 | * Called when the drag is in the drop zone and has moved.
59 | */
60 | - (void)dropZoneDragMoved:(AtkDragAndDropManager *)manager point:(CGPoint)point;
61 |
62 | /*
63 | * called when the drag is in the drop zone and has been dropped.
64 | */
65 | - (void)dropZoneDragDropped:(AtkDragAndDropManager *)manager point:(CGPoint)point;
66 |
67 | @end
68 |
--------------------------------------------------------------------------------
/Examples/AtkDragAndDrop_Examples/Sample01/AtkSampleOneViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // AtkSampleOneViewController.m
3 | // AtkDragAndDrop
4 | //
5 | // Created by Rick Boykin on 1/15/14.
6 | // Copyright (c) 2014 Asymptotik Limited. All rights reserved.
7 | //
8 |
9 | #import "AtkSampleOneViewController.h"
10 | #import "AtkDragAndDropManager.h"
11 |
12 | @interface AtkSampleOneViewController ()
13 |
14 | @property (nonatomic, strong) IBOutlet UIView *viewSource;
15 | @property (nonatomic, strong) IBOutlet UIScrollView *scroller;
16 | @property (nonatomic, strong) IBOutlet UIView *viewParent;
17 | @property (nonatomic, strong) IBOutlet UIView *viewTarget01;
18 | @property (nonatomic, strong) IBOutlet UIView *viewTarget02;
19 | @property (nonatomic, strong) IBOutlet UIView *viewTarget03;
20 | @property (nonatomic, strong) IBOutlet UIView *viewTarget04;
21 | @property (nonatomic, strong) IBOutlet UIView *viewTarget05;
22 | @property (nonatomic, strong) IBOutlet UIView *viewTarget06;
23 | @property (nonatomic, strong) IBOutlet UIView *viewTarget07;
24 | @property (nonatomic, strong) IBOutlet UIView *viewTarget08;
25 | @property (nonatomic, strong) AtkDragAndDropManager *dragAndDropManager;
26 |
27 | @end
28 |
29 | @implementation AtkSampleOneViewController
30 |
31 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
32 | {
33 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
34 | if (self) {
35 | [self initialize];
36 | }
37 | return self;
38 | }
39 |
40 | - (void)initialize
41 | {
42 | self.navigationItem.title = @"Sample One";
43 | self.dragAndDropManager = [[AtkDragAndDropManager alloc] init];
44 | }
45 |
46 | - (void)viewDidLoad
47 | {
48 | [super viewDidLoad];
49 |
50 | CGRect viewParentFrame = _viewParent.frame;
51 |
52 | _scroller.contentSize = viewParentFrame.size;
53 | // Do any additional setup after loading the view from its nib.
54 | }
55 |
56 | - (void)viewDidAppear:(BOOL)animated
57 | {
58 | [super viewDidAppear:animated];
59 | [self.dragAndDropManager start];
60 | }
61 |
62 | - (void)viewWillDisappear:(BOOL)animated
63 | {
64 | [self.dragAndDropManager stop];
65 | [super viewWillDisappear:animated];
66 | }
67 |
68 | - (void)didReceiveMemoryWarning
69 | {
70 | [super didReceiveMemoryWarning];
71 | // Dispose of any resources that can be recreated.
72 | }
73 |
74 | @end
75 |
--------------------------------------------------------------------------------
/Examples/AtkDragAndDrop_Examples/Sample01/AtkSampleOneDropZoneScrollView.m:
--------------------------------------------------------------------------------
1 | //
2 | // AtkSampleOneDropZoneScrollView.m
3 | // AtkDragAndDrop
4 | //
5 | // Created by Rick Boykin on 1/17/14.
6 | // Copyright (c) 2014 Asymptotik Limited. All rights reserved.
7 | //
8 |
9 | #import "AtkSampleOneDropZoneScrollView.h"
10 | #import "UIScrollView+AtkDragAndDrop.h"
11 |
12 | @interface AtkSampleOneDropZoneScrollView ()
13 |
14 | @property (nonatomic, strong) UIColor *savedBackgroundColor;
15 |
16 | @end
17 |
18 | @implementation AtkSampleOneDropZoneScrollView
19 |
20 | - (id)init
21 | {
22 | self = [super init];
23 | if(self) {
24 |
25 | }
26 | return self;
27 | }
28 |
29 | - (id)initWithFrame:(CGRect)frame
30 | {
31 | self = [super initWithFrame:frame];
32 | if (self) {
33 |
34 | }
35 | return self;
36 | }
37 |
38 | - (id)initWithCoder:(NSCoder *)aDecoder
39 | {
40 | self = [super initWithCoder:aDecoder];
41 | if (self) {
42 |
43 | }
44 | return self;
45 | }
46 |
47 | - (BOOL)dropZoneShouldDragStart:(AtkDragAndDropManager *)manager
48 | {
49 | return YES;
50 | }
51 |
52 | - (void)dropZoneDragStarted:(AtkDragAndDropManager *)manager
53 | {
54 | //NSLog(@"AtkSampleOneDropZoneScrollView.dragStarted");
55 | [self autoScrollDragStarted];
56 | }
57 |
58 | - (BOOL)dropZoneIsInterested:(AtkDragAndDropManager *)manager
59 | {
60 | //NSLog(@"AtkSampleOneDropZoneScrollView.isInterested");
61 | return YES;
62 | }
63 |
64 | - (void)dropZoneDragEnded:(AtkDragAndDropManager *)manager
65 | {
66 | //NSLog(@"AtkSampleOneDropZoneScrollView.dragEnded");
67 | [self autoScrollDragEnded];
68 | }
69 |
70 | - (void)dropZoneDragEntered:(AtkDragAndDropManager *)manager point:(CGPoint)point
71 | {
72 | //NSLog(@"AtkSampleOneDropZoneScrollView.dragEntered");
73 | self.savedBackgroundColor = self.backgroundColor;
74 | self.backgroundColor = [UIColor blueColor];
75 | }
76 |
77 | - (void)dropZoneDragExited:(AtkDragAndDropManager *)manager point:(CGPoint)point
78 | {
79 | //NSLog(@"AtkSampleOneDropZoneScrollView.dragExited");
80 | self.backgroundColor = self.savedBackgroundColor;
81 | }
82 |
83 | - (void)dropZoneDragMoved:(AtkDragAndDropManager *)manager point:(CGPoint)point
84 | {
85 | [self autoScrollDragMoved:[manager.rootView convertPoint:point toView:self]];
86 | }
87 |
88 | - (void)dropZoneDragDropped:(AtkDragAndDropManager *)manager point:(CGPoint)point
89 | {
90 | //NSLog(@"AtkSampleOneDropZoneScrollView.dragDropped");
91 | self.backgroundColor = [UIColor greenColor];
92 | }
93 |
94 | @end
95 |
--------------------------------------------------------------------------------
/Examples/AtkDragAndDrop_Examples/Sample02/AtkSampleTwoDropZoneScrollViewWrapper.m:
--------------------------------------------------------------------------------
1 | //
2 | // AtkSampleTwoDropZoneScrollViewWrapper.m
3 | // Atkdrogen_DragAndDrop
4 | //
5 | // Created by Rick Boykin on 1/21/14.
6 | // Copyright (c) 2014 Asymptotik Limited. All rights reserved.
7 | //
8 |
9 | #import "AtkSampleTwoDropZoneScrollViewWrapper.h"
10 | #import "UIScrollView+AtkDragAndDrop.h"
11 |
12 | @interface AtkSampleTwoDropZoneScrollViewWrapper ()
13 |
14 | @property (nonatomic, strong) UIColor *savedBackgroundColor;
15 |
16 | @end
17 |
18 | @implementation AtkSampleTwoDropZoneScrollViewWrapper
19 |
20 | - (id)initWithScrollView:(UIScrollView *)view
21 | {
22 | self = [super init];
23 | if(self)
24 | {
25 | self.view = view;
26 | [self initialize];
27 | }
28 | return self;
29 | }
30 |
31 | - (void)initialize
32 | {
33 | }
34 |
35 | - (BOOL)dropZoneIsActive:(AtkDragAndDropManager *)manager point:(CGPoint)point
36 | {
37 | return [self.view isActiveDropZone:manager point:point];
38 | }
39 |
40 | - (BOOL)dropZoneShouldDragStart:(AtkDragAndDropManager *)manager
41 | {
42 | NSLog(@"AtkSampleOneDropZoneScrollView.shouldDragStart");
43 | return YES;
44 | }
45 |
46 | - (void)dropZoneDragStarted:(AtkDragAndDropManager *)manager
47 | {
48 | NSLog(@"AtkSampleOneDropZoneScrollView.dragStarted");
49 | [self.view autoScrollDragStarted];
50 | }
51 |
52 | - (BOOL)dropZoneIsInterested:(AtkDragAndDropManager *)manager
53 | {
54 | NSLog(@"AtkSampleOneDropZoneScrollView.isInterested");
55 | return YES;
56 | }
57 |
58 | - (void)dropZoneDragEnded:(AtkDragAndDropManager *)manager
59 | {
60 | NSLog(@"AtkSampleOneDropZoneScrollView.dragEnded");
61 | [self.view autoScrollDragEnded];
62 | }
63 |
64 | - (void)dropZoneDragEntered:(AtkDragAndDropManager *)manager point:(CGPoint)point
65 | {
66 | NSLog(@"AtkSampleOneDropZoneScrollView.dragEntered");
67 | self.savedBackgroundColor = self.view.backgroundColor;
68 | self.view.backgroundColor = [UIColor blueColor];
69 | }
70 |
71 | - (void)dropZoneDragExited:(AtkDragAndDropManager *)manager point:(CGPoint)point
72 | {
73 | NSLog(@"AtkSampleOneDropZoneScrollView.dragExited");
74 | self.view.backgroundColor = self.savedBackgroundColor;
75 | }
76 |
77 | - (void)dropZoneDragMoved:(AtkDragAndDropManager *)manager point:(CGPoint)point
78 | {
79 | [self.view autoScrollDragMoved:[manager.rootView convertPoint:point toView:self.view]];
80 | }
81 |
82 | - (void)dropZoneDragDropped:(AtkDragAndDropManager *)manager point:(CGPoint)point
83 | {
84 | NSLog(@"AtkSampleOneDropZoneScrollView.dragDropped");
85 | self.view.backgroundColor = [UIColor greenColor];
86 | }
87 |
88 | @end
89 |
--------------------------------------------------------------------------------
/Examples/AtkDragAndDrop_Examples/AtkAppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AtkAppDelegate.m
3 | // AtkDragAndDrop
4 | //
5 | // Created by Rick Boykin on 1/15/14.
6 | // Copyright (c) 2014 Rick Boykin. All rights reserved.
7 | //
8 |
9 | #import "AtkAppDelegate.h"
10 | #import "AtkSampleViewController.h"
11 | #import "AtkDragAndDrop.h"
12 |
13 | @implementation AtkAppDelegate
14 |
15 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
16 | {
17 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
18 |
19 |
20 | AtkSampleViewController *sampleViewController = [[AtkSampleViewController alloc] initWithNibName:@"AtkSampleViewController" bundle:nil];
21 | UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:sampleViewController];
22 | navController.navigationBar.translucent = NO;
23 | navController.edgesForExtendedLayout = UIRectEdgeNone;
24 |
25 | self.window.rootViewController = navController;
26 |
27 | [self.window makeKeyAndVisible];
28 |
29 | return YES;
30 | }
31 |
32 | - (void)applicationWillResignActive:(UIApplication *)application
33 | {
34 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
35 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
36 | }
37 |
38 | - (void)applicationDidEnterBackground:(UIApplication *)application
39 | {
40 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
41 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
42 | }
43 |
44 | - (void)applicationWillEnterForeground:(UIApplication *)application
45 | {
46 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
47 | }
48 |
49 | - (void)applicationDidBecomeActive:(UIApplication *)application
50 | {
51 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
52 | }
53 |
54 | - (void)applicationWillTerminate:(UIApplication *)application
55 | {
56 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
57 | }
58 |
59 | @end
60 |
--------------------------------------------------------------------------------
/Examples/AtkDragAndDrop_Examples/Sample01/AtkSampleOneDropZoneView.m:
--------------------------------------------------------------------------------
1 | //
2 | // AtkSampleOneDropZoneView.m
3 | // AtkDragAndDrop
4 | //
5 | // Created by Rick Boykin on 1/17/14.
6 | // Copyright (c) 2014 Asymptotik Limited. All rights reserved.
7 | //
8 |
9 | #import "AtkSampleOneDropZoneView.h"
10 |
11 | @interface AtkSampleOneDropZoneView ()
12 |
13 | @property (nonatomic, strong) UIColor *savedBackgroundColor;
14 |
15 | @end
16 |
17 | @implementation AtkSampleOneDropZoneView
18 |
19 | - (id)initWithFrame:(CGRect)frame
20 | {
21 | self = [super initWithFrame:frame];
22 | if (self) {
23 | // Initialization code
24 | }
25 | return self;
26 | }
27 |
28 | - (BOOL)dropZoneShouldDragStart:(AtkDragAndDropManager *)manager
29 | {
30 | return YES;
31 | }
32 |
33 | - (BOOL)dropZoneIsInterested:(AtkDragAndDropManager *)manager
34 | {
35 | NSLog(@"AtkSampleOneDropZoneView.isInterested");
36 |
37 | UIPasteboard *pastebaord = manager.pasteboard;
38 | NSString *tagValue = [NSString stringWithFormat:@"val-%ld", (long)self.tag];
39 | NSString *pasteboardString = pastebaord.string;
40 |
41 | return [tagValue isEqualToString:pasteboardString];
42 | }
43 |
44 | - (void)dropZoneDragStarted:(AtkDragAndDropManager *)manager
45 | {
46 | NSLog(@"AtkSampleOneDropZoneView.dragStarted");
47 | self.savedBackgroundColor = self.backgroundColor;
48 |
49 | UIPasteboard *pastebaord = manager.pasteboard;
50 | NSString *tagValue = [NSString stringWithFormat:@"val-%ld", (long)self.tag];
51 | NSString *pasteboardString = pastebaord.string;
52 |
53 | if([tagValue isEqualToString:pasteboardString])
54 | {
55 | self.backgroundColor = [UIColor colorWithRed:0.9 green:0.9 blue:0.9 alpha:1.0];
56 | }
57 | else
58 | {
59 | self.backgroundColor = [UIColor redColor];
60 | }
61 | }
62 |
63 | - (void)dropZoneDragEnded:(AtkDragAndDropManager *)manager
64 | {
65 | NSLog(@"AtkSampleOneDropZoneView.dragEnded");
66 | [self performSelector:@selector(delayEnd) withObject:nil afterDelay:0.4];
67 | }
68 |
69 | - (void)dropZoneDragEntered:(AtkDragAndDropManager *)manager point:(CGPoint)point
70 | {
71 | NSLog(@"AtkSampleOneDropZoneView.dragEntered");
72 | self.backgroundColor = [UIColor orangeColor];
73 | }
74 |
75 | - (void)dropZoneDragExited:(AtkDragAndDropManager *)manager point:(CGPoint)point
76 | {
77 | NSLog(@"AtkSampleOneDropZoneView.dragExited");
78 | self.backgroundColor = [UIColor colorWithRed:0.9 green:0.9 blue:0.9 alpha:1.0];
79 | }
80 |
81 | - (void)dropZoneDragMoved:(AtkDragAndDropManager *)manager point:(CGPoint)point
82 | {
83 | //NSLog(@"AtkSampleOneDropZoneView.dragMoved");
84 | }
85 |
86 | - (void)dropZoneDragDropped:(AtkDragAndDropManager *)manager point:(CGPoint)point
87 | {
88 | NSLog(@"AtkSampleOneDropZoneView.dragDropped");
89 | self.backgroundColor = [UIColor magentaColor];
90 | }
91 |
92 | - (void)delayEnd
93 | {
94 | self.backgroundColor = self.savedBackgroundColor;
95 | }
96 |
97 | @end
98 |
--------------------------------------------------------------------------------
/Examples/AtkDragAndDrop_Examples/Sample02/AtkSampleTwoDropZoneWrapper.m:
--------------------------------------------------------------------------------
1 | //
2 | // AtkSampleTwoDropZoneWrapper.m
3 | // Atkdrogen_DragAndDrop
4 | //
5 | // Created by Rick Boykin on 1/21/14.
6 | // Copyright (c) 2014 Asymptotik Limited. All rights reserved.
7 | //
8 |
9 | #import "AtkSampleTwoDropZoneWrapper.h"
10 | #import "AtkDragAndDrop.h"
11 |
12 | @interface AtkSampleTwoDropZoneWrapper()
13 |
14 | @property (nonatomic, strong) UIColor *savedBackgroundColor;
15 |
16 | @end
17 |
18 | @implementation AtkSampleTwoDropZoneWrapper
19 |
20 | - (id)initWithView:(UIView *)view
21 | {
22 | self = [super init];
23 | if(self)
24 | {
25 | self.view = view;
26 | [self initialize];
27 | }
28 | return self;
29 | }
30 |
31 | - (void)initialize
32 | {
33 |
34 | }
35 |
36 | - (BOOL)dropZoneIsActive:(AtkDragAndDropManager *)manager point:(CGPoint)point
37 | {
38 | return [self.view isActiveDropZone:manager point:point];
39 | }
40 |
41 | - (BOOL)dropZoneShouldDragStart:(AtkDragAndDropManager *)manager
42 | {
43 | return YES;
44 | }
45 |
46 | - (BOOL)dropZoneIsInterested:(AtkDragAndDropManager *)manager
47 | {
48 | //NSLog(@"AtkSampleOneDropZoneView.dragStarted");
49 | UIPasteboard *pastebaord = manager.pasteboard;
50 | NSString *tagValue = [NSString stringWithFormat:@"val-%ld", (long)self.view.tag];
51 | NSString *pasteboardString = pastebaord.string;
52 |
53 | return [tagValue isEqualToString:pasteboardString];
54 | }
55 |
56 | - (void)dropZoneDragStarted:(AtkDragAndDropManager *)manager
57 | {
58 | //NSLog(@"AtkSampleOneDropZoneView.dragStarted");
59 | self.savedBackgroundColor = self.view.backgroundColor;
60 |
61 | UIPasteboard *pastebaord = manager.pasteboard;
62 | NSString *tagValue = [NSString stringWithFormat:@"val-%ld", (long)self.view.tag];
63 | NSString *pasteboardString = pastebaord.string;
64 |
65 | if([tagValue isEqualToString:pasteboardString])
66 | {
67 | self.view.backgroundColor = [UIColor colorWithRed:0.9 green:0.9 blue:0.9 alpha:1.0];
68 | }
69 | else
70 | {
71 | self.view.backgroundColor = [UIColor redColor];
72 | }
73 | }
74 |
75 | - (void)dropZoneDragEnded:(AtkDragAndDropManager *)manager
76 | {
77 | //NSLog(@"AtkSampleOneDropZoneView.dragEnded");
78 | [self performSelector:@selector(delayEnd) withObject:nil afterDelay:0.4];
79 | }
80 |
81 | - (void)dropZoneDragEntered:(AtkDragAndDropManager *)manager point:(CGPoint)point
82 | {
83 | //NSLog(@"AtkSampleOneDropZoneView.dragEntered");
84 | self.view.backgroundColor = [UIColor orangeColor];
85 | }
86 |
87 | - (void)dropZoneDragExited:(AtkDragAndDropManager *)manager point:(CGPoint)point
88 | {
89 | //NSLog(@"AtkSampleOneDropZoneView.dragExited");
90 | self.view.backgroundColor = [UIColor colorWithRed:0.9 green:0.9 blue:0.9 alpha:1.0];
91 | }
92 |
93 | - (void)dropZoneDragMoved:(AtkDragAndDropManager *)manager point:(CGPoint)point
94 | {
95 | //NSLog(@"AtkSampleOneDropZoneView.dragMoved");
96 | }
97 |
98 | - (void)dropZoneDragDropped:(AtkDragAndDropManager *)manager point:(CGPoint)point
99 | {
100 | //NSLog(@"AtkSampleOneDropZoneView.dragDropped");
101 | self.view.backgroundColor = [UIColor magentaColor];
102 | }
103 |
104 | - (void)delayEnd
105 | {
106 | self.view.backgroundColor = self.savedBackgroundColor;
107 | }
108 |
109 | @end
110 |
--------------------------------------------------------------------------------
/Examples/AtkDragAndDrop_Examples/AtkSampleViewController.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
27 |
36 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/Classes/AtkDefaultDragAndDropManagerDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AtkDefaultDragAndDropManagerDelegate.m
3 | // Atkdrogen_DragAndDrop
4 | //
5 | // Created by Rick Boykin on 1/20/14.
6 | // Copyright (c) 2014 Asymptotik Limited. All rights reserved.
7 | //
8 |
9 | #import "AtkDefaultDragAndDropManagerDelegate.h"
10 | #import "UIView+AtkDragAndDrop.h"
11 |
12 | @implementation AtkDefaultDragAndDropManagerDelegate
13 |
14 | /**
15 | * Finds the drag source.
16 | */
17 | - (id)findDragSource:(AtkDragAndDropManager *)manager recognizer:(UIGestureRecognizer *)recognizer
18 | {
19 | BOOL dragStarted = NO;
20 |
21 | CGPoint point = [recognizer locationInView:manager.rootView];
22 | UIView *hitView = [manager.rootView hitTest:point withEvent:nil];
23 |
24 | while(!dragStarted && hitView)
25 | {
26 | if([hitView conformsToProtocol:@protocol(AtkDragSourceProtocol)])
27 | {
28 | if([hitView respondsToSelector:@selector(shouldDragStart:point:)])
29 | dragStarted = [(UIView *)hitView shouldDragStart:manager point: point];
30 | else
31 | dragStarted = YES;
32 | }
33 |
34 | if(!dragStarted)
35 | {
36 | hitView = hitView.superview;
37 | }
38 | }
39 |
40 | return dragStarted ? (id)hitView : nil;
41 | }
42 |
43 | /**
44 | * Recursively finds any drop zones (id) in view and it's descendants that are interested in the gesture recognizer
45 | * and adds them to dropZones. The return value is the passed in dropZones. If a drop zone is found and dropZones is nil, a new
46 | * NSMutableArray will be constructed, filled and returned.
47 | */
48 | - (NSMutableArray *)findDropZones:(AtkDragAndDropManager *)manager view:(UIView *)view recognizer:(UIGestureRecognizer *)recognizer dropZones:(NSMutableArray *)dropZones
49 | {
50 | if([view conformsToProtocol:@protocol(AtkDropZoneProtocol)] &&
51 | [view respondsToSelector:@selector(dropZoneShouldDragStart:)] &&
52 | [(id)view dropZoneShouldDragStart:manager])
53 | {
54 | if(!dropZones)
55 | dropZones = [NSMutableArray array];
56 |
57 | [dropZones addObject:view];
58 | }
59 |
60 | for (UIView *subview in view.subviews)
61 | {
62 | dropZones = [self findDropZones:manager view:subview recognizer:recognizer dropZones:dropZones];
63 | }
64 |
65 | return dropZones;
66 | }
67 |
68 | /**
69 | * Recursively finds any drop zones (id) in rootView and it's descendants that are interested in the gesture
70 | * recognizer and returns them.
71 | */
72 | - (NSArray *)findDropZones:(AtkDragAndDropManager *)manager recognizer:(UIGestureRecognizer *)recognizer
73 | {
74 | NSMutableArray *ret = [self findDropZones:manager view:manager.rootView recognizer:recognizer dropZones:nil];
75 | return ret ? [NSArray arrayWithArray:ret] : nil;
76 | }
77 |
78 | /**
79 | * Returns YES is the specified drop zone is active for the recognizer. Active means that if the
80 | * drop event were to occur immediately, that drop zone would be dropped upon.
81 | */
82 | - (BOOL)isDropZoneActive:(AtkDragAndDropManager *)manager dropZone:(id)dropZone recognizer:(UIGestureRecognizer *)recognizer
83 | {
84 | BOOL ret = false;
85 |
86 | if([dropZone respondsToSelector:@selector(dropZoneIsActive:point:)])
87 | {
88 | ret = [dropZone dropZoneIsActive:manager point:[recognizer locationInView:manager.rootView]];
89 | }
90 | else if([dropZone isKindOfClass:[UIView class]])
91 | {
92 | UIView *dropView = (UIView *)dropZone;
93 | ret = [dropView isActiveDropZone:manager point:[recognizer locationInView:manager.rootView]];
94 | }
95 | else if([dropZone isKindOfClass:[UIViewController class]])
96 | {
97 | UIView *dropView = ((UIViewController *)dropZone).view;
98 | ret = [dropView isActiveDropZone:manager point:[recognizer locationInView:manager.rootView]];
99 | }
100 |
101 | return ret;
102 | }
103 |
104 | @end
105 |
--------------------------------------------------------------------------------
/Examples/AtkDragAndDrop_Examples/Sample02/AtkSampleTwoViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // AtkSampleTwoViewController.m
3 | // AtkDragAndDrop
4 | //
5 | // Created by Rick Boykin on 1/15/14.
6 | // Copyright (c) 2014 Asymptotik Limited. All rights reserved.
7 | //
8 |
9 | #import "AtkSampleTwoViewController.h"
10 | #import "AtkSampleTwoDragSourceWrapper.h"
11 | #import "AtkSampleTwoDropZoneWrapper.h"
12 | #import "AtkSampleTwoDropZoneScrollViewWrapper.h"
13 | #import "AtkDragAndDrop.h"
14 |
15 | @interface AtkSampleTwoViewController ()
16 |
17 | @property (nonatomic, strong) IBOutlet UIView *viewSource01;
18 | @property (nonatomic, strong) IBOutlet UIView *viewSource02;
19 | @property (nonatomic, strong) IBOutlet UIScrollView *scroller;
20 | @property (nonatomic, strong) IBOutlet UIView *viewParent;
21 | @property (nonatomic, strong) AtkDragAndDropManager *dragAndDropManager;
22 |
23 | @end
24 |
25 | @implementation AtkSampleTwoViewController
26 |
27 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
28 | {
29 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
30 | if (self) {
31 | [self initialize];
32 | }
33 | return self;
34 | }
35 |
36 | - (void)initialize
37 | {
38 | self.navigationItem.title = @"Sample Two";
39 | self.dragAndDropManager = [[AtkDragAndDropManager alloc] init];
40 | self.dragAndDropManager.delegate = self;
41 | }
42 |
43 | - (void)viewDidLoad
44 | {
45 | [super viewDidLoad];
46 |
47 | CGRect viewParentFrame = _viewParent.frame;
48 |
49 | _scroller.contentSize = viewParentFrame.size;
50 | // Do any additional setup after loading the view from its nib.
51 | }
52 |
53 | - (void)viewDidAppear:(BOOL)animated
54 | {
55 | [super viewDidAppear:animated];
56 | [self.dragAndDropManager start:[[UIApplication sharedApplication] keyWindow] recognizerClass:[UILongPressGestureRecognizer class]];
57 | }
58 |
59 | - (void)viewWillDisappear:(BOOL)animated
60 | {
61 | [self.dragAndDropManager stop];
62 | [super viewWillDisappear:animated];
63 | }
64 |
65 | - (void)didReceiveMemoryWarning
66 | {
67 | [super didReceiveMemoryWarning];
68 | // Dispose of any resources that can be recreated.
69 | }
70 |
71 | /**
72 | * Finds the drag source.
73 | */
74 | - (id)findDragSource:(AtkDragAndDropManager *)manager recognizer:(UIGestureRecognizer *)recognizer
75 | {
76 | BOOL dragStarted = NO;
77 |
78 | UIView *hitView = [manager.rootView hitTest:[recognizer locationInView:manager.rootView] withEvent:nil];
79 |
80 | // Very simple find. Use any means you want to find the sources.
81 | if(hitView == _viewSource01 || hitView == _viewSource02)
82 | dragStarted = YES;
83 |
84 | AtkSampleTwoDragSourceWrapper * ret = nil;
85 |
86 | if(dragStarted)
87 | {
88 | ret = [[AtkSampleTwoDragSourceWrapper alloc] initWithView:hitView];
89 | }
90 |
91 | return ret;
92 | }
93 |
94 | /**
95 | * Recursively finds any drop zones (id) in rootView and it's descendents that are interested in the gesture
96 | * recognizer and returns them.
97 | */
98 | - (NSArray *)findDropZones:(AtkDragAndDropManager *)manager recognizer:(UIGestureRecognizer *)recognizer
99 | {
100 | NSMutableArray *ret = [NSMutableArray arrayWithCapacity:10];
101 | AtkSampleTwoDropZoneScrollViewWrapper *scrollViewDropZone = [[AtkSampleTwoDropZoneScrollViewWrapper alloc] initWithScrollView:_scroller];
102 |
103 | [ret addObject:scrollViewDropZone];
104 |
105 | for(UIView *child in _viewParent.subviews)
106 | {
107 | AtkSampleTwoDropZoneWrapper *viewDropZone = [[AtkSampleTwoDropZoneWrapper alloc] initWithView:child];
108 | [ret addObject:viewDropZone];
109 | }
110 |
111 | return ret;
112 | }
113 |
114 | /**
115 | * Returns YES is the specified drop zone is active for the recognizer. Active means that if the
116 | * drop event were to occur immediately, that drop zone would be dropped upon.
117 | */
118 | - (BOOL)isDropZoneActive:(AtkDragAndDropManager *)manager dropZone:(id)dropZone recognizer:(UIGestureRecognizer *)recognizer
119 | {
120 | BOOL ret = false;
121 |
122 | if([dropZone respondsToSelector:@selector(dropZoneIsActive:point:)])
123 | {
124 | ret = [dropZone dropZoneIsActive:manager point:[recognizer locationInView:manager.rootView]];
125 | }
126 |
127 | return ret;
128 | }
129 |
130 | @end
131 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | desc "Runs the specs [EMPTY]"
2 | task :spec do
3 | # Provide your own implementation
4 | end
5 |
6 | task :version do
7 | git_remotes = `git remote`.strip.split("\n")
8 |
9 | if git_remotes.count > 0
10 | puts "-- fetching version number from github"
11 | sh 'git fetch'
12 |
13 | remote_version = remote_spec_version
14 | end
15 |
16 | if remote_version.nil?
17 | puts "There is no current released version. You're about to release a new Pod."
18 | version = "0.0.1"
19 | else
20 | puts "The current released version of your pod is " + remote_spec_version.to_s()
21 | version = suggested_version_number
22 | end
23 |
24 | puts "Enter the version you want to release (" + version + ") "
25 | new_version_number = $stdin.gets.strip
26 | if new_version_number == ""
27 | new_version_number = version
28 | end
29 |
30 | replace_version_number(new_version_number)
31 | end
32 |
33 | desc "Release a new version of the Pod"
34 | task :release do
35 |
36 | puts "* Running version"
37 | sh "rake version"
38 |
39 | unless ENV['SKIP_CHECKS']
40 | if `git symbolic-ref HEAD 2>/dev/null`.strip.split('/').last != 'master'
41 | $stderr.puts "[!] You need to be on the `master' branch in order to be able to do a release."
42 | exit 1
43 | end
44 |
45 | if `git tag`.strip.split("\n").include?(spec_version)
46 | $stderr.puts "[!] A tag for version `#{spec_version}' already exists. Change the version in the podspec"
47 | exit 1
48 | end
49 |
50 | puts "You are about to release `#{spec_version}`, is that correct? [y/n]"
51 | exit if $stdin.gets.strip.downcase != 'y'
52 | end
53 |
54 | puts "* Running specs"
55 | sh "rake spec"
56 |
57 | puts "* Linting the podspec"
58 | sh "pod lib lint"
59 |
60 | # Then release
61 | sh "git commit #{podspec_path} CHANGELOG.md -m 'Release #{spec_version}'"
62 | sh "git tag -a #{spec_version} -m 'Release #{spec_version}'"
63 | sh "git push origin master"
64 | sh "git push origin --tags"
65 | sh "pod push master #{podspec_path}"
66 | end
67 |
68 | # @return [Pod::Version] The version as reported by the Podspec.
69 | #
70 | def spec_version
71 | require 'cocoapods'
72 | spec = Pod::Specification.from_file(podspec_path)
73 | spec.version
74 | end
75 |
76 | # @return [Pod::Version] The version as reported by the Podspec from remote.
77 | #
78 | def remote_spec_version
79 | require 'cocoapods-core'
80 |
81 | if spec_file_exist_on_remote?
82 | remote_spec = eval(`git show origin/master:#{podspec_path}`)
83 | remote_spec.version
84 | else
85 | nil
86 | end
87 | end
88 |
89 | # @return [Bool] If the remote repository has a copy of the podpesc file or not.
90 | #
91 | def spec_file_exist_on_remote?
92 | test_condition = `if git rev-parse --verify --quiet origin/master:#{podspec_path} >/dev/null;
93 | then
94 | echo 'true'
95 | else
96 | echo 'false'
97 | fi`
98 |
99 | 'true' == test_condition.strip
100 | end
101 |
102 | # @return [String] The relative path of the Podspec.
103 | #
104 | def podspec_path
105 | podspecs = Dir.glob('*.podspec')
106 | if podspecs.count == 1
107 | podspecs.first
108 | else
109 | raise "Could not select a podspec"
110 | end
111 | end
112 |
113 | # @return [String] The suggested version number based on the local and remote version numbers.
114 | #
115 | def suggested_version_number
116 | if spec_version != remote_spec_version
117 | spec_version.to_s()
118 | else
119 | next_version(spec_version).to_s()
120 | end
121 | end
122 |
123 | # @param [Pod::Version] version
124 | # the version for which you need the next version
125 | #
126 | # @note It is computed by bumping the last component of the versino string by 1.
127 | #
128 | # @return [Pod::Version] The version that comes next after the version supplied.
129 | #
130 | def next_version(version)
131 | version_components = version.to_s().split(".");
132 | last = (version_components.last.to_i() + 1).to_s
133 | version_components[-1] = last
134 | Pod::Version.new(version_components.join("."))
135 | end
136 |
137 | # @param [String] new_version_number
138 | # the new version number
139 | #
140 | # @note This methods replaces the version number in the podspec file with a new version number.
141 | #
142 | # @return void
143 | #
144 | def replace_version_number(new_version_number)
145 | text = File.read(podspec_path)
146 | text.gsub!(/(s.version( )*= ")#{spec_version}(")/, "\\1#{new_version_number}\\3")
147 | File.open(podspec_path, "w") { |file| file.puts text }
148 | end
--------------------------------------------------------------------------------
/Classes/AtkDragAndDropManager.h:
--------------------------------------------------------------------------------
1 | //
2 | // AtkDragAndDropManager.h
3 | // AtkDragAndDrop
4 | //
5 | // Created by Rick Boykin on 1/17/14.
6 | // Copyright (c) 2014 Asymptotik Limited. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AtkDragSourceProtocol.h"
11 | #import "AtkDragAndDropLifecycleProtocol.h"
12 |
13 | @class AtkDragAndDropManager;
14 |
15 | @protocol AtkDragAndDropManagerDelegate
16 |
17 | @optional
18 |
19 | /**
20 | * Finds the drag source based on the rootView and the recognizer. If not implemented the default is used.
21 | */
22 | - (id)findDragSource:(AtkDragAndDropManager *)manager recognizer:(UIGestureRecognizer *)recognizer;
23 |
24 | /**
25 | * Recursively finds any drop zones (id) in rootView and it's descendents that are interested in the gesture
26 | * recognizer and returns them. In some cases the drag operation may include data set on the AtkDragAndDropManagers UIPasteboard.
27 | * It's up to this method to determine if the drop zone is interested in the content of that UIPasteboard.
28 | *
29 | * If not implemented the default is used.
30 | */
31 | - (NSArray *)findDropZones:(AtkDragAndDropManager *)manager recognizer:(UIGestureRecognizer *)recognizer;
32 |
33 | /**
34 | * Returns YES is the specified drop zone is active for the recognizer. Active means that if the
35 | * drop event were to occur immediately, that drop zone would be dropped upon. For example, if the
36 | * current touch has dragged over the drop zone, the drop zone may then be active.
37 | *
38 | * If not implemented the default is used.
39 | */
40 | - (BOOL)isDropZoneActive:(AtkDragAndDropManager *)manager dropZone:(id)dropZone recognizer:(UIGestureRecognizer *)recognizer;
41 |
42 | /**
43 | * Called when a drag source has been found, but before searching for drop zones.
44 | */
45 | - (void)dragWillStart:(AtkDragAndDropManager *)manager;
46 |
47 |
48 | @end
49 |
50 | @interface AtkDragAndDropManager : NSObject
51 |
52 | extern NSString *const AtkPasteboardNameDragAndDrop;
53 |
54 | /**
55 | * The AtkDDragAndDropManager delegate.
56 | */
57 | @property (nonatomic, weak) id delegate;
58 |
59 | /**
60 | * The pastbaord name. Defaults to AtkPasteboardNameDragAndDrop which creates
61 | * a pastebaord unique to drag and drop. This may be changed to any unique name, including
62 | * the shared pastebaord.
63 | */
64 | @property (nonatomic, strong) NSString* pasteboardName;
65 |
66 | /**
67 | * Get the Drag and Drop pastebaord. The paasteboard is based on pasteboardName, which is configurable.
68 | */
69 | @property (weak, nonatomic, readonly) UIPasteboard* pasteboard;
70 |
71 | /**
72 | * The root UIView as set by the call to start:(UIView *) or the UIApplication keyWindow
73 | * by default. All the players in the drag and drop scenerio must be descendants of rootView.
74 | */
75 | - (UIView*)rootView;
76 |
77 | /**
78 | * Starts the drag and drop manager. This sets up the gesture recognizer and UIApplication keyWindow
79 | * as the rootView.
80 | */
81 | - (void)start;
82 |
83 | /**
84 | * Starts the drag and drop manager. This sets up the rootView.
85 | */
86 | - (void)start:(UIView *)rootView;
87 |
88 | /**
89 | * Starts the drag and drop manager. This sets up the gesture recognizer and the rootView.
90 | */
91 | - (void)start:(UIView *)rootView recognizerClass:(Class)recognizerClass;
92 |
93 | /**
94 | * Stops the drag and drop manager. Any gesture recognizer is removed. Any drag operation in progress is ended.
95 | * The recognizer and rootViews are set to nil.
96 | */
97 | - (void)stop;
98 |
99 | #pragma mark - Protected
100 |
101 | /**
102 | * Find the drag source by calling on the delegate. If the delegate does no implement findDragSource: then the default
103 | * delegate is used.
104 | */
105 | - (id)findDragSource:(UIGestureRecognizer *)recognizer;
106 |
107 | /**
108 | * Find the drop zones by calling on the delegate. If the delegate does no implement findDropZones: then the default
109 | * delegate is used.
110 | */
111 | - (NSArray *)findDropZones:(UIGestureRecognizer *)recognizer;
112 |
113 | /**
114 | * Determine if the drop zone is active. Typically active means that the touch point in the recognizer is over the drop zone.
115 | * Here (and/or in the delegate, it is possible to change that meaning)
116 | * If the delegate does no implement isDropZoneActive:recognizer: then the default delegate is used.
117 | */
118 | - (BOOL)isDropZoneActive:(id)dropZone recognizer:(UIGestureRecognizer *)recognizer;
119 |
120 | //
121 | // Notifications for the drag and drop lifecycle.
122 | //
123 |
124 | /**
125 | * Called when a drag has started but before searching for drop zones.
126 | * If overriding in a subclass the super method should be called to ensure proper functionality.
127 | */
128 | - (void)dragWillStart;
129 |
130 | /**
131 | * Called when a drag has started.
132 | * If overriding in a subclass the super method should be called to ensure proper functionality.
133 | */
134 | - (void)dragStarted;
135 |
136 | /**
137 | * Called when a drag has ended.
138 | * If overriding in a subclass the super method should be called to ensure proper functionality.
139 | */
140 | - (void)dragEnded;
141 |
142 | /**
143 | * Called when a drag has endtered a drop zone.
144 | * If overriding in a subclass the super method should be called to ensure proper functionality.
145 | */
146 | - (void)dragEntered:(id) dropZone point:(CGPoint)point;
147 |
148 | /**
149 | * Called when a drag has exited a drop zone.
150 | * If overriding in a subclass the super method should be called to ensure proper functionality.
151 | */
152 | - (void)dragExited:(id) dropZone point:(CGPoint)point;
153 |
154 | /**
155 | * Called when a drag has moved within a drop zone. Only called after dragEntered and before dragExited.
156 | * If overriding in a subclass the super method should be called to ensure proper functionality.
157 | */
158 | - (void)dragMoved:(id) dropZone point:(CGPoint)point;
159 |
160 | /**
161 | * Called when a drag is dropped onto a drop zone.
162 | * If overriding in a subclass the super method should be called to ensure proper functionality.
163 | */
164 | - (void)dragDropped:(id) dropZone point:(CGPoint)point;
165 |
166 | @end
167 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Asymptotik Drag and Drop
2 | =================
3 |
4 | iOS drag and drop toolkit with support for:
5 |
6 | * Drag Source and Drop Zones by either subclassing or wrapping UIView and subclasses
7 | * Drag shadow generation for UIView
8 | * UIScrollView drag target auto scrolling
9 | * AtkDragAndDropManager uses the delegate pattern to allow a wide varienty of drag and drop scenarios
10 | * Accepts any continuous UIGestureRecognizer class for drag recognition
11 | * Works with the UIPasteboard as a means of data passing for the drag and drop operation.
12 | * Complete set of lifecycle handlers.
13 |
14 | The current limitation to the library is that drag and drop takes place for objects that are associated with a common root view. In practice this simply limits draging across UIWindows. This library does not currently use ARC. I know. I know. But my motivation was a much bigger project that has not yet been converted.
15 |
16 | I wrote this because I needed drag and drop support and didn't find something out there that met all my needs. Please try it out and give me your feedback. I'm interested in making this pretty robust and will accept reasonable pull requests. If you want to do big changes, I'm open, but lets talk.
17 |
18 | Example
19 | --------
20 |
21 | The source base provides a few examples that use most of the features. Here is a simple example of setting up a scenario that uses most of the defaults.
22 |
23 | Here we have a UIView drag source.
24 |
25 | ```objective-c
26 |
27 | @interface AtkSampleOneDragSourceView
28 |
29 | @end
30 |
31 | @implementation AtkSampleOneDragSourceView
32 |
33 | - (BOOL)shouldDragStart:(AtkDragAndDropManager *)manager
34 | {
35 | return YES;
36 | }
37 |
38 | - (void)dragWillStart:(AtkDragAndDropManager *)manager
39 | {
40 | // This is called before any call to AtkDropZoneProtocol shouldDragStart.
41 | // It's a good place to setup data for that method to examine.
42 | manager.pasteboard.string = [NSString stringWithFormat:@"val-%ld", (long)self.tag];
43 | }
44 |
45 | @end
46 |
47 | ```
48 |
49 | Here we have a UIView drop zone.
50 |
51 | ```objective-c
52 |
53 | @interface AtkSampleOneDropZoneView
54 |
55 | @end
56 |
57 | @implementation AtkSampleOneDropZoneView
58 |
59 | - (BOOL)shouldDragStart:(AtkDragAndDropManager *)manager
60 | {
61 | // Yes, consider me for drags. Returning true here only
62 | // ensures that isInterested, dragStarted, and dragEnded will
63 | // be called.
64 | return YES;
65 | }
66 |
67 | - (BOOL)isInterested:(AtkDragAndDropManager *)manager
68 | {
69 | // If we return true here then dragEntered, dragExited, dragMoved and
70 | // dragDropped can be called.
71 | // So, let's see if we are interested in what's on the pasteboard.
72 | // For the example this is if the pastbaord string matches
73 | // a string made up from the views tag property.
74 |
75 | BOOL ret = NO;
76 | UIPasteboard *pastebaord = manager.pasteboard;
77 | NSString *interestedInString =
78 | [NSString stringWithFormat:@"val-%ld", (long)self.tag];
79 | if([interestedInString isEqualToString:pastebaord.string])
80 | ret = YES;
81 |
82 | return ret;
83 | }
84 |
85 | @end
86 |
87 | ```
88 |
89 | And finally, we have our UIViewController. This assumes the drag source and drop zones were layed out on the MySampleOneViewController in Interface Builder or some other means.
90 |
91 | ```objective-c
92 |
93 | @interface AtkSampleOneViewController : UIViewController
94 |
95 | @property (nonatomic, retain) AtkDragAndDropManager *dragAndDropManager;
96 |
97 | @end
98 |
99 | @implementation AtkSampleOneViewController
100 |
101 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
102 | {
103 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
104 | if (self) {
105 | [self initialize];
106 | }
107 | return self;
108 | }
109 |
110 | - (void)initialize
111 | {
112 | self.navigationItem.title = @"Sample One";
113 | //
114 | // By default the AtkDragAndDropManager uses the UIApplication key windows as
115 | // the rootView and a UIPanGestureRecognizer. However, these are configurable.
116 | // Notice there is no need to register the drag sources or drop zones. The
117 | // AtkDragAndDropManager will by default traverse the view hierarch and find them.
118 | // This behavior is also configurable through the AtkDragAndDropManager delegate.
119 | //
120 | self.dragAndDropManager = [[[AtkDragAndDropManager alloc] init] autorelease];
121 | // For the AtkDragAndDropManagerDelegate methods findDragSource: finrDropZones: and
122 | // isDropZoneActive:recognizer:, if we do not implement them here, the
123 | // relevant methods in AtkDefaultDragAndDropManagerDelegate will be called.
124 | // This gives us our reasonable defaults even if we want to capture drag and drop
125 | // events here.
126 | self.dragAndDropManager.delegate = self;
127 | }
128 |
129 | - (void)viewDidAppear:(BOOL)animated
130 | {
131 | [super viewDidAppear:animated];
132 | [self.dragAndDropManager start];
133 | }
134 |
135 | - (void)viewWillDisappear:(BOOL)animated
136 | {
137 | [self.dragAndDropManager stop];
138 | [super viewWillDisappear:animated];
139 | }
140 |
141 | /**
142 | * Called when a drag is dropped onto a drop zone.
143 | */
144 | - (void)dragDropped:(AtkDragAndDropManager *)manager
145 | dropZone:(id)dropZone
146 | point:(CGPoint)point
147 | {
148 | // The drag was dropped onto an interested AtkDropZoneProtocol. Do something with it.
149 | }
150 |
151 | @end
152 |
153 | ```
154 |
155 |
173 |
174 | ## Updates
175 |
176 | ### 0.2.1 -> 0.2.2
177 |
178 | * dragStarted lifecycle event is not called on DropZones that return YES to shouldDragStart.
179 | * Cleaned up examples.
180 |
181 | ### 0.2.0 -> 0.2.1
182 |
183 | * Fixed an issue in Sample 2 which caused a crash. This code was left in after the refactor from 0.1.0 -> 0.2.0 by mistake.
184 |
185 | ### 0.1.0 -> 0.2.0
186 |
187 | * added drag and drop handler methods to the AtkDragAndDropManagerDelegate.
188 | * added shouldDragStart to AtkDragSourceProtocol and AtkDropZoneProtocol. dragStarted no londer returns a boolean.
189 | * made all protocol methods optional. this allows for maximal flexability.
190 | * if a AtkDragAndDropManagerDelegate does not implement methods findDragSource: findDropZones: or isDropZoneActive:recognizer: we look to the AtkDefaultDragAndDropManagerDelegate.
191 | * added dragWillStart to AtkDragSourceProtocol. this is called before dragStarted and AtkDropZoneProtocol shouldDragStart and allows us to setup data for drop zones to look at in shouldDragStart so they can determine if they want to participate as a drop zone.
192 | * Updates to the examples and readme.
193 |
194 | ## Author
195 |
196 | Rick Boykin, rick.boykin@gmail.com
197 |
198 | ## License
199 |
200 | AtkDragAndDrop is available under the MIT license. See the LICENSE file for more info.
201 |
202 |
--------------------------------------------------------------------------------
/Examples/AtkDragAndDrop_Examples/Sample02/AtkSampleTwoViewController.xib:
--------------------------------------------------------------------------------
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 |
35 |
36 |
37 |
38 |
39 |
40 |
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 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
98 |
99 |
100 |
101 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
--------------------------------------------------------------------------------
/Examples/AtkDragAndDrop_Examples/Sample01/AtkSampleOneViewController.xib:
--------------------------------------------------------------------------------
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 |
35 |
36 |
37 |
38 |
39 |
40 |
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 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
--------------------------------------------------------------------------------
/Classes/UIScrollView+AtkDragAndDrop.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIScrollView+AtkDragAndDrop.m
3 | // Atkdrogen_DragAndDrop
4 | //
5 | // Created by Rick Boykin on 1/21/14.
6 | // Copyright (c) 2014 Asymptotik Limited. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "UIScrollView+AtkDragAndDrop.h"
11 | #import "AtkDragAndDropManager.h"
12 |
13 | static const void *AtkDragAndDropScrollViewPropertyHolderKey;
14 | static const CGFloat kAtkAutoScrollEdgeTolleranceDefault = 80.0;
15 | static const CGFloat kAtkAutoScrollMaxVelocityDefault = 4.0;
16 | static const CGFloat kAtkAutoScrollVelocityDefault = 0.1;
17 |
18 | @interface AtkDragAndDropScrollViewPropertyHolder : NSObject
19 | @property (nonatomic, assign) CGFloat autoScrollEdgeTollerance;
20 | @property (nonatomic, assign) CGFloat autoScrollVelocity;
21 | @property (nonatomic, assign) CGFloat autoScrollMaxVelocity;
22 | @property (nonatomic, assign) CGPoint autoScrollDragPinnedPoint;
23 | @property (nonatomic, assign) CGPoint autoScrollLastDragPoint;
24 | @property (nonatomic, strong) NSTimer *autoScrollTimer;
25 | @end
26 |
27 | @implementation AtkDragAndDropScrollViewPropertyHolder
28 |
29 | - (id)init
30 | {
31 | self = [super init];
32 | if(self)
33 | {
34 | self.autoScrollEdgeTollerance = kAtkAutoScrollEdgeTolleranceDefault;
35 | self.autoScrollVelocity = kAtkAutoScrollVelocityDefault;
36 | self.autoScrollMaxVelocity = kAtkAutoScrollMaxVelocityDefault;
37 | }
38 |
39 | return self;
40 | }
41 |
42 | @end
43 |
44 | @implementation UIScrollView (AtkDragAndDrop)
45 |
46 | - (CGFloat)autoScrollEdgeTollerance
47 | {
48 | CGFloat ret = kAtkAutoScrollEdgeTolleranceDefault;
49 | AtkDragAndDropScrollViewPropertyHolder *result = (AtkDragAndDropScrollViewPropertyHolder *)objc_getAssociatedObject(self, &AtkDragAndDropScrollViewPropertyHolderKey);
50 | if (result != nil) {
51 | ret = result.autoScrollEdgeTollerance;
52 | }
53 | return ret;
54 | }
55 |
56 | - (void)setAutoScrollEdgeTollerance:(CGFloat)autoScrollEdgeTollerance
57 | {
58 | AtkDragAndDropScrollViewPropertyHolder *result = (AtkDragAndDropScrollViewPropertyHolder *)objc_getAssociatedObject(self, &AtkDragAndDropScrollViewPropertyHolderKey);
59 | if (result == nil) {
60 | result = [[AtkDragAndDropScrollViewPropertyHolder alloc] init];
61 | objc_setAssociatedObject(self, &AtkDragAndDropScrollViewPropertyHolderKey, result, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
62 | }
63 |
64 | result.autoScrollEdgeTollerance = autoScrollEdgeTollerance;
65 | }
66 |
67 | - (CGFloat)autoScrollVelocity
68 | {
69 | CGFloat ret = kAtkAutoScrollVelocityDefault;
70 | AtkDragAndDropScrollViewPropertyHolder *result = (AtkDragAndDropScrollViewPropertyHolder *)objc_getAssociatedObject(self, &AtkDragAndDropScrollViewPropertyHolderKey);
71 | if (result != nil) {
72 | ret = result.autoScrollVelocity;
73 | }
74 | return ret;
75 | }
76 |
77 | - (void)setAutoScrollVelocity:(CGFloat)autoScrollVelocity
78 | {
79 | AtkDragAndDropScrollViewPropertyHolder *result = (AtkDragAndDropScrollViewPropertyHolder *)objc_getAssociatedObject(self, &AtkDragAndDropScrollViewPropertyHolderKey);
80 | if (result == nil) {
81 | result = [[AtkDragAndDropScrollViewPropertyHolder alloc] init];
82 | objc_setAssociatedObject(self, &AtkDragAndDropScrollViewPropertyHolderKey, result, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
83 | }
84 |
85 | result.autoScrollVelocity = autoScrollVelocity;
86 | }
87 |
88 | - (CGFloat)autoScrollMaxVelocity
89 | {
90 | CGFloat ret = kAtkAutoScrollMaxVelocityDefault;
91 | AtkDragAndDropScrollViewPropertyHolder *result = (AtkDragAndDropScrollViewPropertyHolder *)objc_getAssociatedObject(self, &AtkDragAndDropScrollViewPropertyHolderKey);
92 | if (result != nil) {
93 | ret = result.autoScrollMaxVelocity;
94 | }
95 | return ret;
96 | }
97 |
98 | - (void)setAutoScrollMaxVelocity:(CGFloat)autoScrollMaxVelocity
99 | {
100 | AtkDragAndDropScrollViewPropertyHolder *result = (AtkDragAndDropScrollViewPropertyHolder *)objc_getAssociatedObject(self, &AtkDragAndDropScrollViewPropertyHolderKey);
101 | if (result == nil) {
102 | result = [[AtkDragAndDropScrollViewPropertyHolder alloc] init];
103 | objc_setAssociatedObject(self, &AtkDragAndDropScrollViewPropertyHolderKey, result, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
104 | }
105 |
106 | result.autoScrollMaxVelocity = autoScrollMaxVelocity;
107 | }
108 |
109 | - (CGPoint)autoScrollDragPinnedPoint
110 | {
111 | CGPoint ret = CGPointZero;
112 | AtkDragAndDropScrollViewPropertyHolder *result = (AtkDragAndDropScrollViewPropertyHolder *)objc_getAssociatedObject(self, &AtkDragAndDropScrollViewPropertyHolderKey);
113 | if (result != nil) {
114 | ret = result.autoScrollDragPinnedPoint;
115 | }
116 | return ret;
117 | }
118 |
119 | - (void)setAutoScrollDragPinnedPoint:(CGPoint)autoScrollDragPinnedPoint
120 | {
121 | AtkDragAndDropScrollViewPropertyHolder *result = (AtkDragAndDropScrollViewPropertyHolder *)objc_getAssociatedObject(self, &AtkDragAndDropScrollViewPropertyHolderKey);
122 | if (result == nil) {
123 | result = [[AtkDragAndDropScrollViewPropertyHolder alloc] init];
124 | objc_setAssociatedObject(self, &AtkDragAndDropScrollViewPropertyHolderKey, result, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
125 | }
126 |
127 | result.autoScrollDragPinnedPoint = autoScrollDragPinnedPoint;
128 | }
129 |
130 | - (CGPoint)autoScrollLastDragPoint
131 | {
132 | CGPoint ret = CGPointZero;
133 | AtkDragAndDropScrollViewPropertyHolder *result = (AtkDragAndDropScrollViewPropertyHolder *)objc_getAssociatedObject(self, &AtkDragAndDropScrollViewPropertyHolderKey);
134 | if (result != nil) {
135 | ret = result.autoScrollLastDragPoint;
136 | }
137 | return ret;
138 | }
139 |
140 | - (void)setAutoScrollLastDragPoint:(CGPoint)autoScrollLastDragPoint
141 | {
142 | AtkDragAndDropScrollViewPropertyHolder *result = (AtkDragAndDropScrollViewPropertyHolder *)objc_getAssociatedObject(self, &AtkDragAndDropScrollViewPropertyHolderKey);
143 | if (result == nil) {
144 | result = [[AtkDragAndDropScrollViewPropertyHolder alloc] init];
145 | objc_setAssociatedObject(self, &AtkDragAndDropScrollViewPropertyHolderKey, result, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
146 | }
147 |
148 | result.autoScrollLastDragPoint = autoScrollLastDragPoint;
149 | }
150 |
151 | - (NSTimer *)autoScrollTimer
152 | {
153 | NSTimer *ret = nil;
154 | AtkDragAndDropScrollViewPropertyHolder *result = (AtkDragAndDropScrollViewPropertyHolder *)objc_getAssociatedObject(self, &AtkDragAndDropScrollViewPropertyHolderKey);
155 | if (result != nil) {
156 | ret = result.autoScrollTimer;
157 | }
158 | return ret;
159 | }
160 |
161 | - (void)setAutoScrollTimer:(NSTimer *)timer
162 | {
163 | AtkDragAndDropScrollViewPropertyHolder *result = (AtkDragAndDropScrollViewPropertyHolder *)objc_getAssociatedObject(self, &AtkDragAndDropScrollViewPropertyHolderKey);
164 | if (result == nil) {
165 | result = [[AtkDragAndDropScrollViewPropertyHolder alloc] init];
166 | objc_setAssociatedObject(self, &AtkDragAndDropScrollViewPropertyHolderKey, result, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
167 | }
168 |
169 | result.autoScrollTimer = timer;
170 | }
171 |
172 | /**
173 | * Given a point, this method calculates the scroll delta, or the amount the scroller should scroll
174 | * in both the x and y direction.
175 | */
176 | - (CGPoint)autoScrollDelta:(CGPoint)point
177 | {
178 | CGPoint delta = CGPointZero;
179 | CGFloat autoScrollEdgeTollerance = self.autoScrollEdgeTollerance;
180 | CGFloat autoScrollVelocity = self.autoScrollVelocity;
181 | CGPoint autoScrollDragPinnedPoint = self.autoScrollDragPinnedPoint;
182 | CGFloat autoScrollMaxVelocity = self.autoScrollMaxVelocity;
183 |
184 | if(point.x < autoScrollEdgeTollerance)
185 | {
186 | // Our point is on the left edge of the scroller, within the given tolerance
187 | // We want to pin a point (autoScrollDragPinnedPoint) if that pin point is 0 or the
188 | // new point is to the right of the old point. When the new point is to the right
189 | // we do not scroll to the left. If we have a pin point and the new point is to the
190 | // left of that pin point, we then scroll left. This consideration of
191 | // where the new point is in relation to the pin point prevent us from scrolling
192 | // when we enter the UIScrollView with a drag operation. We actually have to
193 | // move in the direction we want to scroll. This makes a much more user friendly
194 | // drag/scroll operation.
195 | if(autoScrollDragPinnedPoint.x == 0.0 || point.x > autoScrollDragPinnedPoint.x)
196 | {
197 | autoScrollDragPinnedPoint = CGPointMake(point.x, autoScrollDragPinnedPoint.y);
198 | }
199 | else
200 | {
201 | delta.x = (point.x - autoScrollDragPinnedPoint.x) * autoScrollVelocity;
202 | if(delta.x < -autoScrollMaxVelocity) delta.x = -autoScrollMaxVelocity;
203 | }
204 | }
205 | else if(point.x > (self.frame.size.width - autoScrollEdgeTollerance))
206 | {
207 | if(autoScrollDragPinnedPoint.x == 0.0 || point.x < autoScrollDragPinnedPoint.x)
208 | {
209 | autoScrollDragPinnedPoint = CGPointMake(point.x, autoScrollDragPinnedPoint.y);
210 | }
211 | else
212 | {
213 | delta.x = (point.x - autoScrollDragPinnedPoint.x) * autoScrollVelocity;
214 | if(delta.x > autoScrollMaxVelocity) delta.x = autoScrollMaxVelocity;
215 | }
216 | }
217 | else
218 | {
219 | // We are not in scroll teritory on the x axis. Reset the x pin to 0.0.
220 | autoScrollDragPinnedPoint = CGPointMake(0.0, autoScrollDragPinnedPoint.y);
221 | }
222 |
223 | if(delta.x != 0.0)
224 | {
225 | if(self.contentOffset.x + delta.x < 0.0)
226 | {
227 | delta.x = -self.contentOffset.x;
228 | }
229 | else
230 | {
231 | CGFloat maxOffset = self.contentSize.width - self.frame.size.width;
232 | if(maxOffset < 0.0)
233 | maxOffset = 0.0;
234 |
235 | if(self.contentOffset.x + delta.x > maxOffset)
236 | delta.x = maxOffset - self.contentOffset.x;
237 | }
238 | }
239 |
240 | if(point.y < autoScrollEdgeTollerance)
241 | {
242 | if(autoScrollDragPinnedPoint.y == 0.0 || point.y > autoScrollDragPinnedPoint.y)
243 | {
244 | autoScrollDragPinnedPoint = CGPointMake(autoScrollDragPinnedPoint.x, point.y);
245 | }
246 | else
247 | {
248 | delta.y = (point.y - autoScrollDragPinnedPoint.y) * autoScrollVelocity;
249 | if(delta.y < -autoScrollMaxVelocity) delta.y = -autoScrollMaxVelocity;
250 | }
251 | }
252 | else if(point.y > (self.frame.size.height - autoScrollEdgeTollerance))
253 | {
254 | if(autoScrollDragPinnedPoint.y == 0.0 || point.y < autoScrollDragPinnedPoint.y)
255 | {
256 | autoScrollDragPinnedPoint = CGPointMake(autoScrollDragPinnedPoint.x, point.y);
257 | }
258 | else
259 | {
260 | delta.y = (point.y - autoScrollDragPinnedPoint.y) * autoScrollVelocity;
261 | if(delta.y > autoScrollMaxVelocity) delta.y = autoScrollMaxVelocity;
262 | }
263 | }
264 | else
265 | {
266 | autoScrollDragPinnedPoint = CGPointMake(autoScrollDragPinnedPoint.x, 0.0);
267 | }
268 |
269 | if(delta.y != 0.0)
270 | {
271 | if(self.contentOffset.y + delta.y < 0.0)
272 | {
273 | delta.y = -self.contentOffset.y;
274 | }
275 | else
276 | {
277 | CGFloat maxOffset = self.contentSize.height - self.frame.size.height;
278 | if(maxOffset < 0.0)
279 | maxOffset = 0.0;
280 |
281 | if(self.contentOffset.y + delta.y > maxOffset)
282 | delta.y = maxOffset - self.contentOffset.y;
283 | }
284 | }
285 |
286 | if(delta.x < 0.000001 && delta.x > -0.000001)
287 | delta.x = 0.0;
288 |
289 | if(delta.y < 0.000001 && delta.y > -0.000001)
290 | delta.y = 0.0;
291 |
292 | self.autoScrollDragPinnedPoint = autoScrollDragPinnedPoint;
293 |
294 | return delta;
295 | }
296 |
297 | - (void)autoScrollDragStarted
298 | {
299 | self.autoScrollDragPinnedPoint = CGPointZero;
300 | }
301 |
302 | - (void)autoScrollDragMoved:(CGPoint)point
303 | {
304 | //NSLog(@"AtkSampleOneDropZoneScrollView.dragMoved");
305 |
306 | CGPoint offset = self.contentOffset;
307 | NSTimer *autoScrollTimer = self.autoScrollTimer;
308 |
309 | //
310 | // iOS wants to convert the point to the content and not the UIScrollView frame. This
311 | // converts to the UIScrollView frame. Silly iOS.
312 | //
313 | point = CGPointMake(point.x - offset.x, point.y - offset.y);
314 | self.autoScrollLastDragPoint = point;
315 |
316 | if(autoScrollTimer)
317 | return;
318 |
319 | CGPoint autoScrollDelta = [self autoScrollDelta:point];
320 |
321 | if(!CGPointEqualToPoint(autoScrollDelta, CGPointZero))
322 | {
323 | CGPoint p = self.contentOffset;
324 | p.x += autoScrollDelta.x;
325 | p.y += autoScrollDelta.y;
326 |
327 | [self setContentOffset:p animated:NO];
328 |
329 | if(autoScrollTimer == nil)
330 | self.autoScrollTimer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(autoScrollTimerTick:) userInfo:nil repeats:YES];
331 | }
332 | else if(autoScrollTimer)
333 | {
334 | [autoScrollTimer invalidate];
335 | self.autoScrollTimer = nil;
336 | }
337 | }
338 |
339 | - (void)autoScrollDragEnded
340 | {
341 | if(self.autoScrollTimer)
342 | {
343 | [self.autoScrollTimer invalidate];
344 | self.autoScrollTimer = nil;
345 | }
346 | }
347 |
348 | - (void)autoScrollTimerTick:(NSTimer *)timer
349 | {
350 | CGPoint autoScrollDelta = [self autoScrollDelta:self.autoScrollLastDragPoint];
351 |
352 | if(!CGPointEqualToPoint(autoScrollDelta, CGPointZero))
353 | {
354 | CGPoint p = self.contentOffset;
355 | p.x += autoScrollDelta.x;
356 | p.y += autoScrollDelta.y;
357 |
358 | [self setContentOffset:p animated:NO];
359 | }
360 | else if(self.autoScrollTimer)
361 | {
362 | [self.autoScrollTimer invalidate];
363 | self.autoScrollTimer = nil;
364 | }
365 | }
366 |
367 | @end
368 |
--------------------------------------------------------------------------------
/Classes/AtkDragAndDropManager.m:
--------------------------------------------------------------------------------
1 | //
2 | // AtkDragAndDropManager.m
3 | // AtkDragAndDrop
4 | //
5 | // Created by Rick Boykin on 1/17/14.
6 | // Copyright (c) 2014 Asymptotik Limited. All rights reserved.
7 | //
8 |
9 | #import "AtkDragAndDropManager.h"
10 | #import "UIView+AtkDragAndDrop.h"
11 | #import "AtkDropZoneProtocol.h"
12 | #import "AtkDropZoneWrapper.h"
13 | #import "AtkDefaultDragAndDropManagerDelegate.h"
14 |
15 | @interface AtkDragAndDropManager ()
16 |
17 | @property (nonatomic, strong) UIView *rootView;
18 | @property (nonatomic, strong) id dragSource;
19 | @property (nonatomic, assign) CGPoint locationOffset;
20 | @property (nonatomic, strong) UIView *dragShadowView;
21 | @property (nonatomic, strong) UIPanGestureRecognizer *recognizer;
22 | @property (nonatomic, strong) NSArray *uninterestedDropZones;
23 | @property (nonatomic, strong) NSArray *interestedDropZones;
24 | @property (nonatomic, strong) id defaultDelegate;
25 |
26 | @end
27 |
28 | @implementation AtkDragAndDropManager
29 |
30 | NSString *const AtkPasteboardNameDragAndDrop = @"com.comcast.bcv.draganddrop.pasteboard";
31 |
32 | - (id)init
33 | {
34 | if((self = [super init]))
35 | {
36 | self.pasteboardName = AtkPasteboardNameDragAndDrop;
37 | }
38 |
39 | return self;
40 | }
41 |
42 | - (void)dealloc
43 | {
44 | self.dragSource = nil;
45 | self.dragShadowView = nil;
46 |
47 | }
48 |
49 | - (void)start
50 | {
51 | //NSLog(@"AtkDragAndDropManager.start");
52 |
53 | [self start:[[UIApplication sharedApplication] keyWindow]];
54 | }
55 |
56 | - (void)start:(UIView *)rootView
57 | {
58 | //NSLog(@"AtkDragAndDropManager.start:");
59 | [self start:rootView recognizerClass:[UIPanGestureRecognizer class]];
60 | }
61 |
62 | - (void)start:(UIView *)rootView recognizerClass:(Class)recognizerClass
63 | {
64 | //NSLog(@"AtkDragAndDropManager.start:recognizerClass: %@", [recognizerClass description]);
65 |
66 | assert([recognizerClass isSubclassOfClass:[UIGestureRecognizer class]]);
67 |
68 | if(_rootView)
69 | [self stop];
70 |
71 | if(rootView)
72 | {
73 |
74 | self.rootView = rootView;
75 | self.recognizer = [[recognizerClass alloc] initWithTarget:self action:@selector(handleGesture:)];
76 | self.recognizer.delegate = self;
77 | [self.rootView addGestureRecognizer:self.recognizer];
78 | }
79 | }
80 |
81 | - (void)stop
82 | {
83 | if(self.recognizer && self.rootView)
84 | {
85 | [self.rootView removeGestureRecognizer:self.recognizer];
86 | }
87 |
88 | if(self.dragSource)
89 | {
90 | [self onDragEnded:nil];
91 | }
92 |
93 | self.recognizer = nil;
94 | self.rootView = nil;
95 | }
96 |
97 | - (UIPasteboard *)pasteboard
98 | {
99 | return [UIPasteboard pasteboardWithName:self.pasteboardName create:YES];
100 | }
101 |
102 | - (id)findDragSource:(UIGestureRecognizer *)recognizer
103 | {
104 | if(_delegate && [_delegate respondsToSelector:@selector(findDragSource:recognizer:)])
105 | return [_delegate findDragSource:self recognizer:recognizer];
106 | else
107 | return [self.defaultDelegate findDragSource:self recognizer:recognizer];
108 | }
109 |
110 | - (NSArray *)findDropZones:(UIGestureRecognizer *)recognizer
111 | {
112 | if(_delegate && [_delegate respondsToSelector:@selector(findDropZones:recognizer:)])
113 | return [_delegate findDropZones:self recognizer:recognizer];
114 | else
115 | return [self.defaultDelegate findDropZones:self recognizer:recognizer];
116 | }
117 |
118 | - (BOOL)isDropZoneActive:(id)dropZone recognizer:(UIGestureRecognizer *)recognizer
119 | {
120 | if(_delegate && [_delegate respondsToSelector:@selector(isDropZoneActive:dropZone:recognizer:)])
121 | return [_delegate isDropZoneActive:self dropZone:dropZone recognizer:recognizer];
122 | else
123 | return [self.defaultDelegate isDropZoneActive:self dropZone:dropZone recognizer:recognizer];
124 | }
125 |
126 | - (void)dragWillStart
127 | {
128 | if([self.dragSource respondsToSelector:@selector(dragWillStart:)])
129 | [self.dragSource dragWillStart:self];
130 |
131 | if(_delegate && [_delegate respondsToSelector:@selector(dragWillStart:)])
132 | [_delegate dragWillStart:self];
133 | }
134 |
135 | - (void)dragStarted
136 | {
137 | for(AtkDropZoneWrapper *dropZone in self.uninterestedDropZones)
138 | {
139 | if([dropZone.dropZone respondsToSelector:@selector(dropZoneDragStarted:)])
140 | [dropZone.dropZone dropZoneDragStarted:self];
141 | }
142 |
143 | for(AtkDropZoneWrapper *dropZone in self.interestedDropZones)
144 | {
145 | if([dropZone.dropZone respondsToSelector:@selector(dropZoneDragStarted:)])
146 | [dropZone.dropZone dropZoneDragStarted:self];
147 | }
148 |
149 | if([self.dragSource respondsToSelector:@selector(dragStarted:)])
150 | [self.dragSource dragStarted:self];
151 |
152 | if(_delegate && [_delegate respondsToSelector:@selector(dragStarted:)])
153 | [_delegate dragStarted:self];
154 | }
155 |
156 | - (void)dragEnded
157 | {
158 | for(AtkDropZoneWrapper *dropZone in self.uninterestedDropZones)
159 | {
160 | if([dropZone.dropZone respondsToSelector:@selector(dropZoneDragEnded:)])
161 | [dropZone.dropZone dropZoneDragEnded:self];
162 | }
163 |
164 | for(AtkDropZoneWrapper *dropZone in self.interestedDropZones)
165 | {
166 | if([dropZone.dropZone respondsToSelector:@selector(dropZoneDragEnded:)])
167 | [dropZone.dropZone dropZoneDragEnded:self];
168 | }
169 |
170 | if([self.dragSource respondsToSelector:@selector(dragEnded:)])
171 | [self.dragSource dragEnded:self];
172 |
173 | if(_delegate && [_delegate respondsToSelector:@selector(dragEnded:)])
174 | [_delegate dragEnded:self];
175 | }
176 |
177 | - (void)dragEntered:(id)dropZone point:(CGPoint)point
178 | {
179 | if([dropZone respondsToSelector:@selector(dropZoneDragEntered:point:)])
180 | [dropZone dropZoneDragEntered:self point:point];
181 |
182 | if([self.dragSource respondsToSelector:@selector(dragEntered:dropZone:point:)])
183 | [self.dragSource dragEntered:self dropZone:dropZone point:point];
184 |
185 | if(_delegate && [_delegate respondsToSelector:@selector(dragEntered:dropZone:point:)])
186 | [_delegate dragEntered:self dropZone:dropZone point:point];
187 | }
188 |
189 | - (void)dragExited:(id)dropZone point:(CGPoint)point
190 | {
191 | if([dropZone respondsToSelector:@selector(dropZoneDragExited:point:)])
192 | [dropZone dropZoneDragExited:self point:point];
193 |
194 | if([self.dragSource respondsToSelector:@selector(dragExited:dropZone:point:)])
195 | [self.dragSource dragExited:self dropZone:dropZone point:point];
196 |
197 | if(_delegate && [_delegate respondsToSelector:@selector(dragExited:dropZone:point:)])
198 | [_delegate dragExited:self dropZone:dropZone point:point];
199 | }
200 |
201 | - (void)dragMoved:(id)dropZone point:(CGPoint)point
202 | {
203 | if([dropZone respondsToSelector:@selector(dropZoneDragMoved:point:)])
204 | [dropZone dropZoneDragMoved:self point:point];
205 |
206 | if([self.dragSource respondsToSelector:@selector(dragMoved:dropZone:point:)])
207 | [self.dragSource dragMoved:self dropZone:dropZone point:point];
208 |
209 | if(_delegate && [_delegate respondsToSelector:@selector(dragMoved:dropZone:point:)])
210 | [_delegate dragMoved:self dropZone:dropZone point:point];
211 | }
212 |
213 | - (void)dragDropped:(id)dropZone point:(CGPoint)point
214 | {
215 | if([dropZone respondsToSelector:@selector(dropZoneDragDropped:point:)])
216 | [dropZone dropZoneDragDropped:self point:point];
217 |
218 | if([self.dragSource respondsToSelector:@selector(dragDropped:dropZone:point:)])
219 | [self.dragSource dragDropped:self dropZone:dropZone point:point];
220 |
221 | if(_delegate && [_delegate respondsToSelector:@selector(dragDropped:dropZone:point:)])
222 | [_delegate dragDropped:self dropZone:dropZone point:point];
223 | }
224 |
225 | #pragma mark - private methods
226 |
227 | /**
228 | * Sets the drag source.
229 | */
230 | - (void)setDragSource:(id)dragSource
231 | {
232 | if(_dragSource != dragSource)
233 | {
234 | _dragSource = dragSource;
235 |
236 | if(_dragSource)
237 | {
238 | if([_dragSource respondsToSelector:@selector(createDragShadowView:)])
239 | self.dragShadowView = [_dragSource createDragShadowView:self];
240 | else if([_dragSource respondsToSelector:@selector(createDefaultDragShadowView:)])
241 | self.dragShadowView = [_dragSource performSelector:@selector(createDefaultDragShadowView:) withObject:self];
242 | }
243 | else
244 | {
245 | self.dragShadowView = nil;
246 | }
247 | }
248 | }
249 |
250 | /**
251 | * Sets the drag shadow view.
252 | */
253 | - (void)setDragShadowView:(UIView *)view
254 | {
255 | if(_dragShadowView != view)
256 | {
257 | if(_dragShadowView)
258 | {
259 | [_dragShadowView removeFromSuperview];
260 | }
261 |
262 | _dragShadowView = view;
263 |
264 | if(_dragShadowView)
265 | {
266 | [self.rootView addSubview:_dragShadowView];
267 | }
268 | }
269 | }
270 |
271 | - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)recognizer
272 | {
273 | //NSLog(@"AtkDragAndDropManager:gestureRecognizerShouldBegin");
274 | // Only begin if we have a dragSource.
275 | return [self onDragStart:recognizer];
276 | }
277 |
278 | /**
279 | * Handles the gesture.
280 | */
281 | - (IBAction)handleGesture:(UIPanGestureRecognizer *)recognizer
282 | {
283 | switch(recognizer.state)
284 | {
285 | case UIGestureRecognizerStateBegan:
286 | break;
287 | case UIGestureRecognizerStateChanged:
288 | if(_dragSource)
289 | {
290 | [self onDragMoved:recognizer];
291 | }
292 | break;
293 | case UIGestureRecognizerStateEnded: // same as UIGestureRecognizerStateRecognized
294 | if(_dragSource)
295 | {
296 | [self onDragDropped:recognizer];
297 | [self onDragEnded:recognizer];
298 | }
299 | break;
300 | case UIGestureRecognizerStateCancelled:
301 | if(_dragSource)
302 | {
303 | //NSLog(@"UIGestureRecognizerStateCancelled");
304 | [self onDragEnded:recognizer];
305 | }
306 | break;
307 | case UIGestureRecognizerStateFailed:
308 | if(_dragSource)
309 | {
310 | //NSLog(@"UIGestureRecognizerStateFailed");
311 | [self onDragEnded:recognizer];
312 | }
313 | break;
314 | case UIGestureRecognizerStatePossible:
315 | //NSLog(@"UIGestureRecognizerStatePossible");
316 | break;
317 | }
318 | }
319 |
320 | /**
321 | * Checks the movement of the recognizer and determines wheather and dropZones change their active status.
322 | */
323 | - (void)checkMovement:(UIGestureRecognizer *)recognizer
324 | {
325 | CGPoint pointInRootView = [recognizer locationInView:self.rootView];
326 |
327 | for(AtkDropZoneWrapper *dropZone in self.interestedDropZones)
328 | {
329 | if([self isDropZoneActive:dropZone.dropZone recognizer:recognizer])
330 | {
331 | if(!dropZone.isActive)
332 | {
333 | // transitioned to inside
334 | dropZone.isActive = YES;
335 |
336 | [self dragEntered:dropZone.dropZone point:pointInRootView];
337 | }
338 | else
339 | {
340 | [self dragMoved:dropZone.dropZone point:pointInRootView];
341 | }
342 | }
343 | else if(dropZone.isActive)
344 | {
345 | // transitioned to outside
346 | dropZone.isActive = NO;
347 | [self dragExited:dropZone.dropZone point:pointInRootView];
348 | }
349 | }
350 | }
351 |
352 | /**
353 | * Called when a drag operation starts. Returns true if a self.dragSource was set indicating
354 | * that a drag source was found and dragging will commence.
355 | */
356 | - (BOOL)onDragStart:(UIGestureRecognizer *)recognizer
357 | {
358 | //NSLog(@"AtkDragAndDropManager.dragStart");
359 |
360 | self.dragShadowView = nil;
361 | self.interestedDropZones = nil;
362 | self.uninterestedDropZones = nil;
363 |
364 | if((self.dragSource = [self findDragSource:recognizer]))
365 | {
366 | [self dragWillStart];
367 |
368 | NSArray *dropZones = [self findDropZones:recognizer];
369 |
370 | // Wrap the drop zones with AtkDropZoneWrapper to track it's state.
371 | NSMutableArray *interestedDropZones = nil;
372 | NSMutableArray *uninterestedDropZones = nil;
373 |
374 | if(dropZones)
375 | {
376 | for(id dropZone in dropZones)
377 | {
378 | if([dropZone respondsToSelector:@selector(dropZoneIsInterested:)] && [dropZone dropZoneIsInterested:self])
379 | {
380 | if(!interestedDropZones)
381 | interestedDropZones = [NSMutableArray arrayWithCapacity:[dropZones count]];
382 | [interestedDropZones addObject:[[AtkDropZoneWrapper alloc] initWithDropZone:dropZone interested:YES]];
383 | }
384 | else
385 | {
386 | if(!uninterestedDropZones)
387 | uninterestedDropZones = [NSMutableArray arrayWithCapacity:[dropZones count]];
388 | [uninterestedDropZones addObject:[[AtkDropZoneWrapper alloc] initWithDropZone:dropZone interested:NO]];
389 | }
390 | }
391 | }
392 |
393 | self.interestedDropZones = interestedDropZones;
394 | self.uninterestedDropZones = uninterestedDropZones;
395 |
396 | [self dragStarted];
397 | self.locationOffset = [recognizer locationInView:self.rootView];
398 | [self positionDragShadow:recognizer];
399 | }
400 |
401 | return _dragSource == nil ? NO : YES;
402 | }
403 |
404 | /**
405 | * Called when a drag operation ends.
406 | */
407 | - (void)onDragEnded:(UIGestureRecognizer *)recognizer
408 | {
409 | //NSLog(@"AtkDragAndDropManager.dragEnded");
410 |
411 | [self dragEnded];
412 |
413 | self.dragShadowView = nil;
414 | self.dragSource = nil;
415 | self.interestedDropZones = nil;
416 | self.uninterestedDropZones = nil;
417 | }
418 |
419 | /**
420 | * Called when a drag moves.
421 | */
422 | - (void)onDragMoved:(UIGestureRecognizer *)recognizer
423 | {
424 | //NSLog(@"AtkDragAndDropManager.dragMoved");
425 |
426 | [self checkMovement:recognizer];
427 | [self positionDragShadow:recognizer];
428 | }
429 |
430 | /**
431 | * Called when a drag is dropped.
432 | */
433 | - (void)onDragDropped:(UIGestureRecognizer *)recognizer
434 | {
435 | //NSLog(@"AtkDragAndDropManager.dragDropped");
436 |
437 | for(NSInteger n = [self.interestedDropZones count] - 1; n >= 0; n--)
438 | {
439 | AtkDropZoneWrapper *interestedDropZone = [self.interestedDropZones objectAtIndex:n];
440 | if(interestedDropZone.isActive)
441 | [self dragDropped:interestedDropZone.dropZone point:[recognizer locationInView:self.rootView]];
442 | }
443 | }
444 |
445 | /**
446 | * Positions the drag shadow.
447 | */
448 | - (void)positionDragShadow:(UIGestureRecognizer *)recognizer
449 | {
450 | if(_dragShadowView)
451 | {
452 | CGPoint point = [recognizer locationInView:self.rootView];
453 | CGRect frame = _dragShadowView.frame;
454 |
455 | CGPoint offset = CGPointMake(point.x - self.locationOffset.x, point.y - self.locationOffset.y);
456 | //NSLog(@"offset %f %f frame %f %f", offset.x, offset.y, frame.origin.x, frame.origin.y);
457 |
458 | frame.origin = CGPointMake(offset.x + frame.origin.x, offset.y + frame.origin.y);
459 | self.locationOffset = point;
460 | _dragShadowView.frame = frame;
461 | }
462 | }
463 |
464 | - (id)defaultDelegate
465 | {
466 | if(!_defaultDelegate)
467 | {
468 | self.defaultDelegate = [[AtkDefaultDragAndDropManagerDelegate alloc] init];
469 | }
470 |
471 | return _defaultDelegate;
472 | }
473 |
474 | - (void)setDelegate:(id)delegate
475 | {
476 | if(_delegate != delegate)
477 | {
478 | _delegate = delegate;
479 | }
480 |
481 | if(_delegate)
482 | self.defaultDelegate = nil;
483 | }
484 |
485 | @end
486 |
--------------------------------------------------------------------------------
/Examples/AtkDragAndDrop_Examples.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 1D0A2DA5189848D000175F59 /* AtkSampleViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D0A2D8F189848D000175F59 /* AtkSampleViewController.m */; };
11 | 1D0A2DA6189848D000175F59 /* AtkSampleViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1D0A2D90189848D000175F59 /* AtkSampleViewController.xib */; };
12 | 1D0A2DA7189848D000175F59 /* AtkSampleOneDragSourceView.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D0A2D93189848D000175F59 /* AtkSampleOneDragSourceView.m */; };
13 | 1D0A2DA8189848D000175F59 /* AtkSampleOneDropZoneScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D0A2D95189848D000175F59 /* AtkSampleOneDropZoneScrollView.m */; };
14 | 1D0A2DA9189848D000175F59 /* AtkSampleOneDropZoneView.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D0A2D97189848D000175F59 /* AtkSampleOneDropZoneView.m */; };
15 | 1D0A2DAA189848D000175F59 /* AtkSampleOneViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D0A2D99189848D000175F59 /* AtkSampleOneViewController.m */; };
16 | 1D0A2DAB189848D000175F59 /* AtkSampleOneViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1D0A2D9A189848D000175F59 /* AtkSampleOneViewController.xib */; };
17 | 1D0A2DAC189848D000175F59 /* AtkSampleTwoDragSourceWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D0A2D9D189848D000175F59 /* AtkSampleTwoDragSourceWrapper.m */; };
18 | 1D0A2DAD189848D000175F59 /* AtkSampleTwoDropZoneScrollViewWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D0A2D9F189848D000175F59 /* AtkSampleTwoDropZoneScrollViewWrapper.m */; };
19 | 1D0A2DAE189848D000175F59 /* AtkSampleTwoDropZoneWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D0A2DA1189848D000175F59 /* AtkSampleTwoDropZoneWrapper.m */; };
20 | 1D0A2DAF189848D000175F59 /* AtkSampleTwoViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D0A2DA3189848D000175F59 /* AtkSampleTwoViewController.m */; };
21 | 1D0A2DB0189848D000175F59 /* AtkSampleTwoViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1D0A2DA4189848D000175F59 /* AtkSampleTwoViewController.xib */; };
22 | 1D847C3A1898471E00F419F6 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D847C391898471E00F419F6 /* Foundation.framework */; };
23 | 1D847C3C1898471E00F419F6 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D847C3B1898471E00F419F6 /* CoreGraphics.framework */; };
24 | 1D847C3E1898471E00F419F6 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D847C3D1898471E00F419F6 /* UIKit.framework */; };
25 | 1D847C441898471E00F419F6 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 1D847C421898471E00F419F6 /* InfoPlist.strings */; };
26 | 1D847C461898471E00F419F6 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D847C451898471E00F419F6 /* main.m */; };
27 | 1D847C4A1898471E00F419F6 /* AtkAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D847C491898471E00F419F6 /* AtkAppDelegate.m */; };
28 | 1D847C4C1898471E00F419F6 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1D847C4B1898471E00F419F6 /* Images.xcassets */; };
29 | 1DE3C72118988AD2002C1C4E /* AtkDefaultDragAndDropManagerDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1DE3C71318988AD2002C1C4E /* AtkDefaultDragAndDropManagerDelegate.m */; };
30 | 1DE3C72218988AD2002C1C4E /* AtkDragAndDropManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1DE3C71618988AD2002C1C4E /* AtkDragAndDropManager.m */; };
31 | 1DE3C72318988AD2002C1C4E /* AtkDropZoneWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 1DE3C71A18988AD2002C1C4E /* AtkDropZoneWrapper.m */; };
32 | 1DE3C72418988AD2002C1C4E /* UIScrollView+AtkDragAndDrop.m in Sources */ = {isa = PBXBuildFile; fileRef = 1DE3C71C18988AD2002C1C4E /* UIScrollView+AtkDragAndDrop.m */; };
33 | 1DE3C72518988AD2002C1C4E /* UIView+AtkDragAndDrop.m in Sources */ = {isa = PBXBuildFile; fileRef = 1DE3C71E18988AD2002C1C4E /* UIView+AtkDragAndDrop.m */; };
34 | 1DE3C72618988AD2002C1C4E /* UIView+AtkImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 1DE3C72018988AD2002C1C4E /* UIView+AtkImage.m */; };
35 | /* End PBXBuildFile section */
36 |
37 | /* Begin PBXFileReference section */
38 | 1D0928B418B0827B00ACDAE7 /* AtkDragAndDrop.podspec */ = {isa = PBXFileReference; lastKnownFileType = text; name = AtkDragAndDrop.podspec; path = ../AtkDragAndDrop.podspec; sourceTree = ""; };
39 | 1D0A2D8E189848D000175F59 /* AtkSampleViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AtkSampleViewController.h; sourceTree = ""; };
40 | 1D0A2D8F189848D000175F59 /* AtkSampleViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AtkSampleViewController.m; sourceTree = ""; };
41 | 1D0A2D90189848D000175F59 /* AtkSampleViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = AtkSampleViewController.xib; sourceTree = ""; };
42 | 1D0A2D92189848D000175F59 /* AtkSampleOneDragSourceView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AtkSampleOneDragSourceView.h; sourceTree = ""; };
43 | 1D0A2D93189848D000175F59 /* AtkSampleOneDragSourceView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AtkSampleOneDragSourceView.m; sourceTree = ""; };
44 | 1D0A2D94189848D000175F59 /* AtkSampleOneDropZoneScrollView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AtkSampleOneDropZoneScrollView.h; sourceTree = ""; };
45 | 1D0A2D95189848D000175F59 /* AtkSampleOneDropZoneScrollView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AtkSampleOneDropZoneScrollView.m; sourceTree = ""; };
46 | 1D0A2D96189848D000175F59 /* AtkSampleOneDropZoneView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AtkSampleOneDropZoneView.h; sourceTree = ""; };
47 | 1D0A2D97189848D000175F59 /* AtkSampleOneDropZoneView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AtkSampleOneDropZoneView.m; sourceTree = ""; };
48 | 1D0A2D98189848D000175F59 /* AtkSampleOneViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AtkSampleOneViewController.h; sourceTree = ""; };
49 | 1D0A2D99189848D000175F59 /* AtkSampleOneViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AtkSampleOneViewController.m; sourceTree = ""; };
50 | 1D0A2D9A189848D000175F59 /* AtkSampleOneViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = AtkSampleOneViewController.xib; sourceTree = ""; };
51 | 1D0A2D9C189848D000175F59 /* AtkSampleTwoDragSourceWrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AtkSampleTwoDragSourceWrapper.h; sourceTree = ""; };
52 | 1D0A2D9D189848D000175F59 /* AtkSampleTwoDragSourceWrapper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AtkSampleTwoDragSourceWrapper.m; sourceTree = ""; };
53 | 1D0A2D9E189848D000175F59 /* AtkSampleTwoDropZoneScrollViewWrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AtkSampleTwoDropZoneScrollViewWrapper.h; sourceTree = ""; };
54 | 1D0A2D9F189848D000175F59 /* AtkSampleTwoDropZoneScrollViewWrapper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AtkSampleTwoDropZoneScrollViewWrapper.m; sourceTree = ""; };
55 | 1D0A2DA0189848D000175F59 /* AtkSampleTwoDropZoneWrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AtkSampleTwoDropZoneWrapper.h; sourceTree = ""; };
56 | 1D0A2DA1189848D000175F59 /* AtkSampleTwoDropZoneWrapper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AtkSampleTwoDropZoneWrapper.m; sourceTree = ""; };
57 | 1D0A2DA2189848D000175F59 /* AtkSampleTwoViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AtkSampleTwoViewController.h; sourceTree = ""; };
58 | 1D0A2DA3189848D000175F59 /* AtkSampleTwoViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AtkSampleTwoViewController.m; sourceTree = ""; };
59 | 1D0A2DA4189848D000175F59 /* AtkSampleTwoViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = AtkSampleTwoViewController.xib; sourceTree = ""; };
60 | 1D29A2861910639D0053E0F4 /* AtkDragAndDropLifecycleProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AtkDragAndDropLifecycleProtocol.h; sourceTree = ""; };
61 | 1D847C361898471E00F419F6 /* AtkDragAndDrop_Examples.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AtkDragAndDrop_Examples.app; sourceTree = BUILT_PRODUCTS_DIR; };
62 | 1D847C391898471E00F419F6 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
63 | 1D847C3B1898471E00F419F6 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
64 | 1D847C3D1898471E00F419F6 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
65 | 1D847C411898471E00F419F6 /* AtkDragAndDrop_Examples-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "AtkDragAndDrop_Examples-Info.plist"; sourceTree = ""; };
66 | 1D847C431898471E00F419F6 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; };
67 | 1D847C451898471E00F419F6 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
68 | 1D847C471898471E00F419F6 /* AtkDragAndDrop_Examples-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "AtkDragAndDrop_Examples-Prefix.pch"; sourceTree = ""; };
69 | 1D847C481898471E00F419F6 /* AtkAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AtkAppDelegate.h; sourceTree = ""; };
70 | 1D847C491898471E00F419F6 /* AtkAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AtkAppDelegate.m; sourceTree = ""; };
71 | 1D847C4B1898471E00F419F6 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; };
72 | 1DE3C71218988AD2002C1C4E /* AtkDefaultDragAndDropManagerDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AtkDefaultDragAndDropManagerDelegate.h; sourceTree = ""; };
73 | 1DE3C71318988AD2002C1C4E /* AtkDefaultDragAndDropManagerDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AtkDefaultDragAndDropManagerDelegate.m; sourceTree = ""; };
74 | 1DE3C71418988AD2002C1C4E /* AtkDragAndDrop.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AtkDragAndDrop.h; sourceTree = ""; };
75 | 1DE3C71518988AD2002C1C4E /* AtkDragAndDropManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AtkDragAndDropManager.h; sourceTree = ""; };
76 | 1DE3C71618988AD2002C1C4E /* AtkDragAndDropManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AtkDragAndDropManager.m; sourceTree = ""; };
77 | 1DE3C71718988AD2002C1C4E /* AtkDragSourceProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AtkDragSourceProtocol.h; sourceTree = ""; };
78 | 1DE3C71818988AD2002C1C4E /* AtkDropZoneProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AtkDropZoneProtocol.h; sourceTree = ""; };
79 | 1DE3C71918988AD2002C1C4E /* AtkDropZoneWrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AtkDropZoneWrapper.h; sourceTree = ""; };
80 | 1DE3C71A18988AD2002C1C4E /* AtkDropZoneWrapper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AtkDropZoneWrapper.m; sourceTree = ""; };
81 | 1DE3C71B18988AD2002C1C4E /* UIScrollView+AtkDragAndDrop.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIScrollView+AtkDragAndDrop.h"; sourceTree = ""; };
82 | 1DE3C71C18988AD2002C1C4E /* UIScrollView+AtkDragAndDrop.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIScrollView+AtkDragAndDrop.m"; sourceTree = ""; };
83 | 1DE3C71D18988AD2002C1C4E /* UIView+AtkDragAndDrop.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+AtkDragAndDrop.h"; sourceTree = ""; };
84 | 1DE3C71E18988AD2002C1C4E /* UIView+AtkDragAndDrop.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+AtkDragAndDrop.m"; sourceTree = ""; };
85 | 1DE3C71F18988AD2002C1C4E /* UIView+AtkImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+AtkImage.h"; sourceTree = ""; };
86 | 1DE3C72018988AD2002C1C4E /* UIView+AtkImage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+AtkImage.m"; sourceTree = ""; };
87 | 586968C86D4546FF8BBDD1E5 /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; };
88 | /* End PBXFileReference section */
89 |
90 | /* Begin PBXFrameworksBuildPhase section */
91 | 1D847C331898471E00F419F6 /* Frameworks */ = {
92 | isa = PBXFrameworksBuildPhase;
93 | buildActionMask = 2147483647;
94 | files = (
95 | 1D847C3C1898471E00F419F6 /* CoreGraphics.framework in Frameworks */,
96 | 1D847C3E1898471E00F419F6 /* UIKit.framework in Frameworks */,
97 | 1D847C3A1898471E00F419F6 /* Foundation.framework in Frameworks */,
98 | );
99 | runOnlyForDeploymentPostprocessing = 0;
100 | };
101 | /* End PBXFrameworksBuildPhase section */
102 |
103 | /* Begin PBXGroup section */
104 | 1D0A2D91189848D000175F59 /* Sample01 */ = {
105 | isa = PBXGroup;
106 | children = (
107 | 1D0A2D92189848D000175F59 /* AtkSampleOneDragSourceView.h */,
108 | 1D0A2D93189848D000175F59 /* AtkSampleOneDragSourceView.m */,
109 | 1D0A2D94189848D000175F59 /* AtkSampleOneDropZoneScrollView.h */,
110 | 1D0A2D95189848D000175F59 /* AtkSampleOneDropZoneScrollView.m */,
111 | 1D0A2D96189848D000175F59 /* AtkSampleOneDropZoneView.h */,
112 | 1D0A2D97189848D000175F59 /* AtkSampleOneDropZoneView.m */,
113 | 1D0A2D98189848D000175F59 /* AtkSampleOneViewController.h */,
114 | 1D0A2D99189848D000175F59 /* AtkSampleOneViewController.m */,
115 | 1D0A2D9A189848D000175F59 /* AtkSampleOneViewController.xib */,
116 | );
117 | path = Sample01;
118 | sourceTree = "";
119 | };
120 | 1D0A2D9B189848D000175F59 /* Sample02 */ = {
121 | isa = PBXGroup;
122 | children = (
123 | 1D0A2D9C189848D000175F59 /* AtkSampleTwoDragSourceWrapper.h */,
124 | 1D0A2D9D189848D000175F59 /* AtkSampleTwoDragSourceWrapper.m */,
125 | 1D0A2D9E189848D000175F59 /* AtkSampleTwoDropZoneScrollViewWrapper.h */,
126 | 1D0A2D9F189848D000175F59 /* AtkSampleTwoDropZoneScrollViewWrapper.m */,
127 | 1D0A2DA0189848D000175F59 /* AtkSampleTwoDropZoneWrapper.h */,
128 | 1D0A2DA1189848D000175F59 /* AtkSampleTwoDropZoneWrapper.m */,
129 | 1D0A2DA2189848D000175F59 /* AtkSampleTwoViewController.h */,
130 | 1D0A2DA3189848D000175F59 /* AtkSampleTwoViewController.m */,
131 | 1D0A2DA4189848D000175F59 /* AtkSampleTwoViewController.xib */,
132 | );
133 | path = Sample02;
134 | sourceTree = "";
135 | };
136 | 1D847C2D1898471E00F419F6 = {
137 | isa = PBXGroup;
138 | children = (
139 | 1D0928B418B0827B00ACDAE7 /* AtkDragAndDrop.podspec */,
140 | 1DE3C71118988AD2002C1C4E /* Classes */,
141 | 1D847C3F1898471E00F419F6 /* AtkDragAndDrop_Examples */,
142 | 1D847C381898471E00F419F6 /* Frameworks */,
143 | 1D847C371898471E00F419F6 /* Products */,
144 | );
145 | sourceTree = "";
146 | };
147 | 1D847C371898471E00F419F6 /* Products */ = {
148 | isa = PBXGroup;
149 | children = (
150 | 1D847C361898471E00F419F6 /* AtkDragAndDrop_Examples.app */,
151 | );
152 | name = Products;
153 | sourceTree = "";
154 | };
155 | 1D847C381898471E00F419F6 /* Frameworks */ = {
156 | isa = PBXGroup;
157 | children = (
158 | 1D847C391898471E00F419F6 /* Foundation.framework */,
159 | 1D847C3B1898471E00F419F6 /* CoreGraphics.framework */,
160 | 1D847C3D1898471E00F419F6 /* UIKit.framework */,
161 | 586968C86D4546FF8BBDD1E5 /* libPods.a */,
162 | );
163 | name = Frameworks;
164 | sourceTree = "";
165 | };
166 | 1D847C3F1898471E00F419F6 /* AtkDragAndDrop_Examples */ = {
167 | isa = PBXGroup;
168 | children = (
169 | 1D847C401898471E00F419F6 /* Supporting Files */,
170 | 1D0A2D91189848D000175F59 /* Sample01 */,
171 | 1D0A2D9B189848D000175F59 /* Sample02 */,
172 | 1D0A2D8E189848D000175F59 /* AtkSampleViewController.h */,
173 | 1D0A2D8F189848D000175F59 /* AtkSampleViewController.m */,
174 | 1D0A2D90189848D000175F59 /* AtkSampleViewController.xib */,
175 | 1D847C481898471E00F419F6 /* AtkAppDelegate.h */,
176 | 1D847C491898471E00F419F6 /* AtkAppDelegate.m */,
177 | 1D847C4B1898471E00F419F6 /* Images.xcassets */,
178 | );
179 | path = AtkDragAndDrop_Examples;
180 | sourceTree = "";
181 | };
182 | 1D847C401898471E00F419F6 /* Supporting Files */ = {
183 | isa = PBXGroup;
184 | children = (
185 | 1D847C411898471E00F419F6 /* AtkDragAndDrop_Examples-Info.plist */,
186 | 1D847C421898471E00F419F6 /* InfoPlist.strings */,
187 | 1D847C451898471E00F419F6 /* main.m */,
188 | 1D847C471898471E00F419F6 /* AtkDragAndDrop_Examples-Prefix.pch */,
189 | );
190 | name = "Supporting Files";
191 | sourceTree = "";
192 | };
193 | 1DE3C71118988AD2002C1C4E /* Classes */ = {
194 | isa = PBXGroup;
195 | children = (
196 | 1DE3C71218988AD2002C1C4E /* AtkDefaultDragAndDropManagerDelegate.h */,
197 | 1DE3C71318988AD2002C1C4E /* AtkDefaultDragAndDropManagerDelegate.m */,
198 | 1DE3C71418988AD2002C1C4E /* AtkDragAndDrop.h */,
199 | 1D29A2861910639D0053E0F4 /* AtkDragAndDropLifecycleProtocol.h */,
200 | 1DE3C71518988AD2002C1C4E /* AtkDragAndDropManager.h */,
201 | 1DE3C71618988AD2002C1C4E /* AtkDragAndDropManager.m */,
202 | 1DE3C71718988AD2002C1C4E /* AtkDragSourceProtocol.h */,
203 | 1DE3C71818988AD2002C1C4E /* AtkDropZoneProtocol.h */,
204 | 1DE3C71918988AD2002C1C4E /* AtkDropZoneWrapper.h */,
205 | 1DE3C71A18988AD2002C1C4E /* AtkDropZoneWrapper.m */,
206 | 1DE3C71B18988AD2002C1C4E /* UIScrollView+AtkDragAndDrop.h */,
207 | 1DE3C71C18988AD2002C1C4E /* UIScrollView+AtkDragAndDrop.m */,
208 | 1DE3C71D18988AD2002C1C4E /* UIView+AtkDragAndDrop.h */,
209 | 1DE3C71E18988AD2002C1C4E /* UIView+AtkDragAndDrop.m */,
210 | 1DE3C71F18988AD2002C1C4E /* UIView+AtkImage.h */,
211 | 1DE3C72018988AD2002C1C4E /* UIView+AtkImage.m */,
212 | );
213 | name = Classes;
214 | path = ../Classes;
215 | sourceTree = "";
216 | };
217 | /* End PBXGroup section */
218 |
219 | /* Begin PBXNativeTarget section */
220 | 1D847C351898471E00F419F6 /* AtkDragAndDrop_Examples */ = {
221 | isa = PBXNativeTarget;
222 | buildConfigurationList = 1D847C621898471F00F419F6 /* Build configuration list for PBXNativeTarget "AtkDragAndDrop_Examples" */;
223 | buildPhases = (
224 | 1D847C321898471E00F419F6 /* Sources */,
225 | 1D847C331898471E00F419F6 /* Frameworks */,
226 | 1D847C341898471E00F419F6 /* Resources */,
227 | );
228 | buildRules = (
229 | );
230 | dependencies = (
231 | );
232 | name = AtkDragAndDrop_Examples;
233 | productName = AtkDragAndDrop_Examples;
234 | productReference = 1D847C361898471E00F419F6 /* AtkDragAndDrop_Examples.app */;
235 | productType = "com.apple.product-type.application";
236 | };
237 | /* End PBXNativeTarget section */
238 |
239 | /* Begin PBXProject section */
240 | 1D847C2E1898471E00F419F6 /* Project object */ = {
241 | isa = PBXProject;
242 | attributes = {
243 | CLASSPREFIX = Atk;
244 | LastUpgradeCheck = 0510;
245 | ORGANIZATIONNAME = "Asymptotik Limited";
246 | };
247 | buildConfigurationList = 1D847C311898471E00F419F6 /* Build configuration list for PBXProject "AtkDragAndDrop_Examples" */;
248 | compatibilityVersion = "Xcode 3.2";
249 | developmentRegion = English;
250 | hasScannedForEncodings = 0;
251 | knownRegions = (
252 | en,
253 | );
254 | mainGroup = 1D847C2D1898471E00F419F6;
255 | productRefGroup = 1D847C371898471E00F419F6 /* Products */;
256 | projectDirPath = "";
257 | projectRoot = "";
258 | targets = (
259 | 1D847C351898471E00F419F6 /* AtkDragAndDrop_Examples */,
260 | );
261 | };
262 | /* End PBXProject section */
263 |
264 | /* Begin PBXResourcesBuildPhase section */
265 | 1D847C341898471E00F419F6 /* Resources */ = {
266 | isa = PBXResourcesBuildPhase;
267 | buildActionMask = 2147483647;
268 | files = (
269 | 1D0A2DA6189848D000175F59 /* AtkSampleViewController.xib in Resources */,
270 | 1D847C441898471E00F419F6 /* InfoPlist.strings in Resources */,
271 | 1D0A2DB0189848D000175F59 /* AtkSampleTwoViewController.xib in Resources */,
272 | 1D0A2DAB189848D000175F59 /* AtkSampleOneViewController.xib in Resources */,
273 | 1D847C4C1898471E00F419F6 /* Images.xcassets in Resources */,
274 | );
275 | runOnlyForDeploymentPostprocessing = 0;
276 | };
277 | /* End PBXResourcesBuildPhase section */
278 |
279 | /* Begin PBXSourcesBuildPhase section */
280 | 1D847C321898471E00F419F6 /* Sources */ = {
281 | isa = PBXSourcesBuildPhase;
282 | buildActionMask = 2147483647;
283 | files = (
284 | 1D0A2DA5189848D000175F59 /* AtkSampleViewController.m in Sources */,
285 | 1DE3C72418988AD2002C1C4E /* UIScrollView+AtkDragAndDrop.m in Sources */,
286 | 1DE3C72618988AD2002C1C4E /* UIView+AtkImage.m in Sources */,
287 | 1D0A2DA7189848D000175F59 /* AtkSampleOneDragSourceView.m in Sources */,
288 | 1D847C461898471E00F419F6 /* main.m in Sources */,
289 | 1D0A2DAA189848D000175F59 /* AtkSampleOneViewController.m in Sources */,
290 | 1D0A2DAE189848D000175F59 /* AtkSampleTwoDropZoneWrapper.m in Sources */,
291 | 1D0A2DAD189848D000175F59 /* AtkSampleTwoDropZoneScrollViewWrapper.m in Sources */,
292 | 1D0A2DA8189848D000175F59 /* AtkSampleOneDropZoneScrollView.m in Sources */,
293 | 1D0A2DAF189848D000175F59 /* AtkSampleTwoViewController.m in Sources */,
294 | 1D847C4A1898471E00F419F6 /* AtkAppDelegate.m in Sources */,
295 | 1DE3C72218988AD2002C1C4E /* AtkDragAndDropManager.m in Sources */,
296 | 1D0A2DAC189848D000175F59 /* AtkSampleTwoDragSourceWrapper.m in Sources */,
297 | 1DE3C72518988AD2002C1C4E /* UIView+AtkDragAndDrop.m in Sources */,
298 | 1DE3C72118988AD2002C1C4E /* AtkDefaultDragAndDropManagerDelegate.m in Sources */,
299 | 1D0A2DA9189848D000175F59 /* AtkSampleOneDropZoneView.m in Sources */,
300 | 1DE3C72318988AD2002C1C4E /* AtkDropZoneWrapper.m in Sources */,
301 | );
302 | runOnlyForDeploymentPostprocessing = 0;
303 | };
304 | /* End PBXSourcesBuildPhase section */
305 |
306 | /* Begin PBXVariantGroup section */
307 | 1D847C421898471E00F419F6 /* InfoPlist.strings */ = {
308 | isa = PBXVariantGroup;
309 | children = (
310 | 1D847C431898471E00F419F6 /* en */,
311 | );
312 | name = InfoPlist.strings;
313 | sourceTree = "";
314 | };
315 | /* End PBXVariantGroup section */
316 |
317 | /* Begin XCBuildConfiguration section */
318 | 1D847C601898471F00F419F6 /* Debug */ = {
319 | isa = XCBuildConfiguration;
320 | buildSettings = {
321 | ALWAYS_SEARCH_USER_PATHS = NO;
322 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
323 | CLANG_CXX_LIBRARY = "libc++";
324 | CLANG_ENABLE_MODULES = YES;
325 | CLANG_ENABLE_OBJC_ARC = YES;
326 | CLANG_WARN_BOOL_CONVERSION = YES;
327 | CLANG_WARN_CONSTANT_CONVERSION = YES;
328 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
329 | CLANG_WARN_EMPTY_BODY = YES;
330 | CLANG_WARN_ENUM_CONVERSION = YES;
331 | CLANG_WARN_INT_CONVERSION = YES;
332 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
333 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
334 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
335 | COPY_PHASE_STRIP = NO;
336 | GCC_C_LANGUAGE_STANDARD = gnu99;
337 | GCC_DYNAMIC_NO_PIC = NO;
338 | GCC_OPTIMIZATION_LEVEL = 0;
339 | GCC_PREPROCESSOR_DEFINITIONS = (
340 | "DEBUG=1",
341 | "$(inherited)",
342 | );
343 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
344 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
345 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
346 | GCC_WARN_UNDECLARED_SELECTOR = YES;
347 | GCC_WARN_UNINITIALIZED_AUTOS = YES;
348 | GCC_WARN_UNUSED_FUNCTION = YES;
349 | GCC_WARN_UNUSED_VARIABLE = YES;
350 | IPHONEOS_DEPLOYMENT_TARGET = 7.0;
351 | ONLY_ACTIVE_ARCH = YES;
352 | SDKROOT = iphoneos;
353 | };
354 | name = Debug;
355 | };
356 | 1D847C611898471F00F419F6 /* Release */ = {
357 | isa = XCBuildConfiguration;
358 | buildSettings = {
359 | ALWAYS_SEARCH_USER_PATHS = NO;
360 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
361 | CLANG_CXX_LIBRARY = "libc++";
362 | CLANG_ENABLE_MODULES = YES;
363 | CLANG_ENABLE_OBJC_ARC = YES;
364 | CLANG_WARN_BOOL_CONVERSION = YES;
365 | CLANG_WARN_CONSTANT_CONVERSION = YES;
366 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
367 | CLANG_WARN_EMPTY_BODY = YES;
368 | CLANG_WARN_ENUM_CONVERSION = YES;
369 | CLANG_WARN_INT_CONVERSION = YES;
370 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
371 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
372 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
373 | COPY_PHASE_STRIP = YES;
374 | ENABLE_NS_ASSERTIONS = NO;
375 | GCC_C_LANGUAGE_STANDARD = gnu99;
376 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
377 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
378 | GCC_WARN_UNDECLARED_SELECTOR = YES;
379 | GCC_WARN_UNINITIALIZED_AUTOS = YES;
380 | GCC_WARN_UNUSED_FUNCTION = YES;
381 | GCC_WARN_UNUSED_VARIABLE = YES;
382 | IPHONEOS_DEPLOYMENT_TARGET = 7.0;
383 | SDKROOT = iphoneos;
384 | VALIDATE_PRODUCT = YES;
385 | };
386 | name = Release;
387 | };
388 | 1D847C631898471F00F419F6 /* Debug */ = {
389 | isa = XCBuildConfiguration;
390 | buildSettings = {
391 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
392 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
393 | CLANG_ENABLE_OBJC_ARC = YES;
394 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
395 | GCC_PREFIX_HEADER = "AtkDragAndDrop_Examples/AtkDragAndDrop_Examples-Prefix.pch";
396 | INFOPLIST_FILE = "AtkDragAndDrop_Examples/AtkDragAndDrop_Examples-Info.plist";
397 | IPHONEOS_DEPLOYMENT_TARGET = 7.1;
398 | PRODUCT_NAME = "$(TARGET_NAME)";
399 | TARGETED_DEVICE_FAMILY = 1;
400 | WRAPPER_EXTENSION = app;
401 | };
402 | name = Debug;
403 | };
404 | 1D847C641898471F00F419F6 /* Release */ = {
405 | isa = XCBuildConfiguration;
406 | buildSettings = {
407 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
408 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
409 | CLANG_ENABLE_OBJC_ARC = YES;
410 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
411 | GCC_PREFIX_HEADER = "AtkDragAndDrop_Examples/AtkDragAndDrop_Examples-Prefix.pch";
412 | INFOPLIST_FILE = "AtkDragAndDrop_Examples/AtkDragAndDrop_Examples-Info.plist";
413 | IPHONEOS_DEPLOYMENT_TARGET = 7.1;
414 | PRODUCT_NAME = "$(TARGET_NAME)";
415 | TARGETED_DEVICE_FAMILY = 1;
416 | WRAPPER_EXTENSION = app;
417 | };
418 | name = Release;
419 | };
420 | /* End XCBuildConfiguration section */
421 |
422 | /* Begin XCConfigurationList section */
423 | 1D847C311898471E00F419F6 /* Build configuration list for PBXProject "AtkDragAndDrop_Examples" */ = {
424 | isa = XCConfigurationList;
425 | buildConfigurations = (
426 | 1D847C601898471F00F419F6 /* Debug */,
427 | 1D847C611898471F00F419F6 /* Release */,
428 | );
429 | defaultConfigurationIsVisible = 0;
430 | defaultConfigurationName = Release;
431 | };
432 | 1D847C621898471F00F419F6 /* Build configuration list for PBXNativeTarget "AtkDragAndDrop_Examples" */ = {
433 | isa = XCConfigurationList;
434 | buildConfigurations = (
435 | 1D847C631898471F00F419F6 /* Debug */,
436 | 1D847C641898471F00F419F6 /* Release */,
437 | );
438 | defaultConfigurationIsVisible = 0;
439 | defaultConfigurationName = Release;
440 | };
441 | /* End XCConfigurationList section */
442 | };
443 | rootObject = 1D847C2E1898471E00F419F6 /* Project object */;
444 | }
445 |
--------------------------------------------------------------------------------