Gold/Silver solution why not this way?

#1

I tried a different approach which works by putting the “no more items” in a separate section and testing against that. Is there a reason why it should not be done this way? I welcome any comments. Hre is my BNRViewController code, the other code modules are the same as in the book. [code]#import “BNRItemsViewController.h”
#import “BNRItemStore.h”
#import “BNRItem.h”

@interface BNRItemsViewController()

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

@end

@implementation BNRItemsViewController

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

return self;

}

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

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

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if(section ==0){
return [[[BNRItemStore sharedStore]allItems]count];
} else {
return 1;
}
}

-(void)viewDidLoad
{
[super viewDidLoad];

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

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

}

-(UITableViewCell *)tableView: (UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Create an instance of UITableViewCell, with default appearance
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@“UITableViewCell” forIndexPath:indexPath];

// Set the text on the cell with the description of the item that is at the nth index of items, where n = row this cell
// will appear in on the tableview

if (indexPath.section ==0) {
    NSArray *items = [[BNRItemStore sharedStore] allItems];

    BNRItem *item = items[indexPath.row];

    cell.textLabel.text= [item description];
} else {
    cell.textLabel.text = @"No More Items";
}

return cell;

}

-(IBAction)addNewItem:(id)sender
{

// Create a new BNRItem and addit to the store
BNRItem *newItem = [[BNRItemStore sharedStore] createItem];

// Figure out where that item is in the array
NSInteger lastRow =[[[BNRItemStore 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];
}

}

-(UIView *)headerView
{
// If you have not loaded the headerView yet…
if(!_headerView){

    // Load HeaderView.xib
    [[NSBundle mainBundle] loadNibNamed:@"HeaderView" owner:self options:nil];
    
}
return _headerView;

}

-(NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath
{
return @“Remove”;
}

-(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 = [[BNRItemStore sharedStore] allItems];
BNRItem *item = items[indexPath.row];
[[BNRItemStore sharedStore]removeItem:item];

    // Also remove that row from the table view with an animation
    [tableView deleteRowsAtIndexPaths:@[indexPath]
                     withRowAnimation:UITableViewRowAnimationFade];
}

}

  • (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
    {
    if(indexPath.section == 1){
    return NO;
    }else {
    return YES;
    }
    }

  • (NSIndexPath *)tableView:(UITableView *)tableView
    targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath
    toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
    {

    // IF trying to move outside of section, return the source to stop it otherwise return the destination to allow it.
    if(sourceIndexPath.section != proposedDestinationIndexPath.section){
    return sourceIndexPath;
    }else {
    return proposedDestinationIndexPath;
    }
    }

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

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

}
@end[/code]

#2

I did the same too, and I added also some code for the moved row to be in the last cell before “No more items!”, in case we want to move it after the “No more items!” cell.

Here is my code:

BNRItemsViewController.m

#import "BNRItemsViewController.h"
#import "BNRItemStore.h"
#import "BNRItem.h"


@interface BNRItemsViewController()

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

@end

@implementation BNRItemsViewController

-(IBAction)addNewItem:(id)sender
{
    NSLog(@"Let's create a fucking new Item");
    //Create a new BNRItem and add it to the store
    BNRItem *newItem = [[BNRItemStore sharedStore] createItem];
    NSLog(@"BNRItem instance created");
    
    /*//Make a new index path for the 0th section, last row
     NSInteger lastRow = [self.tableView numberOfRowsInSection:0];*/
    
    //Figure out where that item is in the array
    NSInteger lastRowOfTheStore = [[[BNRItemStore sharedStore] allItems] indexOfObject:newItem];
    NSLog(@"The new item is in the array of BNRItemStore at the index %ld", (long)lastRowOfTheStore);
    
    NSIndexPath *indexPathLastRowOfStore = [NSIndexPath indexPathForRow:lastRowOfTheStore inSection:0];
    NSLog(@"Now we just created the indexpath for this new Item, %ld - %ld", indexPathLastRowOfStore.section, indexPathLastRowOfStore.row);

    //Insert this new row into the table.
    [self.tableView insertRowsAtIndexPaths:@[indexPathLastRowOfStore] withRowAnimation:UITableViewRowAnimationTop];
    NSLog(@"We just added a row by clicking the New button");
}

-(IBAction)toggleEditingMode:(id)sender
{
    //If you are in current 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];
        NSLog(@"We turn off editing mode");
    } else {
        //CHange text of button to inform user of state
        [sender setTitle:@"Done"
                forState:UIControlStateNormal];
        //Enter editing mode
        [self setEditing:YES animated:YES];
        NSLog(@"We turn on editing mode");
        
    }
}

//Designated Initializer is initWithStyle  Changing to init
-(instancetype)init
{
    //ALWAYS call the superclass's designated initializer
    self = [super initWithStyle:UITableViewStylePlain];
    if (self) {
    }
    NSLog(@"Store created");
    return self;
}

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

//SILVER CHALLENGE
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 2;
}

-(NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section
{
    if (section == 0) {
        NSLog(@"There are %lu rows in section %ld", (unsigned long)[[[BNRItemStore sharedStore] allItems] count], (long)section);
        return [[[BNRItemStore sharedStore] allItems] count];
    }
    //SILVER CHALLENGE
    else {
        return 1;
    }
    
}

-(UITableViewCell *)tableView:(UITableView *)tableView
        cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    
    /*
     //Create an instance of UITableViewCell, with default appearance
     UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
     reuseIdentifier:@"UITableViewCell"];
     */
    //Get a new or recycled cell
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"UITableViewCell"
                                                            forIndexPath:indexPath];
    
    
    //SILVER CHALLENGE
    if (indexPath.section == 0) {
        NSArray *items = [[BNRItemStore sharedStore] allItems];
        BNRItem *item = items[indexPath.row];
        
        cell.textLabel.text = [item description];
    }
    else {
        cell.textLabel.text = @"No more items !";
    }
    
    NSLog(@"We just told UITableView that it could put a cell at the path %ld - %ld of a length %lu, where the item %ld is stored", (long)indexPath.section, (long)indexPath.row, (unsigned long)indexPath.length, (long)indexPath.item);
    
    return cell;
}

//BRONZE CHALLENGE
-(NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return @"Supprimer";
}


-(UIView *)headerView
{
    //If you haven't loaded the header view yet...
    if (!_headerView) {
        //Load HeaderView.xib
        [[NSBundle mainBundle] loadNibNamed:@"HeaderView"
                                      owner:self
                                    options:nil];
    }
    NSLog(@"NIB file loaded !");
    return _headerView;
}

-(void)viewDidLoad
{
    [super viewDidLoad];
    [self.tableView registerClass:[UITableViewCell class]
           forCellReuseIdentifier:@"UITableViewCell"];
    UIView *header = self.headerView;
    [self.tableView setTableHeaderView:header];
    
}

-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.section == 1) {
        return NO;
    } else {
        return YES;
    }
}

-(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 = [[BNRItemStore sharedStore] allItems];
        BNRItem *item = items[indexPath.row];
        [[BNRItemStore sharedStore] removeItem:item];
        
        //Also remove that row from the table view with an animation
        [tableView deleteRowsAtIndexPaths:@[indexPath]
                         withRowAnimation:UITableViewRowAnimationFade];
    }
}

//SILVER CHALLENGE
-(BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.section == 1) {
        return NO;
    } else {
        return YES;
    }
}

-(void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath
{
    [[BNRItemStore sharedStore] moveItemAtIndex:sourceIndexPath.row
                                        toIndex:destinationIndexPath.row];
    
    NSLog(@"The item moved was at indexPath %lu - %lu and is now at indexPath %lu - %lu", sourceIndexPath.section, sourceIndexPath.row, destinationIndexPath.section, destinationIndexPath.row);
    
}

//GOLD CHALLENGE
-(NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
{
    if (sourceIndexPath.section != proposedDestinationIndexPath.section) {
        NSInteger lastRowOfSection0 = [[[BNRItemStore sharedStore] allItems] count]-1;
        NSIndexPath *designatedDestinationIndexPath = [NSIndexPath indexPathForRow:lastRowOfSection0
                                                                         inSection:sourceIndexPath.section];
        
        NSLog(@"The item moved was at indexPath %lu - %lu and is now at indexPath %lu - %lu",
              sourceIndexPath.section,
              sourceIndexPath.row,
              designatedDestinationIndexPath.section,
              designatedDestinationIndexPath.row);
        
        return designatedDestinationIndexPath;
    } else {
        
        NSLog(@"The item moved was at indexPath %lu - %lu and is now at indexPath %lu - %lu",
              sourceIndexPath.section,
              sourceIndexPath.row,
              proposedDestinationIndexPath.section,
              proposedDestinationIndexPath.row);
        
        return proposedDestinationIndexPath;
    }
}

@end