Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Beginning iOS5 Development.pdf
Скачиваний:
7
Добавлен:
09.05.2015
Размер:
15.6 Mб
Скачать

324

CHAPTER 9: Navigation Controllers and Table Views

Now let’s move on to the fifth subcontroller, which demonstrates another use of edit mode. This time, we’ll allow the user to delete our precious rows. Gasp!

Fifth Subcontroller: Deletable Rows

Letting users delete rows isn’t really significantly harder than letting them move rows. Let’s take a look at that process.

Instead of creating an array from a hard-coded list of objects, we’re going to load a property list file this time, just to save some typing. You can grab the file called computers.plist out of the 09 Nav folder in the projects archive that accompanies this book and add it to the Nav folder of your Xcode project.

Select the Nav folder in the project navigator, and then press N or select File New New File…. Select Cocoa Touch, select Objective-C class, and click Next. Name your new class BIDDeleteMeController, and enter BIDSecondLevelViewController for Subclass of.

Creating the Deletable Rows View

The changes we’re going to make to BIDDeleteMeController.h should look familiar, as they’re nearly identical to the ones we made in the movable rows view controller we just built. Go ahead and make these changes now:

#import "BIDSecondLevelViewController.h"

@interface BIDDeleteMeController : BIDSecondLevelViewController

@property (strong, nonatomic) NSMutableArray *list; - (IBAction)toggleEdit:(id)sender;

@end

No surprises here, right? We declare a mutable array to hold our data and an action method to toggle edit mode.

In the previous controller, we used edit mode to let the users reorder rows. In this version, edit mode will be used to let them delete rows. You can actually combine both in the same table if you like. We separated them so the concepts would be a bit easier to follow, but the delete and reorder operations do play nicely together.

A row that can be reordered will display the reorder icon anytime that the table is in edit mode. When you tap the red, circular icon on the left side of the row (see Figure 9–7), the Delete button will pop up, obscuring the reorder icon, but only temporarily.

Switch over to BIDDeleteMeController.m, and add the following code:

#import "BIDDeleteMeController.h"

@implementation BIDDeleteMeController

@synthesize list;

- (IBAction)toggleEdit:(id)sender {

www.it-ebooks.info

CHAPTER 9: Navigation Controllers and Table Views

325

[self.tableView setEditing:!self.tableView.editing animated:YES];

if (self.tableView.editing) [self.navigationItem.rightBarButtonItem setTitle:@"Done"];

else

[self.navigationItem.rightBarButtonItem setTitle:@"Delete"];

}

- (void)viewDidLoad { [super viewDidLoad]; if (list == nil) {

NSString *path = [[NSBundle mainBundle] pathForResource:@"computers" ofType:@"plist"];

NSMutableArray *array = [[NSMutableArray alloc] initWithContentsOfFile:path];

self.list = array;

}

UIBarButtonItem *editButton = [[UIBarButtonItem alloc] initWithTitle:@"Delete" style:UIBarButtonItemStyleBordered target:self action:@selector(toggleEdit:)];

self.navigationItem.rightBarButtonItem = editButton;

}

#pragma mark -

#pragma mark Table Data Source Methods

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

return [list count];

}

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

static NSString *DeleteMeCellIdentifier = @"DeleteMeCellIdentifier";

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:

DeleteMeCellIdentifier];

if (cell == nil) {

cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:DeleteMeCellIdentifier];

}

NSInteger row = [indexPath row];

cell.textLabel.text = [self.list objectAtIndex:row]; return cell;

}

#pragma mark -

#pragma mark Table View Data Source Methods - (void)tableView:(UITableView *)tableView

commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {

www.it-ebooks.info

326

CHAPTER 9: Navigation Controllers and Table Views

NSUInteger row = [indexPath row]; [self.list removeObjectAtIndex:row];

[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];

}

@end

Here, the new action method, toggleEdit:, is pretty much the same as our previous version. It sets edit mode to on if it’s currently off and vice versa, and then sets the button’s title as appropriate. The viewDidLoad method is also similar to the one from the previous view controller and, again, we do not have a viewDidUnload method because we have no outlets and we want to preserve changes made to our mutable array in edit mode. The only difference is that we’re loading our array from a property list rather than feeding it a hard-coded list of strings. The property list we’re using is a flat array of strings containing a variety of computer model names that might be a bit familiar. We also assign the name Delete to the edit button, to make the button’s effect obvious to the user.

The two data source methods contain nothing new, but the last method in the class is something you’ve never seen before, so let’s take a closer look at it.

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {

This method is called by the table view when the user has made an edit, which means a deletion or an insertion. The first argument is the table view on which a row was edited. The second parameter, editingStyle, is a constant that tells us what kind of edit just happened. Currently, three editing styles are defined:

UITableViewCellEditingStyleNone: We used this style in the previous controller to indicate that a row can’t be edited. The option

UITableViewCellEditingStyleNone will never be passed into this method, because it is used to indicate that editing is not allowed for this row.

UITableViewCellEditingStyleDelete: This is the default option. We ignore this parameter, because the default editing style for rows is the delete style, so we know that every time this method is called, it will be requesting a delete. You can use this parameter to allow both inserts and deletes within a single table.

UITableViewCellEditingStyleInsert: This is generally used when you need to let the user insert rows at a specific spot in a list. In a list whose order is maintained by the system, such as an alphabetical list of names, the user will usually tap a toolbar or navigation bar button to ask the system to create a new object in a detail view. Once the user is finished specifying the new object, the system will place in the appropriate row.

www.it-ebooks.info

CHAPTER 9: Navigation Controllers and Table Views

327

The last parameter, indexPath, tells us which row is being edited. For a delete, this index path represents the row to be deleted. For an insert, it represents the index where the new row should be inserted.

NOTE: We won’t be covering the use of inserts, but the insert functionality works in fundamentally the same way as the delete functionality we are about to implement. The only difference is that instead of deleting the specified row from your data model, you need to create a new object and insert it at the specified spot.

In our method, we first retrieve the row that is being edited from indexPath.

NSUInteger row = [indexPath row];

Then we remove the object from the mutable array we created earlier.

[self.list removeObjectAtIndex:row];

Finally, we tell the table to delete the row, specifying the constant UITableViewRowAnimationAutomatic, which sets the animation so that the row disappears as either the rows below or the rows above appear to slide over it. The table view will decide the direction of the sliding animation on its own, depending on which row is being deleted.

[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];

}

NOTE: Several types of animation are available for table views. You can look up UITableViewRowAnimation in Xcode’s document browser to see what other animations are available.

And that’s all she wrote, folks. That’s the whole enchilada for this class.

Adding a Delete Me Controller Instance

Now, let’s add an instance of the new controller to our root view controller and try it out. In BIDFirstLevelController.m, we first need to import our new controller class’s header file, so add the following line of code directly before the @implementation declaration:

#import "BIDDeleteMeController.h"

Next, add the following code to the viewDidLoad method:

- (void)viewDidLoad { [super viewDidLoad];

self.title = @"First Level";

NSMutableArray *array = [[NSMutableArray alloc] init];

// Disclosure Button

BIDDisclosureButtonController *disclosureButtonController =

www.it-ebooks.info

328

CHAPTER 9: Navigation Controllers and Table Views

[[BIDDisclosureButtonController alloc] initWithStyle:UITableViewStylePlain];

disclosureButtonController.title = @"Disclosure Buttons"; disclosureButtonController.rowImage = [UIImage imageNamed:

@"disclosureButtonControllerIcon.png"]; [array addObject:disclosureButtonController];

// Checklist

BIDCheckListController *checkListController = [[BIDCheckListController alloc] initWithStyle:UITableViewStylePlain];

checkListController.title = @"Check One"; checkListController.rowImage = [UIImage imageNamed:

@"checkmarkControllerIcon.png"]; [array addObject:checkListController];

// Table Row Controls

RowControlsController *rowControlsController = [[RowControlsController alloc] initWithStyle:UITableViewStylePlain];

rowControlsController.title = @"Row Controls"; rowControlsController.rowImage = [UIImage imageNamed:

@"rowControlsIcon.png"];

[array addObject:rowControlsController];

// Move Me

BIDMoveMeController *moveMeController = [[BIDMoveMeController alloc] initWithStyle:UITableViewStylePlain];

moveMeController.title = @"Move Me";

moveMeController.rowImage = [UIImage imageNamed:@"moveMeIcon.png"]; [array addObject:moveMeController];

// Delete Me

BIDDeleteMeController *deleteMeController = [[BIDDeleteMeController alloc] initWithStyle:UITableViewStylePlain];

deleteMeController.title = @"Delete Me";

deleteMeController.rowImage = [UIImage imageNamed:@"deleteMeIcon.png"]; [array addObject:deleteMeController];

self.controllers = array;

}

Save everything, compile, and let her rip. When the simulator comes up, the root level will now have—can you guess?—five rows. If you select the new Delete Me row, you’ll be presented with a list of computer models (see Figure 9–19). How many of these have you owned?

www.it-ebooks.info

CHAPTER 9: Navigation Controllers and Table Views

329

Figure 9–19. The Delete Me view when it first launches. Recognize any of these computers?

Notice that we again have a button on the right side of the navigation bar, this time labeled Delete. If you tap that, the table enters edit mode, which looks like Figure 9–20.

www.it-ebooks.info

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]