A robust drag-and-drop framework for iOS.

Overview

#  BetweenKit

Build Status Coverage Status

###Overview

BetweenKit is a robust framework, built on UIKit that allows you to build drag-and-drop functionallity into your iOS application user interfaces.

BetweenKit is based on the concepts of the original i3-dragndrop helper, re-engineered from the ground up.

Check out the website and documentation for more.

###Features

  • Easy to integrate: aims to work smoothly alongside Apple's built in UI components.

  • Rich 'drag and drop' abstraction: abstracts away the gory details of gesture handling to provide a series of high-level 'drop/drop'-like events: drag starting, rearranging, deleting, dropping, etc.

  • Fully extensible: customize everything from the drag/drop properties of individual items in a collection, to how the various drag/drop events are rendered on-screen. SOLID design of its core components gives you the flexibillity to inject, extend, override, conform and take control.

  • Fully tested: ~100% unit test coverage, 20 functional use case applications, used in [production applications](Docs/Production Cases.md) on the App Store. It also comes bundled with a few test utilities to make it easier for contributors to write clean unit tests.

  • Fully documented: full written documentation, extensive inline comments and example code provided in the 20 use cases.

  • Reliable: tried, tested, refined, re-tried and re-tested once more.

###License

BetweenKit is licensed under the MIT License. See here.

Comments
  • NSKeyedUnarchiver error

    NSKeyedUnarchiver error

    Hello,

    In (UIView_) copyOfView:(UIView_) viewToCopy function { ...

    NSData* viewCopyData = [NSKeyedArchiver archivedDataWithRootObject:viewToCopy];
        UIView* viewCopy = [NSKeyedUnarchiver unarchiveObjectWithData:viewCopyData];
    

    ... } , i am having this issue: " [NSKeyedUnarchiver decodeBoolForKey:]: value for key (UIHighlighted) is not a boolean' ".... Its happening when i DOUBLE TAP on my item AND THEN try TO DRAG

    After little research, some people fixed the problem with unsetting Highlighted but its not working for me....

    Please, how i have to implement some double Tap function for ignoring double tap.

    opened by igorms-pro 29
  • Can't reorder - crashes

    Can't reorder - crashes

    I have followed the I32RearrangeableExchangeableTablesViewController and when I reorder it crashes. Assuming my fault but not sure where to start looking. Tried debugging but still not seeing clear root cause.

    I see it stating "This view probably hasn't received initWithFrame: or initWithCoder:" but not exactly sure what that means. My app was initially implemented back in 2011, so perhaps a version issue (ARC, or something to that effect).

    Here is the debugger output with error below.

    If you have any insights, would be much appreciated. This is a really great time saver for me. Thanks for putting it together and making it available.

    2014-03-10 17:27:38.949 Lacrosse-Stats[609:70b] Dragging from destination to destination. 2014-03-10 17:27:38.950 Lacrosse-Stats[609:70b] Rearrangeing dst 2014-03-10 17:27:42.128 Lacrosse-Stats[609:70b] *** 6) start isCellInDstAtIndexPathExchangable 2014-03-10 17:27:42.128 Lacrosse-Stats[609:70b] Cell row: 3 2014-03-10 17:27:42.144 Lacrosse-Stats[609:70b] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Requesting the window of a view (<UITableViewCell: 0xdca2e00; frame = (0 0; 0 0); transform = [0, 0, 0, 0, 0, 0]; text = '2 - Frick, Andrew'; alpha = 0; autoresize = W; layer = (null)>) with a nil layer. This view probably hasn't received initWithFrame: or initWithCoder:.' *** First throw call stack: ( 0 CoreFoundation 0x0389b5e4 exceptionPreprocess + 180 1 libobjc.A.dylib 0x02d898b6 objc_exception_throw + 44 2 CoreFoundation 0x0389b3bb +[NSException raise:format:] + 139 3 UIKit 0x01bb2f5b __windowForView + 467 4 UIKit 0x01bb52a0 -[UIView(Hierarchy) _postMovedFromSuperview:] + 28 5 UIKit 0x01bc04c1 -[UIView(Internal) _addSubview:positioned:relativeTo:] + 1847 6 UIKit 0x01bb39b1 -[UIView(Hierarchy) addSubview:] + 56 7 Lacrosse-Stats 0x00083d2f -[I3DragBetweenHelper animateDummyExchange:inContainer:withCompletionBlock:] + 879 8 Lacrosse-Stats 0x00088467 -[I3DragBetweenHelper handleDragFromDstStoppedInDstAtPoint:] + 1031 9 Lacrosse-Stats 0x00086949 -[I3DragBetweenHelper handleDragStopped:] + 1289 10 Lacrosse-Stats 0x0008623e -[I3DragBetweenHelper handlePan:] + 254 11 UIKit 0x01ed0e8c _UIGestureRecognizerSendActions + 230 12 UIKit 0x01ecfb00 -[UIGestureRecognizer _updateGestureWithEvent:buttonEvent:] + 383 13 UIKit 0x01ed156d -[UIGestureRecognizer _delayedUpdateGesture] + 60 14 UIKit 0x01ed4acd ___UIGestureRecognizerUpdate_block_invoke + 57 15 UIKit 0x01ed4a4e _UIGestureRecognizerRemoveObjectsFromArrayAndApplyBlocks + 317 16 UIKit 0x01ecb148 _UIGestureRecognizerUpdate + 199 17 UIKit 0x01b9719a -[UIWindow _sendGesturesForEvent:] + 1291 18 UIKit 0x01b980ba -[UIWindow sendEvent:] + 1030 19 UIKit 0x01b6be86 -[UIApplication sendEvent:] + 242 20 UIKit 0x01b5618f _UIApplicationHandleEventQueue + 11421 21 CoreFoundation 0x0382483f __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION + 15 22 CoreFoundation 0x038241cb __CFRunLoopDoSources0 + 235 23 CoreFoundation 0x0384129e __CFRunLoopRun + 910 24 CoreFoundation 0x03840ac3 CFRunLoopRunSpecific + 467 25 CoreFoundation 0x038408db CFRunLoopRunInMode + 123 26 GraphicsServices 0x037559e2 GSEventRunModal + 192 27 GraphicsServices 0x03755809 GSEventRun + 104 28 UIKit 0x01b58d3b UIApplicationMain + 1225 29 Lacrosse-Stats 0x0000300d main + 125 30 libdyld.dylib 0x03270701 start + 1 ) libc++abi.dylib: terminating with uncaught exception of type NSException (lldb)

    opened by cvconover 10
  • Delegate only allows for one delegate impl per class

    Delegate only allows for one delegate impl per class

    As the delegate protocol does not include a parameter for the helper class that sent the delegate message, there is no way of implementing delegates for multiple helpers in a single class. Here is an example of what we need:

    -(void) dragFromDstAtIndex:(NSIndexPath*) from toSrcAtIndex:(NSIndexPath*) to fromHelper:(I3DragBetweenHelper*) sender{
    
        if(sender == self.helper1){
    
           // Helper 1 impl
        }
        else if(sender == self.helper2){
    
          // Helper 2 impl
        }
    
    }
    

    ...vs what we have at the moment:

    -(void) dragFromDstAtIndex:(NSIndexPath*) from toSrcAtIndex:(NSIndexPath*) to{
    
        // How can I tell if this message was sent form helper1 or helper2?
    }
    

    This is currently being implemented in the delegate-refactor branch

    enhancement 
    opened by SteveFortune 9
  • Build 2.0.0 - BetweenKit

    Build 2.0.0 - BetweenKit

    Objectives

    The main objective for V2 is to act upon the feedback given thus far in order to bring the codebase from just a helper class to a proper user interface framework.

    • Testabillity
      • We now have active users and contributors. Automated tests will help us to review third party PRs, pick up regressions more easily, increase user confidence in the framework's stability and ultimately help standardise our maintenance approach.
      • We want all components of this framework to be coverable by unit tests. This will probably mean refactoring some core components to be more loosely coupled from UIKit in order to separate out the testable business logic.
      • For this release we will aim for 80% test coverage.
      • PRs from third parties must be covered my proper unit tests.
      • We will also endeavour to release some functional tests with the library, but unit tests are higher priority.
      • CI environment? Travis?
    • Integration
      • Apple provides some drag-drop-ability (UITableViewRow moveable and editable properties). This framework needs to work alongside, and integrate with, these vendor-provided features.
      • This is so that users can start using the library in applications that use the built-in UIKit features.
    • Help
      • People need more classes, provided by the framework, that help them meet their requirements.
      • Namely helpers for CoreData...
    • Documentation
      • Documentation around contribution, change-logs, etc, is lacking.
      • This will help to standardise third party contributions and general development practices, as well as providing more transparency for users of the framework.

    Plan

    Phase 1

    • Migrate the drag-n-drop routing logic into its own, isolated class
    • Allow for the gesture listener to be injected to this class
    • Create a manager-type class to register draggable components against and coordinate how the gesture recogniser is configured and injected
    • Should fix #5, #6, #14,
    • Should allow for #11
    • Should pave the way for #7, #16, #22

    Phase 2

    • Review the plan
    • #8
    • #23
    • #15
    • #12
    • #29

    Phase 3

    • Preview the plan
    • _TODO... _

    Timeframes

    Currently I am aiming to dedicate 1, 8 hour day per week to this project (probably on a Sunday).

    opened by SteveFortune 8
  • Allow drop on empty part of table

    Allow drop on empty part of table

    I thought it was not as intuitive to force the user to drop the first item at the very top on an empty table, so I made some mods that I think could improve the UX but I am not certain if there are any negative repercussions as I have not done extensive testing, yet, but so far it looks good. Here's what I did.

    In I3DragBetweenHelper, I commented out lines 792 - 797 (if nil check on drop index) https://github.com/ice3-software/i3-dragndrop/blob/master/Classes/I3DragBetweenHelper.m#L792

    Then in the delegate method, droppedOnDstAtIndexPath:to fromSrcIndexPath:from, I check for index==nil and just create a new NSIndexPath with row set to the size of the datasource of the target table. I have to do the same in the srcTable as I did in the dstTable, obviously.

    if (to == nil)
    {
        to = [NSIndexPath indexPathForRow:(self.dstDataSource.count) inSection:0];
    }
    

    Hope this can make it into your sources as feature if you see it as useful.

    opened by cvconover 8
  • Enable drag and drop into an empty VC

    Enable drag and drop into an empty VC

    Including nil drop indexes when a drop event occurs lets the user drag and drop a cell into an empty Collection/Table VC.

    I'm using the draggingView handler to detect when a cell is in a hover state over the destination view.

    opened by tcirwin 7
  • Custom UITableViewCell or UICollectionViewCell s key archive issue on iOS 6

    Custom UITableViewCell or UICollectionViewCell s key archive issue on iOS 6

    On iOS 6, if you subclass UITableViewCell or UICollectionViewCell and add subviews as properties to your custom cell they are issues with the duplicate dragging cell - the new subviews that you've added are usually not encoded/decoded for the duplicate dragging view. At present you must implement your own archiving mechanism in the subclass for your custom cell subviews.

    I will provide examples on how to do this shortly.

    bug wontfix 
    opened by SteveFortune 7
  • Must drag to side before dragging up or down to prevent table scroll

    Must drag to side before dragging up or down to prevent table scroll

    This might not be that big a deal but in my case, I don't want the tables to scroll with single touch. So I disable single finger/touch scroll and force 2 finger scrolling. This has a side effect of allowing drag in any direction to initiate the DnD.

    Just do the following in viewDidLoad: self.myLeftSideTable.panGestureRecognizer.minimumNumberOfTouches = 2;

    opened by cvconover 6
  • Can't DnD from src to a dst table with 0 items

    Can't DnD from src to a dst table with 0 items

    Once I have one item in the dst table, I can DnD without issue. But am unable to add that first item with DnD. I also cannot DnD a cell so that I drop it at the bottom of the table (as the last row in the table) - maybe related?

    Again, love this DnD solution. So easy to implement using your helper and example code. Kudos!

    opened by cvconover 6
  • Ability to rearrange without exchange

    Ability to rearrange without exchange

    Currently, rearrange swaps the drag indexPath with the drop indexPath. It would be useful if the DnD could be optionally configured to just reorder the all indexPaths above the drop by -1.

    opened by cvconover 5
  • NSKeyedArchiver archivedDataWithRootObject: crash

    NSKeyedArchiver archivedDataWithRootObject: crash

    While using this I3DragBetweenHelper code for rearranging rows in the same table view, app get crashed in the line (+[NSKeyedArchiver archivedDataWithRootObject:]) with exception as follows,

    NSConcreteAttributedString initWithString:: nil value SampleApp-[I3DragBetweenHelper copyOfView:] in I3DragBetweenHelper.m on Line 163

    0 CoreFoundation 0x2f277e8b exceptionPreprocess 1 libobjc.A.dylib 0x395726c7 objc_exception_throw 2 CoreFoundation 0x2f277dcd -[NSException initWithCoder:] 3 Foundation 0x2fba9f95 -[NSConcreteAttributedString initWithString:] 4 Foundation 0x2fba9e71 -[NSConcreteAttributedString initWithString:attributes:] 5 UIKit 0x31cf10e5 -[UILabel _attributedStringHasAttributesNotCoveredByPrimitives] 6 UIKit 0x31cf1475 -[UILabel encodeWithCoder:] 7 Foundation 0x2fbf2891 _encodeObject 8 Foundation 0x2fbf3a6f -[NSKeyedArchiver _encodeArrayOfObjects:forKey:] 9 Foundation 0x2fbf4045 -[NSArray(NSArray) encodeWithCoder:] 10 Foundation 0x2fbf2891 _encodeObject 11 UIKit 0x31c90151 -[UIView encodeWithCoder:] 12 Foundation 0x2fbf2891 _encodeObject 13 Foundation 0x2fbf3a6f -[NSKeyedArchiver _encodeArrayOfObjects:forKey:] 14 Foundation 0x2fbf4045 -[NSArray(NSArray) encodeWithCoder:] 15 Foundation 0x2fbf2891 _encodeObject 16 UIKit 0x31c90151 -[UIView encodeWithCoder:] 17 UIKit 0x31d41ced -[UITableViewCell encodeWithCoder:] 18 Foundation 0x2fbf2891 _encodeObject 19 Foundation 0x2fbf8cb1 +[NSKeyedArchiver archivedDataWithRootObject:] 20 SampleApp 0x00059b47 -[I3DragBetweenHelper copyOfView:] in I3DragBetweenHelper.m on Line 163 21 SampleApp 0x0005a50b -[I3DragBetweenHelper startDragFromView:atPoint:] in I3DragBetweenHelper.m on Line 346 22 SampleApp 0x0005b8bd -[I3DragBetweenHelper handleDragStartedInSrcAtPoint:] in I3DragBetweenHelper.m on Line 696 23 SampleApp 0x0005b23f -[I3DragBetweenHelper handleDragStarted:] in I3DragBetweenHelper.m on Line 583 24 SampleApp 0x0005b093 -[I3DragBetweenHelper handlePan:] in I3DragBetweenHelper.m on Line 528 25 UIKit 0x31b84171 _UIGestureRecognizerSendActions 26 UIKit 0x31a2e943 -[UIGestureRecognizer _updateGestureWithEvent:buttonEvent:] 27 UIKit 0x31db9437 ___UIGestureRecognizerUpdate_block_invoke 28 UIKit 0x319f57af _UIGestureRecognizerRemoveObjectsFromArrayAndApplyBlocks 29 UIKit 0x319f3f13 _UIGestureRecognizerUpdate 30 UIKit 0x31a2d1b5 -[UIWindow _sendGesturesForEvent:] 31 UIKit 0x31a2cb63 -[UIWindow sendEvent:] 32 UIKit 0x31a01f59 -[UIApplication sendEvent:] 33 SampleApp 0x000989cd -[UIApplication(InstabugApplication) InstabugSendEvent:] in InstabugSession.m on Line 42 34 UIKit 0x31a00747 _UIApplicationHandleEventQueue 35 CoreFoundation 0x2f242f27 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION 36 CoreFoundation 0x2f2423ef __CFRunLoopDoSources0 37 CoreFoundation 0x2f240bdf __CFRunLoopRun 38 CoreFoundation 0x2f1ab541 CFRunLoopRunSpecific 39 CoreFoundation 0x2f1ab323 CFRunLoopRunInMode 40 GraphicsServices 0x33ee22eb GSEventRunModal 41 UIKit 0x31a621e5 UIApplicationMain 42 SampleApp 0x00068137 main in main.m on Line 16 43 libdyld.dylib 0x39a6bab7 start

    Device used: iPhone 5 OS 7.0.2

    Please help on this issue.

    Thanks.

    opened by mykrr 4
  • Typo in Docs/Usage.md

    Typo in Docs/Usage.md

    Hello.

    https://github.com/ice3-software/between-kit/blob/master/Docs/Usage.md

    #import <BetweenKit/UITableView+I3Collection.h> #import <BetweenKit/I3DragArea.h>

    Gives error: 'BetweenKit/I3DragArea.h' file not found.

    #import <BetweenKit/UITableView+I3Collection.h> #import <BetweenKit/I3DragArena.h>

    Work correct.

    opened by ARGAMX 0
  • Get drag events while dragging.

    Get drag events while dragging.

    To get drag events while dragging, I used I3DragRenderDelegate. But after implementing the delegate, the snapshot view is not rendered. Why do I need to implement all the methods if I implement I3DragRenderDelegate? How will I get a snapshot view?

    opened by KalpeshTalkar 4
  • Consider removing numbering scheme from Use Cases

    Consider removing numbering scheme from Use Cases

    The numbering scheme was originally meant to achieve tutorial-like ordering. The ordering of difficulty can easily be expressed in the Getting Started doc.

    opened by SteveFortune 0
Owner
IceCube Software
Mobile and web apps for businesses.
IceCube Software
A Simple way help you drop or drag your source (like UIImage) between different App.

A Simple way help you drop or drag your source (like UIImage) between different App.

逸风 13 Nov 24, 2022
A Swift SPM framework for running and managing Lua code from Swift

LuaKit A Swift Package for running and managing Lua code from Swift. Documentation For documentation, add this package as Swift Package Dependency, an

GGorAA 5 Nov 24, 2022
ConfettiKit is a custom framework used to add Confetti on your iOS/iPadOS projects.

ConfettiKit is a custom framework used to add Confetti on your iOS/iPadOS projects. The kit provides variety of customisations inorder to design a confetti which matches your project's UI. ConfettiKit makes your work of adding Confetti on your project with just one line of code.

Gokul Nair 14 Sep 27, 2022
contoh pembuatan framework untuk ios swift

circularContohFramework Example To run the example project, clone the repo, and run pod install from the Example directory first. Requirements Install

null 0 Oct 31, 2021
How to develop an iOS 14 application with SwiftUI 2.0 framework. How to create an Onboarding Screen with Page Tab View

Ama-Fruits USER INTERFACE AND USER EXPERIENCE APP DESIGN How to develop an iOS 14 application with SwiftUI 2.0 framework. How to create an Onboarding

Noye Samuel 1 Dec 11, 2021
Start your next Open-Source Swift Framework 📦

SwiftKit enables you to easily generate a cross platform Swift Framework from your command line. It is the best way to start your next Open-Source Swi

Sven Tiigi 821 Dec 28, 2022
Easily generate cross platform Swift framework projects from the command line

SwiftPlate Easily generate cross platform Swift framework projects from the command line. SwiftPlate will generate Xcode projects for you in seconds,

John Sundell 1.8k Dec 27, 2022
A Swift wrapper around the CoreSymbolication private framework on macOS.

CoreSymbolication provides a very powerful system for looking up and extracting symbolic information from mach-o executables, dyld shared caches, and dSYMs.

Stacksift 7 Nov 21, 2022
A ARM macOS Virtual Machine, using macOS 12's new Virtualization framework.

macOS Virtual Machine A ARM macOS Virtual Machine, using macOS 12's new Virtualization framework. I copied KhaosT's code from here, all I did is chang

Ming Chang 127 Nov 30, 2022
Alchemy, an elegant, batteries included backend framework for Swift.

Elegant, batteries included web framework for Swift.

Alchemy 313 Jan 2, 2023
SandboxKit - Framework that makes it easy to launch a single Scene of your application

SandboxKit This framework makes debugging more efficient in your application. Sandbox is the name of a structure that improves the efficiency of debug

Aoi Okawa 10 Apr 24, 2022
The QuoteKit is a Swift framework to use the free APIs provided by Quotable created by Luke Peavey.

QuoteKit The QuoteKit is a Swift framework to use the free APIs provided by Quotable created by Luke Peavey. It uses the latest async/await syntax for

rryam 17 Jun 23, 2022
Useless tools for exploring Virtualization.framework

Tools for exploring the internals of Virtualization.framework's Mac virtualization support. I made this since I don't have an Apple Silicon Mac but st

null 18 Aug 9, 2022
A simple composition framework to create transformations that are either unidirectional or bidirectional

c is a simple composition framework. You have the ability to create transformations that are either unidirectional or bidirectional. There is also a cache that values can be set and resolved.

OpenBytes 4 May 10, 2022
A simple framework to output to a file, url, the console, or even register notification using UserNotifications

o is a simple framework to output to a file, url, the console, or even register notification using UserNotifications. o can also get input from a file, url, or console.

OpenBytes 4 Mar 18, 2022
Generic model framework

Pistachio Pistachio is a generic model framework. By leveraging lenses and value transformers, it allows you to create type safe adapters for any recu

Felix Visée 164 Jun 29, 2022
IBSKit - an Xcode Fat Framework written in Swift 5

IBSKit framework is designed to solve everyday tasks that any iOS developer faces when developing a new project.

IBS Mobile iOS 9 Nov 11, 2022
macOS Virtual Machine using Virtualization.framework

virtualOS Run a virtual macOS machine on your Apple Silicon computer. On first start, the latest macOS restore image is automatically downloaded from

null 102 Dec 24, 2022
Qiling Advanced Binary Emulation Framework

Qiling's usecase, blog and related work Qiling is an advanced binary emulation framework, with the following features: Emulate multi-platforms: Window

qiling.io 3.8k Jan 6, 2023