Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to let the user reorder sections in a UITableView

I'm working on an app with stocks, arranged in portfolios. So this is a natural fit for the table view, and I'm working on the editing interaction; it's straightforward enough to allow the user to add or delete stocks, drag them around within one portfolio or to another portfolio, but one thing that I haven't been able to do gracefully is let the user drag one portfolio above or below another.

I've got a hacky solution right now, where row 0 of each section is the portfolio name, and if they drag that row above another portfolio, the whole table is reloaded with the portfolios switched. This works, but doesn't feel very natural.

I'm sure I'm not the first to encounter this problem; anyone have a more refined solution?

A related question - how do I let users create a new portfolio/section?

like image 440
Apollo Grace Avatar asked Jul 03 '14 23:07

Apollo Grace


People also ask

What is Section in UITableView?

UITableView with sections allows us to separate the list into different categories, so the list looks more organized and readable. We can customize sections as per our need, but in this tutorial, we are covering the basic UITableview with sections.

Is it possible to add UITableView within a UITableviewCell?

yes it is possible, I added the UITableVIew within the UITableView cell .. :) no need to add tableview cell in xib file - just subclass the UITableviewCell and use the code below, a cell will be created programatically.

What is Indexpath in Tableview Swift?

Swift version: 5.6. Index paths describe an item's position inside a table view or collection view, storing both its section and its position inside that section.


1 Answers

Easy peasy:

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController
{
    NSMutableArray *_data;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    _data = [NSMutableArray arrayWithObjects:@"One", @"Two", @"Three", nil];
    self.tableView.editing = YES;
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return _data.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *identifier = @"reuseIdentifier";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
    if (!cell)
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                      reuseIdentifier:identifier];
    }
    cell.textLabel.text = _data[indexPath.row];
    cell.showsReorderControl = YES;

    return cell;
}

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return UITableViewCellEditingStyleNone;
}

- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
    return YES;
}

- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath
{
    [_data exchangeObjectAtIndex:sourceIndexPath.row withObjectAtIndex:destinationIndexPath.row];
}

@end

EDIT:

What you've asked for now is a little more complicated. I created an example that puts tables into cells, which gives you nested cells. The example is highly unattractive, but it works, and there's no reason you can't make it look pretty, so check it out:

https://github.com/MichaelSnowden/TableViewInCell

If that doesn't work for you, try making UITableView moveSection:(NSInteger) toSection:(NSInteger) look pretty. Documentation for that method is here.

My experience with the above method was that it's very easy to use, and it looks nice when it's called. A smart way to use it would be to create headers with tap gesture recognizers. On the first tap, highlight that section and record that indexPath, and on the second tap, call the method on the two index paths. It should work nicely, but you won't get drag-and-drop from it.

like image 167
michaelsnowden Avatar answered Oct 21 '22 03:10

michaelsnowden