ok, here's my solution on this
I have a root view that displays a list of items. Items is a NSMutableArray. When an item is clicked, the detail view is shown. Normally you hand over the object to display in a way like this:
Code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
DetailViewController *detailVC = [[DetailViewController alloc]
initWithNibName:@"DetailViewController" bundle:nil];
detailVC.item = [self.items objectAtIndex:indexPath.row];
[self.navigationController pushViewController:detailVC animated:YES];
[detailVC release];
}
The problem here is that the detail view knows about the item but nothing about the list and the current position. So the detail view is unable to navigate itself through the list of items later. We should hand over the items array and the position instead of only the item.
Simply replace
Code:
detailVC.item = [self.items objectAtIndex:indexPath.row];
with
Code:
detailVC.currentRow = indexPath.row;
detailVC.items = self.items;
In the detail view we define
Code:
NSMutableArray *items;
int currentRow;
...
@property (nonatomic, retain) NSMutableArray *items;
@property (nonatomic, assign) int currentRow;
(be careful
not to use retain here because currentRow is a simple datatype, not an object.)
In the detail view I use a segmented control in the navbar to navigate through the items (as you can see in the mail app). To setup the navbar I define
Code:
@property (nonatomic, retain) UISegmentedControl *segControl;
Then I extended the viewDidLoad:
Code:
- (void)viewDidLoad {
[super viewDidLoad];
// "Segmented" control to the right
UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] initWithItems:
[NSArray arrayWithObjects:
[UIImage imageNamed:@"up.png"],
[UIImage imageNamed:@"down.png"],
nil]];
[segmentedControl addTarget:self action:@selector(segmentAction:) forControlEvents:UIControlEventValueChanged];
segmentedControl.frame = CGRectMake(0, 0, 90, 30.0);
segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar;
segmentedControl.momentary = YES;
UIBarButtonItem *segmentBarItem = [[UIBarButtonItem alloc] initWithCustomView:segmentedControl];
[segmentedControl release];
self.navigationItem.rightBarButtonItem = segmentBarItem;
self.segControl = segmentedControl;
[self redrawButtonState];
[segmentBarItem release];
}
The method segmentAction is a callback that says which button was pressed, prev or next. To make this work you also need two icon files showing an up and down arrow ("up.png" and "down.png")
Code:
- (IBAction)segmentAction:(id)sender
{
// The segmented control was clicked, handle it here
UISegmentedControl *segmentedControl = (UISegmentedControl *)sender;
switch (segmentedControl.selectedSegmentIndex) {
case 0: // Up clicked
if (self.currentRow>0) {
self.currentRow = self.currentRow-1;
[self showItem:currentRow];
}
break;
case 1: // Down clicked
if (self.currentRow < [items count]-1) {
self.currentRow = self.currentRow+1;
[self showItem:currentRow];
}
break;
default:
break;
}
[self redrawButtonState];
}
To display the item I use this method
Code:
-(void) showItem:(int)index {
self.item = [self.items objectAtIndex:index];
itemTextView.text = [item objectForKey:@"something"];
...
}
So we can use this any time when we need to display another item. First it is used in viewWillAppear
Code:
-(void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self showItem:currentRow];
}
Remember that currentRow is set already in the root view.
Another thing to mention here is that we want to disable the prev button when we show the first item in the list (and disable the next button when we show the last item, too). So I use this method whenever a button is pressed and also when we initially open the view, right after creating the segControl.
Code:
-(void)redrawButtonState {
[self.segControl setEnabled:self.currentRow>0 forSegmentAtIndex:0];
[self.segControl setEnabled:self.currentRow<[self.items count]-1 forSegmentAtIndex:1];
}
By the way, don't forget to release your objects in the dealloc.
For me it looks pretty cool now. I hope this is helpful.