Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6099969
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 23, 20262026-05-23T13:19:59+00:00 2026-05-23T13:19:59+00:00

my question is, wether or not this is possible, and if so, how would

  • 0

my question is, wether or not this is possible, and if so, how would you approach this task?

Does anybody know of an app already using this functionality, or where to get some sample code?

Also, if i’m to implement this on my own without too much knowledge of the topic what would be your estimation on how long it would take to get it done?

One other thing to mention, since it could make things more complicated: The destination table is in editmode per default, so that the user can rearrange the cells (using the standard reordering control in accessory view), which have already been dropped there.

Edit:

I just tried to include a screenshot of a concept image in my post. The image shows one table on the left and a grayish drop area on the right. My customer says that he saw this on other apps, too, so there has to be some kind of ui element that I am not aware of.

I haven’t found anything in the developer library about such a drop area, so hopefully one of you can give me directions or clear things up.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-23T13:20:00+00:00Added an answer on May 23, 2026 at 1:20 pm

    Ok, I managed to implement this myself and I’m quite happy with the result. You can drag cells from left (source table) to right (destination table) and also drag cells within the destination table for reodering. If you try to drag a cell from right to left it will be reinserted at the same position where you started dragging (so nothing happens). The destination table also supports deletion of cells, the source table doesn’t. So here’s the complete code:

    UIDropTableViewController.h

    #import <UIKit/UIKit.h>
    
    @interface UIDropTableViewController : UIViewController <UITableViewDelegate, UITableViewDataSource, UIGestureRecognizerDelegate>
    {
        UINavigationItem*   srcTableNavItem;
        UINavigationItem*   dstTableNavItem;
    
        UITableView*        srcTableView;
        UITableView*        dstTableView;
        UITableViewCell*    draggedCell;
        UIView*             dropArea;
    
        NSMutableArray*     srcData;
        NSMutableArray*     dstData;
        id                  draggedData;
    
        BOOL            dragFromSource;     // used for reodering
        NSIndexPath*    pathFromDstTable;   // used to reinsert data when reodering fails
    }
    
    @property (nonatomic, readonly) NSArray* srcData;
    @property (nonatomic, readonly) NSArray* dstData;
    
    - (id)initWithFrame:(CGRect)frame SourceData:(NSArray*)sourceData DestinationData:(NSArray*)destinationData;
    
    - (void)setSrcTableTitle:(NSString*)title;
    - (void)setDstTableTitle:(NSString*)title;
    
    @end
    

    UIDropTableViewController.m

    #import "UIDropTableViewController.h"
    
    #define kCellIdentifier @"DropTableCell"
    #define kCellHeight 44
    #define kNavBarHeight 30
    
    
    // forward declaration of private helper methods
    @interface UIDropTableViewController()
    
    - (void)setupSourceTableWithFrame:(CGRect)frame;
    - (void)setupDestinationTableWithFrame:(CGRect)frame;
    - (void)initDraggedCellWithCell:(UITableViewCell*)cell AtPoint:(CGPoint)point;
    
    - (void)startDragging:(UIPanGestureRecognizer *)gestureRecognizer;
    - (void)startDraggingFromSrcAtPoint:(CGPoint)point;
    - (void)startDraggingFromDstAtPoint:(CGPoint)point;
    
    - (void)doDrag:(UIPanGestureRecognizer *)gestureRecognizer;
    - (void)stopDragging:(UIPanGestureRecognizer *)gestureRecognizer;
    
    - (UITableViewCell*)srcTableCellForRowAtIndexPath:(NSIndexPath*)indexPath;
    - (UITableViewCell*)dstTableCellForRowAtIndexPath:(NSIndexPath*)indexPath;
    
    @end
    
    
    @implementation UIDropTableViewController
    
    @synthesize srcData, dstData;
    
    #pragma mark -
    #pragma mark Public Methods
    
    - (void)setSrcTableTitle:(NSString*)title
    {
        srcTableNavItem.title = title;
    }
    
    - (void)setDstTableTitle:(NSString*)title
    {
        dstTableNavItem.title = title;
    }
    
    #pragma mark -
    #pragma mark UIViewController
    
    - (id)initWithFrame:(CGRect)frame SourceData:(NSArray*)sourceData DestinationData:(NSArray*)destinationData
    {
        self = [super init];
        if (self)
        {
            self.view.clipsToBounds = YES;
            self.view.frame = frame;
            int width = frame.size.width;
            int height = frame.size.height;
    
            // set up data
            srcData = [[NSMutableArray alloc] initWithArray:sourceData];
            dstData = [[NSMutableArray alloc] initWithArray:destinationData];
    
            draggedCell = nil;
            draggedData = nil;
            pathFromDstTable = nil;
    
            // set up views
            [self setupSourceTableWithFrame:CGRectMake(0, 0, width / 2, height)];
            [self setupDestinationTableWithFrame:CGRectMake(width / 2, 0, width / 2, height)];
    
            UIView* separator = [[UIView alloc] initWithFrame:CGRectMake(width / 2, 0, 1, height)];
            separator.backgroundColor = [UIColor blackColor];
            [self.view addSubview:separator];
            [separator release];
    
            // set up gestures
            UIPanGestureRecognizer* panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanning:)];
            [self.view addGestureRecognizer:panGesture];
            [panGesture release];
        }
        return self;
    }
    
    - (void)dealloc
    {
        [srcTableNavItem release];
        [dstTableNavItem release];
    
        [srcTableView release];
        [dstTableView release];
        [dropArea release];
    
        [srcData release];
        [dstData release];
    
        if(draggedCell != nil)
            [draggedCell release];
        if(draggedData != nil)
            [draggedData release];
        if(pathFromDstTable != nil)
            [pathFromDstTable release];
    
        [super dealloc];
    }
    
    - (void)viewWillAppear:(BOOL)animated
    {
        [srcTableView reloadData];
        [dstTableView reloadData];
    
        [UIView animateWithDuration:0.2 animations:^
         {
             CGRect frame = dstTableView.frame;
             frame.size.height = kCellHeight * [dstData count];
             dstTableView.frame = frame;
         }];
    }
    
    - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
    {
        // Return YES for supported orientations
        return UIInterfaceOrientationIsLandscape(interfaceOrientation);
    }
    
    #pragma mark -
    #pragma mark Helper methods for initialization
    
    - (void)setupSourceTableWithFrame:(CGRect)frame
    {
        srcTableNavItem = [[UINavigationItem alloc] init];
        srcTableNavItem.title = @"Source Table";
    
        CGRect navBarFrame = frame;
        navBarFrame.size.height = kNavBarHeight;
    
        UINavigationBar* navigationBar = [[UINavigationBar alloc] initWithFrame:navBarFrame];
        [navigationBar pushNavigationItem:srcTableNavItem animated:false];
        [navigationBar setTintColor:[UIColor lightGrayColor]];
        [self.view addSubview:navigationBar];
        [navigationBar release];
    
        CGRect tableFrame = frame;
        tableFrame.origin.y = kNavBarHeight;
        tableFrame.size.height -= kNavBarHeight;
    
        srcTableView = [[UITableView alloc] initWithFrame:tableFrame];
        [srcTableView setDelegate:self];
        [srcTableView setDataSource:self];
        [self.view addSubview:srcTableView];
    }
    
    - (void)setupDestinationTableWithFrame:(CGRect)frame
    {
        dstTableNavItem = [[UINavigationItem alloc] init];
        dstTableNavItem.title = @"Destination Table";
    
        CGRect navBarFrame = frame;
        navBarFrame.size.height = kNavBarHeight;
    
        UINavigationBar* navigationBar = [[UINavigationBar alloc] initWithFrame:navBarFrame];
        [navigationBar pushNavigationItem:dstTableNavItem animated:false];
        [navigationBar setTintColor:[UIColor lightGrayColor]];
        [self.view addSubview:navigationBar];
        [navigationBar release];
    
        CGRect dropAreaFrame = frame;
        dropAreaFrame.origin.y = kNavBarHeight;
        dropAreaFrame.size.height -= kNavBarHeight;
    
        dropArea = [[UIView alloc] initWithFrame:dropAreaFrame];
        [dropArea setBackgroundColor:[UIColor grayColor]];
        [self.view addSubview:dropArea];
    
        CGRect contentFrame = dropAreaFrame;
        contentFrame.origin = CGPointMake(0, 0);
    
        UILabel* dropAreaLabel = [[UILabel alloc] initWithFrame:contentFrame];
        dropAreaLabel.backgroundColor = [UIColor clearColor];
        dropAreaLabel.font = [UIFont boldSystemFontOfSize:12];
        dropAreaLabel.textAlignment = UITextAlignmentCenter;
        dropAreaLabel.textColor = [UIColor whiteColor];
        dropAreaLabel.text = @"Drop items here...";
        [dropArea addSubview:dropAreaLabel];
        [dropAreaLabel release];
    
        CGRect tableFrame = contentFrame;
        tableFrame.size.height = kCellHeight * [dstData count];
    
        dstTableView = [[UITableView alloc] initWithFrame:tableFrame];
        [dstTableView setEditing:YES];
        [dstTableView setDelegate:self];
        [dstTableView setDataSource:self];
        [dropArea addSubview:dstTableView];
    }
    
    - (void)initDraggedCellWithCell:(UITableViewCell*)cell AtPoint:(CGPoint)point
    {
        // get rid of old cell, if it wasn't disposed already
        if(draggedCell != nil)
        {
            [draggedCell removeFromSuperview];
            [draggedCell release];
            draggedCell = nil;
        }
    
        CGRect frame = CGRectMake(point.x, point.y, cell.frame.size.width, cell.frame.size.height);
    
        draggedCell = [[UITableViewCell alloc] init];
        draggedCell.selectionStyle = UITableViewCellSelectionStyleGray;
        draggedCell.textLabel.text = cell.textLabel.text;
        draggedCell.textLabel.textColor = cell.textLabel.textColor;
        draggedCell.highlighted = YES;
        draggedCell.frame = frame;
        draggedCell.alpha = 0.8;
    
        [self.view addSubview:draggedCell];
    }
    
    #pragma mark -
    #pragma mark UIGestureRecognizer
    
    - (void)handlePanning:(UIPanGestureRecognizer *)gestureRecognizer
    {
        switch ([gestureRecognizer state]) {
            case UIGestureRecognizerStateBegan:
                [self startDragging:gestureRecognizer];
                break;
            case UIGestureRecognizerStateChanged:
                [self doDrag:gestureRecognizer];
                break;
            case UIGestureRecognizerStateEnded:
            case UIGestureRecognizerStateCancelled:
            case UIGestureRecognizerStateFailed:
                [self stopDragging:gestureRecognizer];
                break;
            default:
                break;
        }
    }
    
    #pragma mark -
    #pragma mark Helper methods for dragging
    
    - (void)startDragging:(UIPanGestureRecognizer *)gestureRecognizer
    {
        CGPoint pointInSrc = [gestureRecognizer locationInView:srcTableView];
        CGPoint pointInDst = [gestureRecognizer locationInView:dstTableView];
    
        if([srcTableView pointInside:pointInSrc withEvent:nil])
        {
            [self startDraggingFromSrcAtPoint:pointInSrc];
            dragFromSource = YES;
        }
        else if([dstTableView pointInside:pointInDst withEvent:nil])
        {
            [self startDraggingFromDstAtPoint:pointInDst];
            dragFromSource = NO;
        }
    }
    
    - (void)startDraggingFromSrcAtPoint:(CGPoint)point
    {
        NSIndexPath* indexPath = [srcTableView indexPathForRowAtPoint:point];
        UITableViewCell* cell = [srcTableView cellForRowAtIndexPath:indexPath];
        if(cell != nil)
        {
            CGPoint origin = cell.frame.origin;
            origin.x += srcTableView.frame.origin.x;
            origin.y += srcTableView.frame.origin.y;
    
            [self initDraggedCellWithCell:cell AtPoint:origin];
            cell.highlighted = NO;
    
            if(draggedData != nil)
            {
                [draggedData release];
                draggedData = nil;
            }
            draggedData = [[srcData objectAtIndex:indexPath.row] retain];
        }
    }
    
    - (void)startDraggingFromDstAtPoint:(CGPoint)point
    {
        NSIndexPath* indexPath = [dstTableView indexPathForRowAtPoint:point];
        UITableViewCell* cell = [dstTableView cellForRowAtIndexPath:indexPath];
        if(cell != nil)
        {
            CGPoint origin = cell.frame.origin;
            origin.x += dropArea.frame.origin.x;
            origin.y += dropArea.frame.origin.y;
    
            [self initDraggedCellWithCell:cell AtPoint:origin];
            cell.highlighted = NO;
    
            if(draggedData != nil)
            {
                [draggedData release];
                draggedData = nil;
            }
            draggedData = [[dstData objectAtIndex:indexPath.row] retain];
    
            // remove old cell
            [dstData removeObjectAtIndex:indexPath.row];
            [dstTableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationMiddle];
            pathFromDstTable = [indexPath retain];
    
            [UIView animateWithDuration:0.2 animations:^
             {
                 CGRect frame = dstTableView.frame;
                 frame.size.height = kCellHeight * [dstData count];
                 dstTableView.frame = frame;
             }];
    
        }
    }
    
    - (void)doDrag:(UIPanGestureRecognizer *)gestureRecognizer
    {
        if(draggedCell != nil && draggedData != nil)
        {
            CGPoint translation = [gestureRecognizer translationInView:[draggedCell superview]];
                [draggedCell setCenter:CGPointMake([draggedCell center].x + translation.x,
                                                   [draggedCell center].y + translation.y)];
            [gestureRecognizer setTranslation:CGPointZero inView:[draggedCell superview]];
        }
    }
    
    - (void)stopDragging:(UIPanGestureRecognizer *)gestureRecognizer
    {
        if(draggedCell != nil && draggedData != nil)
        {
            if([gestureRecognizer state] == UIGestureRecognizerStateEnded
               && [dropArea pointInside:[gestureRecognizer locationInView:dropArea] withEvent:nil])
            {            
                NSIndexPath* indexPath = [dstTableView indexPathForRowAtPoint:[gestureRecognizer locationInView:dstTableView]];
                if(indexPath != nil)
                {
                    [dstData insertObject:draggedData atIndex:indexPath.row];
                    [dstTableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationMiddle];
                }
                else
                {
                    [dstData addObject:draggedData];
                    [dstTableView reloadData];
                }
            }
            else if(!dragFromSource && pathFromDstTable != nil)
            {
                // insert cell back where it came from
                [dstData insertObject:draggedData atIndex:pathFromDstTable.row];
                [dstTableView insertRowsAtIndexPaths:[NSArray arrayWithObject:pathFromDstTable] withRowAnimation:UITableViewRowAnimationMiddle];
    
                [pathFromDstTable release];
                pathFromDstTable = nil;
            }
    
            [UIView animateWithDuration:0.3 animations:^
             {
                 CGRect frame = dstTableView.frame;
                 frame.size.height = kCellHeight * [dstData count];
                 dstTableView.frame = frame;
             }];
    
            [draggedCell removeFromSuperview];
            [draggedCell release];
            draggedCell = nil;
    
            [draggedData release];
            draggedData = nil;
        }
    }
    
    #pragma mark -
    #pragma mark UITableViewDataSource
    
    - (BOOL)tableView:(UITableView*)tableView canMoveRowAtIndexPath:(NSIndexPath*)indexPath
    {
        // disable build in reodering functionality
        return NO;
    }
    
    - (void)tableView:(UITableView*)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
    {
        // enable cell deletion for destination table
        if([tableView isEqual:dstTableView] && editingStyle == UITableViewCellEditingStyleDelete)
        {
            [dstData removeObjectAtIndex:indexPath.row];
            [dstTableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
    
            [UIView animateWithDuration:0.2 animations:^
             {
                 CGRect frame = dstTableView.frame;
                 frame.size.height = kCellHeight * [dstData count];
                 dstTableView.frame = frame;
             }];
        }
    }
    
    - (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section
    {
        // tell our tables how many rows they will have
        int count = 0;
        if([tableView isEqual:srcTableView])
        {
            count = [srcData count];
        }
        else if([tableView isEqual:dstTableView])
        {
            count = [dstData count];
        }
        return count;
    }
    
    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        return kCellHeight;
    }
    
    - (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
    {
        UITableViewCell* result = nil;
        if([tableView isEqual:srcTableView])
        {
            result = [self srcTableCellForRowAtIndexPath:indexPath];
        }
        else if([tableView isEqual:dstTableView])
        {
            result = [self dstTableCellForRowAtIndexPath:indexPath];
        }
    
        return result;
    }
    
    #pragma mark -
    #pragma mark Helper methods for table stuff
    
    - (UITableViewCell*)srcTableCellForRowAtIndexPath:(NSIndexPath*)indexPath
    {
        // tell our source table what kind of cell to use and its title for the given row
        UITableViewCell *cell = [srcTableView dequeueReusableCellWithIdentifier:kCellIdentifier];
        if (cell == nil)
        {
            cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                           reuseIdentifier:kCellIdentifier] autorelease];
    
            cell.selectionStyle = UITableViewCellSelectionStyleNone;
            cell.textLabel.textColor = [UIColor darkGrayColor];
        }
        cell.textLabel.text = [[srcData objectAtIndex:indexPath.row] description];
    
        return cell;
    }
    
    - (UITableViewCell*)dstTableCellForRowAtIndexPath:(NSIndexPath*)indexPath
    {
        // tell our destination table what kind of cell to use and its title for the given row
        UITableViewCell *cell = [dstTableView dequeueReusableCellWithIdentifier:kCellIdentifier];
        if (cell == nil)
        {
            cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                           reuseIdentifier:kCellIdentifier] autorelease];
    
            cell.selectionStyle = UITableViewCellSelectionStyleNone;
            cell.textLabel.textColor = [UIColor darkGrayColor];
        }
        cell.textLabel.text = [[dstData objectAtIndex:indexPath.row] description];
    
        return cell;
    }
    
    @end
    

    Here is an example of how to use it:

    NSArray* srcData = [NSArray arrayWithObjects:@"item0", @"item1", @"item2", @"item3", @"item4", nil];
    NSArray* dstData = [NSArray arrayWithObjects:@"item5", @"item6", nil];
    
    dropTable = [[UIDropTableViewController alloc] initWithFrame:CGRectMake(100, 100, 600, 500) SourceData:srcData DestinationData:dstData];
    [dropTable setSrcTableTitle:@"Bla"];
    [dropTable setDstTableTitle:@"Blub"];
    [[dropTable.view layer] setBorderColor:[[UIColor darkGrayColor] CGColor]];
    [[dropTable.view layer] setBorderWidth:1];
    [[dropTable.view layer] setCornerRadius:2];
    [self.view addSubview:dropTable.view];
    

    Then, after you are done editing you just read dropTable.dstData and continue using it for what ever you want to do.

    In UIDropTableViewController.m you might want to adjust initDraggedCellWithCell, srcTableCellForRowAtIndexPath and dstTableCellForRowAtIndexPath for your own needs as far as cell representation goes.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Easy question this time. I'm trying to test whether or not a string does
NOTE: I am not exactly sure how to title or tag this question, so
I would like to know whether its possible to open Open word 2003 (doc)
This question is not about any error I'm currently seeing, it's more about theory
My question is whether or not it is possible to allow DB connections ONLY
Note: This is not a question whether I should use list or deque. It's
I know there's already a lot of questions on this topic but I might
Does anyone know if it is possible to do lock-free programming in Haskell? I'm
I was going to ask a question here about whether or not my design
I'm not sure whether I'm asking the question correctly, but I've been told SQL

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.