My Bronze/Silver/Gold Challenges Solution


#1

This is like the second gold challenge that i found easy to commit! But here i’ll share you my approach to avoid the rows to move under No more items!
Hope i can help. If you have any suggestions they are welcome!

[code]#import “JDMItemsViewController.h”
#import “JDMItemStore.h”
#import “JDMItem.h”

@interface JDMItemsViewController()

@property (nonatomic,strong) IBOutlet UIView *headerView;

@end

@implementation JDMItemsViewController

-(instancetype)init
{
//Call the superclass’s designated initializer
self = [super initWithStyle:UITableViewStylePlain];
if (self) {

}

return self;

}

-(instancetype)initWithStyle:(UITableViewStyle)style
{
return [self init];
}

#pragma mark - tableview datasource and delegate methods

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [[[JDMItemStore sharedStore] allItems] count] + 1;
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"UITableViewCell" forIndexPath:indexPath];

//Set the text on the cell with the description of the item, that is at nth index of items, where n = row this cell will appear on the tableview
if (indexPath.row == [[[JDMItemStore sharedStore] allItems] count]) {
    cell.textLabel.text = @"No more Items!";
}else {
    NSArray *items = [[JDMItemStore sharedStore] allItems];
    JDMItem *item = items[indexPath.row];
    cell.textLabel.text = [item description];
}



return cell;

}

-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
//If the table view is asking to commit a delete command…
if (editingStyle == UITableViewCellEditingStyleDelete) {

    NSArray *items = [[JDMItemStore sharedStore] allItems];
    JDMItem *item = items[indexPath.row];
    [[JDMItemStore sharedStore] removeItem:item];
    
    //Also remove that row from the table view with an animation
    
    [self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}

}

-(NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath
{
//Bronze Challenge Solution

NSString *newTitle = @"Remove";
return newTitle;

}

-(void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath
{

    [[JDMItemStore sharedStore] moveItemAtIndex:sourceIndexPath.row toIndex:destinationIndexPath.row];

}

-(NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
{
//Gold Challenge Solution

//Prevents from under No more Items!
//source indexPath is equivalent to last row from the array, so like the proposedDestinationIndexPath really does not exist in our source
//Then it is not possible to move beyond the No more Items! cell/row.

if (sourceIndexPath.row > proposedDestinationIndexPath.row) {
    return proposedDestinationIndexPath;
}else {
    return sourceIndexPath;
}

}

-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
//Silver Challenge Solution

if (indexPath.row < [[[JDMItemStore sharedStore] allItems] count]) {
    return YES;
}else {
    return NO;
}

}

#pragma mark - views Methods

-(void)viewDidLoad
{
[super viewDidLoad];

[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"UITableViewCell"];

UIView *header = self.headerView;
[self.tableView setTableHeaderView:header];

}

-(UIView *)headerView
{
if (!_headerView) {
//Load the HeaderView.xib
[[NSBundle mainBundle] loadNibNamed:@“HeaderView” owner:self options:nil];
}

return _headerView;

}

-(IBAction)addNewItem:(id)sender
{
//Create a new JDMItem and add it to the store
JDMItem *newItem = [[JDMItemStore sharedStore] createItem];

//figure out where that item is in the array
NSInteger lastRow = [[[JDMItemStore sharedStore] allItems] indexOfObject:newItem];

NSIndexPath *indexPath = [NSIndexPath indexPathForRow:lastRow inSection:0];

//Insert this new row into the table.
[self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationTop];

}

-(IBAction)toggleEditingMode:(id)sender
{
//If you are currently in editing mode…
if (self.isEditing) {
//Change text of button to inform user of state
[sender setTitle:@“Edit” forState:UIControlStateNormal];

    //Turn off editing mode
    [self setEditing:NO animated:YES];
}else {
    //Change text of button to inform user of state
    [sender setTitle:@"Done" forState:UIControlStateNormal];
    
    //Enter editing mode
    [self setEditing:YES animated:YES];
}

}

@end
[/code]


#2

You will not be able to move any rows down with that
code in targetIndexPathForMoveFromRowAtIndexPath.

Looks like this fixes that. Try it out…

if (proposedDestinationIndexPath.row < [[[BNRItemStore sharedStore] allItems] count]) { return proposedDestinationIndexPath; } else { return sourceIndexPath; }

]


#3

[quote=“GunnyHwy”]You will not be able to move any rows down with that
code in targetIndexPathForMoveFromRowAtIndexPath.

Looks like this fixes that. Try it out…

if (proposedDestinationIndexPath.row < [[[BNRItemStore sharedStore] allItems] count]) { return proposedDestinationIndexPath; } else { return sourceIndexPath; }

][/quote]

Totally Right sir! Thanks for the solution! i guess i was to excited to catch that lol! Thanks again!