AtkDragAndDrop 0.2.2

AtkDragAndDrop 0.2.2

测试已测试
语言语言 Obj-CObjective C
许可证 MIT
发布最后发布2014年12月

未认领 维护。



  • Rick Boykin

Asymptotik Drag and Drop

iOS 拖拽工具包,支持

  • 通过子类化或封装 UIView 及其子类的方式实现拖拽源和拖拽区域
  • 为 UIView 生成拖拽阴影
  • UIScrollView 拖拽目标自动滚动
  • AtkDragAndDropManager 使用代理模式允许多种拖拽场景
  • 接受任何连续的 UIGestureRecognizer 类用于拖拽识别
  • 可通过 UIPasteboard 作为拖拽操作的数据传递方式
  • 完整的生命周期处理程序。

当前库的限制是拖拽操作发生在与常见根视图关联的对象上。在实际上,这仅仅限制了跨越 UIWindows 的拖拽。此库目前没有使用 ARC。我知道。我知道。但我的动机是一个更大的项目,该项目尚未转换。

我写了这个库,因为我需要拖拽支持,但没有找到满足所有需求的东西。请试用并给我反馈。我对使其更健壮很感兴趣,并将接受合理的拉取请求。如果您想进行重大更改,我可以开放,但让我们谈谈。

示例

源代码库提供了一些使用大多数功能的示例。以下是一个使用大多数默认设置的简单示例。

这里有一个 UIView 拖拽源。

@interface AtkSampleOneDragSourceView<AtkDragSourceProtocol>

@end

@implementation AtkSampleOneDragSourceView

- (BOOL)shouldDragStart:(AtkDragAndDropManager *)manager
{
    return YES;
}

- (void)dragWillStart:(AtkDragAndDropManager *)manager
{
    // This is called before any call to AtkDropZoneProtocol shouldDragStart. 
    // It's a good place to setup data for that method to examine.
    manager.pasteboard.string = [NSString stringWithFormat:@"val-%ld", (long)self.tag];
}

@end

这里有一个 UIView 拖拽区域。

@interface AtkSampleOneDropZoneView<AtkDropZoneProtocol>

@end

@implementation AtkSampleOneDropZoneView

- (BOOL)shouldDragStart:(AtkDragAndDropManager *)manager
{
    // Yes, consider me for drags. Returning true here only
    // ensures that isInterested, dragStarted, and dragEnded will
    // be called. 
    return YES;
}

- (BOOL)isInterested:(AtkDragAndDropManager *)manager
{
    // If we return true here then dragEntered, dragExited, dragMoved and 
    // dragDropped can be called.
    // So, let's see if we are interested in what's on the pasteboard.
    // For the example this is if the pastbaord string matches
    // a string made up from the views tag property.

    BOOL ret = NO;
    UIPasteboard *pastebaord = manager.pasteboard;
    NSString *interestedInString = 
             [NSString stringWithFormat:@"val-%ld", (long)self.tag];
    if([interestedInString isEqualToString:pastebaord.string])
        ret = YES;

    return ret;
}

@end

最后,我们有我们的 UIViewController。这假设拖拽源和拖拽区域已在 Interface Builder 或其他方式中布置在 MySampleOneViewController 上。

@interface AtkSampleOneViewController : UIViewController<AtkDragAndDropManagerDelegate>

@property (nonatomic, retain) AtkDragAndDropManager *dragAndDropManager;

@end

@implementation AtkSampleOneViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        [self initialize];
    }
    return self;
}

- (void)initialize
{
    self.navigationItem.title = @"Sample One";
    //
    // By default the AtkDragAndDropManager uses the UIApplication key windows as 
    // the rootView and a UIPanGestureRecognizer. However, these are configurable.
    // Notice there is no need to register the drag sources or drop zones. The
    // AtkDragAndDropManager will by default traverse the view hierarch and find them. 
    // This behavior is also configurable through the AtkDragAndDropManager delegate.
    //
    self.dragAndDropManager = [[[AtkDragAndDropManager alloc] init] autorelease];
    // For the AtkDragAndDropManagerDelegate methods findDragSource: finrDropZones: and
    // isDropZoneActive:recognizer:, if we do not implement them here, the 
    // relevant methods in AtkDefaultDragAndDropManagerDelegate will be called.
    // This gives us our reasonable defaults even if we want to capture drag and drop
    // events here.
    self.dragAndDropManager.delegate = self;
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    [self.dragAndDropManager start];
}

- (void)viewWillDisappear:(BOOL)animated
{
    [self.dragAndDropManager stop];
    [super viewWillDisappear:animated];
}

/**
 * Called when a drag is dropped onto a drop zone.
 */
- (void)dragDropped:(AtkDragAndDropManager *)manager
           dropZone:(id<AtkDropZoneProtocol>)dropZone 
              point:(CGPoint)point
{
   // The drag was dropped onto an interested AtkDropZoneProtocol. Do something with it.
}

@end

更新

0.2.1 -> 0.2.2

  • 当 DropZones 返回 YES 到 shouldDragStart 时,不会调用 dragStarted 生命周期事件。
  • 清理了示例。

0.2.0 -> 0.2.1

  • 修复了 Sample 2 中导致崩溃的问题。由于从 0.1.0 到 0.2.0 的重构错误,该代码被遗留在之后。

0.1.0 -> 0.2.0

  • 向 AtkDragAndDropManagerDelegate 添加了拖拽和放置处理方法。
  • 将 shouldDragStart 添加到 AtkDragSourceProtocol 和 AtkDropZoneProtocol。dragStarted 不再返回布尔值。
  • 所有的协议方法都是可选的,这提供了最大限度的灵活性。
  • 如果 AtkDragAndDropManagerDelegate 没有实现 findDragSource: findDropZones: 或 isDropZoneActive:recognizer: 方法,我们将查看 AtkDefaultDragAndDropManagerDelegate。
  • 向 AtkDragSourceProtocol 添加了 dragWillStart。这调用在 dragStarted 和 AtkDropZoneProtocol shouldDragStart 之前,允许我们设置在 shouldDragStart 中查看的拖拽区域的数据,以便它们可以确定是否想作为拖拽区域参与。
  • 更新了示例和README文件。

作者

Rick Boykin, [email protected]

许可

AtkDragAndDrop 在MIT许可下可用。更多详细信息请参阅LICENSE文件。