Basic iOS issues - objective-c

I am trying to to complete the 'Your Second iOS App' tutorial from the apple developer program. It is a basic tableView app. My problem is that the app is building successfully and without warnings, however I cannot get the detail view to segue from the master view. I have copied and pasted both the segue identifier and the code that apple has provided. The segue is using push and I have deleted it and tried again several times. I am testing the app in the simulator.
How can I tell if a segue is working?
Every time I copy/paste my code from Xcode into the stack overflow question text area, I get warnings at the bottom saying that code must be indented by 4 spaces??? Does this mean I have to go line-by-line indenting code?? I did the control + k and pasted in the highlighted area, however I still got the warning??
When running the simulator and looking at it, I'm trying to use a disclosure indicator by clicking on it, do I have to push something special like control = click or command = click, etc. ?
Here is the code for BirdsMasterViewController.m file:
//
// BirdsMasterViewController.m
// BirdWatching
//
// Created by David Hall on 11/13/12.
// Copyright (c) 2012 David Hall. All rights reserved.
//
#import "BirdsMasterViewController.h"
#import "BirdsDetailViewController.h"
#import "BirdSightingDataController.h"
#import "BirdSighting.h"
/*
#interface BirdsMasterViewController () {
NSMutableArray *_objects;
}
#end
*/
#implementation BirdsMasterViewController
- (void)awakeFromNib
{
[super awakeFromNib];
self.dataController = [[BirdSightingDataController alloc] init];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
/*
self.navigationItem.leftBarButtonItem = self.editButtonItem;
UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(insertNewObject:)];
self.navigationItem.rightBarButtonItem = addButton;
*/
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
/*- (void)insertNewObject:(id)sender
{
if (!_objects) {
_objects = [[NSMutableArray alloc] init];
}
[_objects insertObject:[NSDate date] atIndex:0];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[self.tableView insertRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
*/
#pragma mark - Table View
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.dataController countOfList];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"BirdSightingCell";
static NSDateFormatter *formatter = nil;
if (formatter == nil)
{
formatter = [[NSDateFormatter alloc] init];
[formatter setDateStyle:NSDateFormatterMediumStyle];
}
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
BirdSighting *sightingAtIndex = [self.dataController objectInListAtIndex:indexPath.row];
[[cell textLabel] setText:sightingAtIndex.name];
[[cell detailTextLabel] setText:[formatter stringFromDate:(NSDate *)sightingAtIndex.date]];
return cell;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return NO;
}
/*- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
[_objects removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
} else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.
}
}
*/
/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
}
*/
/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the item to be re-orderable.
return YES;
}
*/
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"ShowSightingDetails"]) {
BirdsDetailViewController *detailViewController = [segue destinationViewController];
detailViewController.sighting = [self.dataController objectInListAtIndex:[self.tableView indexPathForSelectedRow].row];
}
}
#end
And here is the code for the BirdsDetailViewController.m
//
// BirdSightingDataController.m
// BirdWatching
//
// Created by David Hall on 11/25/12.
// Copyright (c) 2012 David Hall. All rights reserved.
//
#import "BirdSightingDataController.h"
#import "BirdSighting.h"
#interface BirdSightingDataController ()
- (void)initializeDefaultDataList;
#end
#implementation BirdSightingDataController
- (void)initializeDefaultDataList
{
NSMutableArray *sightingList = [[NSMutableArray alloc] init];
self.masterBirdSightingList = sightingList;
BirdSighting *sighting;
NSDate *today = [NSDate date];
sighting = [[BirdSighting alloc] initWithName:#"Pigeon" location:#"Everywhere" date:today];
[self addBirdSightingWithSighting:sighting];
}
- (void)setMasterBirdSightingList:(NSMutableArray *)newList
{
if (_masterBirdSightingList != newList)
{
_masterBirdSightingList = [newList mutableCopy];
}
}
- (id)init
{
if (self = [super init])
{
[self initializeDefaultDataList];
return self;
}
return nil;
}
- (NSUInteger)countOfList
{
return [self.masterBirdSightingList count];
}
- (BirdSighting *)objectInListAtIndex:(NSUInteger)theIndex
{
return [self.masterBirdSightingList objectAtIndex:theIndex];
}
- (void)addBirdSightingWithSighting:(BirdSighting *)sighting
{
[self.masterBirdSightingList addObject:sighting];
}
#end
David Hall

It's working when it works. But without knowing more about what you are doing it's hard to give you an answer.
Highlight the code in the textbox and then click on this button.
It will indent the code correctly for you.
I can't make sense of this question.
Edited to add
(After seeing a copy of the project that the OP mailed me)
Your segue wasn't wired up properly.
The segue is supposed to go from the cell to the next view controller, because the point is to transition on a cell click. Your segue is wired up from the controller to the detail view controller. In your project - right click on your view controller and you'll see the segue is manually connected. But right clicking on the cell doesn't show a segue connection.
Delete the current segue and recreate it, this time by control-dragging from the cell to the next view controller. You can then double check the connection by right clicking on the cell and making sure that the segue is connected.
It should look like:

If the segue is supposed to transition from your table to a detail view, and if you can't get to the detail view from the table, then your segue isn't working.
You can use the code sample button at the top of the SO editor, or you can select the code in your text editor and indent it before you copy it. For example, in Xcode it's easy to select the code, hit Command-], and copy. Then just paste into the SO editor.
Please edit your question so that it makes sense. However, I think you might be asking something along the lines of how to push a view controller from your table. If you're using a segue, and if you've created the segue in your storyboard and it's connected to both the source and destination view controllers, then you can send -performSegueWithIdentifier:sender: to your table's view controller. That is, your table view controller's -tableView:didSelectRowAtIndexPath: method should call -performSegueWithIdentifier:sender: and specify the identifier for the segue leading from the table view controller to the detail view controller. It doesn't matter whether you're using the simulator or running your app on a real device.

See the other answers from Caleb and Abizem regarding 1. and 2. If I understood your question No 3 correctly, then the answer is no. You do not have to press something in particular in the simulator when you want to select a table row or the detail desclosure indicator. Just click on those items that you would tap on your device too. If it does not segue then the chances are that its not the simulator causing the problem :)

Related

Two UITableView, one master view and one details view

I need some help on displaying data from Master view to Details view. When a cell is selected on Master view, data will display on details view. Master Details View
All other class is a xib file to be loaded on the Details view which is being outlet in the container view. The implementation is to avoid using UISplitViewController. I'm using objective-c. Please can anyone help me.
MainContainerViewController.m
+ (MainContainerViewController *)createModalContainer:(NSString*)paramStr{
MainContainerViewController *aController = [[MainContainerViewController alloc] initWithNibName:#"MainContainerViewController" bundle:nil];
aController.title = paramStr
return aController;
}
- (void)viewDidLoad {
[super viewDidLoad];
_masterViewController = [[MasterViewController alloc]init];
[_masterTableView setDataSource:_masterViewController];
[_masterTableView setDelegate:_masterViewController];
_masterViewController.view = _masterViewController.tableView;
}
MasterViewController.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
switch (indexPath.row) {
case 0:
DetailsProfileViewController *detailsController = [[DetailsProfileViewController alloc] init];
detailsController.title = #"Details";
MainContainerViewController *container = MainContainerViewController.sharedInstance;
[container.detailsTableView setDataSource:detailsController];
[container.detailsTableView setDelegate:detailsController];
detailsController.view = detailsController.tableView;
[container.detailsTableView reloadData];
break;
}
}

Populating NSTableView from NSMutableArray at button pressed

in an OSX app i'm currently developping to get familiar with obj-c, I want to populate a TableView. After some hours spent reading way too much blog posts, I can't understand how to add a row in my TableView.
Here is what I've done following this guide:
I have an NSMutableArray in my ViewController, this ViewController implement both interfaces NSTableViewDataSource and NSTableViewDelegate. And I implement both methodes as indicated in the guide. I also have a button and a tableView. When I click on the button, I fill my array with my own object, that's works great.
But what I want now, is when my array is populated, my tableview is too. I'm aware I need to bind those two in some way, but I have no idea how, can someone give some indication ?
Here is my code for my ViewController:
- (void)viewDidLoad {
[super viewDidLoad];
self.tableViewEpisodes.delegate = self;
self.tableViewEpisodes.dataSource = self;
}
- (IBAction)btRefresh:(id)sender {
CalendarReader* reader = [[CalendarReader alloc]init];
self.episodes = [Episode getEpisodeFromEKEvents:[reader getLastMonthEventsForCalendarName:#"TV Shows"]];
[self.tableViewEpisodes reloadData];
}
- (NSInteger)numberOfSectionsInTableView:(NSTableView *)tableView
{
return [self.episodes count];
}
- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColum row:(NSInteger)row {
// Retrieve to get the #"MyView" from the pool or,
// if no version is available in the pool, load the Interface Builder version
NSTableCellView *result = [tableView makeViewWithIdentifier:#"MyView" owner:self];
// Set the stringValue of the cell's text field to the nameArray value at row
result.textField.stringValue = [self.episodes objectAtIndex:row];
// Return the result
return result;
}
First, you are creating a cell view with an identifier which you have not declared, you need to do something like this (assuming you correctly adopted the UITableView protocol in your class):
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *Ident = #"Ident";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:Ident];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:Ident] autorelease];
}
[cell.textLabel setText: [yourArray objectAtIndex:indexPath.row];
return cell;
}
This is a delegate method for your NSTableView. It is called when the view is loaded so you need to provide a data source at runtime.
Second, I'm assuming you want one section with a number of rows equal to your data array. If this is so, you need to change the delegate method:
- (NSInteger)numberOfSectionsInTableView:(NSTableView *)tableView
to:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
Finally, keep in mind these above methods populate the ROWS, not the COLUMNS as you have it now. Once you populate your array, you need to invoke the method:
[yourTableView reloadData]
In order to refresh the table.
Hope this helps.
Thanks to #bryan-wheeler, I notice a message log when testing his code, and I found out, I was not implementing the correct method: here is my code for my ViewController now:
- (void)viewDidLoad {
[super viewDidLoad];
self.tableViewEpisodes.delegate = self;
self.tableViewEpisodes.dataSource = self;
}
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
{
return 1;
}
-(id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex{
return [self.episodes objectAtIndex:rowIndex];
}
For beginner like me, you'll also have to implement the NSCopying protocol for the class stored in your data source array.
Right now, I only have one element in my TableView and it only show its memory address, but I'll update this answer as soon as I found out how to make it works for future beginner in my case.
EDIT: OK, it works !! My mistake was that: in the tableView:objectValueForTableColumn:row: method, I though I needed to return the Object representing the row given in parameter, but I had to return the one for the AND the cell given in parameter, now I found out, it's pretty obvious, but as a French, I didn't understand the method name correctly. Here is my code now:
- (void)viewDidLoad {
[super viewDidLoad];
self.tableViewEpisodes.delegate = self;
self.tableViewEpisodes.dataSource = self;
}
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
{
return [self.episodes count];
}
-(id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex{
if([[aTableColumn title] isEqual: #"Serie's name"]){
return [[self.episodes objectAtIndex:rowIndex] seriesName];
}else if([[aTableColumn title] isEqual: #"Season number"]){
return [NSString stringWithFormat:#"%ld", (long)[[self.episodes objectAtIndex:rowIndex] seasonNumber]];
}else if([[aTableColumn title] isEqual: #"Episode number"]){
return [NSString stringWithFormat:#"%ld", (long)[[self.episodes objectAtIndex:rowIndex]episodeNumber]];
}else{
return nil;
}
}
There is some optimisation to do for sure, feel free to propose. But it's doing the job.

UITableViewController Grouped Property Not Working

I have two UITableViewControllers. In the first UITableView, once a user selects a cell, a new UITableViewController is pushed. I have set both UITableViews to "Grouped" in IB. However, when the second UITableViewController is pushed, it appears as a "Plain" UITableView. Is there a way to fix this?
Just as a sanity check, I changed the code so that the second UITableViewController is pushed not from the first UITableViewController, and it does appear to be "Grouped". Is there a reason this is happening?
Code From UITableViewController that is pushing second UITableViewController:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if ([cell.text isEqualToString:#"Long Term Disability"]) {
LongDisabilityTableView *ldvc = [LongDisabilityTableView alloc];
[self.navigationController pushViewController:ldvc animated:YES];
}
if ([cell.textLabel.text isEqualToString:#"Short Term Disability"]) {
ShortDisabilityTableView *sdvc = [ShortDisabilityTableView alloc];
[self.navigationController pushViewController:sdvc animated:YES];
}
}
If you are pushing to a UITableViewController, you can force the table to be grouped by doing one of the following:
Init
MyTableController *grouped = [[MyTableController alloc] initWithStyle:UITableViewStyleGrouped];
Super
This needs to be added to a UITableViewController.
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:UITableViewStyleGrouped]; /* This is where the magic happens */
if (self) {
self.title = #"My Grouped Table";
}
return self;
}
Double Check
Make sure that you are not placing your UITableView on a UIViewController.
Make sure that you are calling the correct controller in your code (from didSelectRowAtIndexPath:)
Update, added after code
Well there's one reason right there, you aren't using init. See my first example above.
You should also change your code to this:
/* This assumes that your Long Term Disability cell is at index 0
and that your Short Term Disability cell is at index 1.
*/
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
switch ( indexPath.row )
{
case 0: /* #"Long Term Disability" */
LongDisabilityTableView *ldvc = [[LongDisabilityTableView alloc] initWithStyle:UITableViewStyleGrouped];
[self.navigationController pushViewController:ldvc animated:YES];
break;
case 1: /* #"Short Term Disability" */
ShortDisabilityTableView *sdvc = [[ShortDisabilityTableView alloc] initWithStyle:UITableViewStyleGrouped];
[self.navigationController pushViewController:sdvc animated:YES];
break;
}
}

Initialize custom UITableViewCell

I'm trying to load a single custom cell into a UITableView and it keeps throwing an error
UITableView dataSource must return a cell from tableView:cellForRowAtIndexPath:
I have no idea why. I have linked my table view cell to the UITableViewCell definition in my code, but it keeps giving me this error. Here is my code; any help would be greatly appreciated.
#import "RegisterDeviceViewController.h"
#implementation RegisterDeviceViewController
#synthesize checkString;
#synthesize cellRegistration;
// The designated initializer. Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
/*
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization.
}
return self;
}
*/
//Change UITableView Style to Grouped
- (id)initWithStyle:(UITableViewStyle)style {
// Override initWithStyle: if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
style = UITableViewStyleGrouped;
if (self = [super initWithStyle:style]) {
}
return self;
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
self.title = #"Registration";
[super viewDidLoad];
}
// Customize the number of sections in the table view.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 1) {
if (indexPath.row == 1) {
return cellRegistration;
}
}
return nil;
}
//Pass search type over to rootViewController section2
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
/*
<#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:#"<#Nib name#>" bundle:nil];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
*/
}
/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations.
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc. that aren't in use.
}
- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[super dealloc];
}
#end
Okay. That's not how UITableView works. When the table view needs to draw a cell (ie, a row); it invokes tableView:cellForRowAtIndexPath: on the object specified in the dataSource property. It's your job to return a UITableViewCell from that method. This is how Apple does it (and how you should do it):
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"AnIdentifierString"];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:#"AnIdentifierString"] autorelease];
}
cell.textLabel.text = #"This text will appear in the cell";
return cell;
}
The number of times that method will be invoked depends on the number of sections in the table view and the number of rows in each section. The process works like this:
Table View invokes the delegate method numberOfSectionsInTableView: on its dataSource (it knows it implements that method because the dataSource must adhere to the UITableViewDataSource protocol).
If numberOfSectionsInTableView: returns a number greater than zero, the table view will invoke the delegate method tableView:numberOfRowsInSection: on the dataSource. So if numberOfSectionsInTableView: returns 2, tableView:numberOfRowsInSection: will be invoked twice.
If each invocation of tableView:numberOfRowsInSection: returns a number greater than zero, the table view will invoke the delegate method tableView:cellForRowAtIndexPath: on the dataSource' So if tableView:numberOfRowsInSection: returns 5, tableView:numberOfRowsInSection: will be invoked five times (once for each individual row).
Your opportunity to customise how that cell appears is after you've received a useable cell, but before it is returned (where 'This text will appear in the cell' appears above). You can do quite a lot here; you should see the Class Reference for UITableViewCell to see everything you can do (all I've done is set it to show 'This text...'). The lines above that are a way for iOS to reuse cells for performance considerations. If you, for example, wanted to show a certain string from an array of strings, you could do this (notice the use of the indexPath variable): cell.textLabel.text = [someArrayYouHave objectAtIndex:indexPath.row];.
You wrote:
it keeps throwing an error
'UITableView dataSource must return a
cell from
tableView:cellForRowAtIndexPath:' But
I have no idea why..
But your -tableView:cellForRowAtIndexPath: says, in part:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//...
return nil;
}
After reading the error message and looking at the code, do you not see the problem?
You are returning only one section, only one row
the section count and row count starts from 0.
Thats y you are getting this kinda error
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 0) {
if (indexPath.row == 0) {
//this checking is no necessary, anyway if you want use like this
//ensure that cellRegistration is UITableViewCell
return cellRegistration;
}
}
return nil;
}
Also refer this post for loading custom cells.
New iOS7+ solution optimized for Smoother Scrolling
You already can see old solutions but as far as huge amount of Apps will continue only iOS7+ support here is a way more optimized and correct solution.
Cell initialization
To initialize cell just call dequeueReusableCellWithIdentifier and iOS7+ systems are enough smart to handle if cell == nil or not. If during dequeue cell is nil system will automatically make a cell for you.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cellIdentifier" forIndexPath:indexPath];
return cell;
}
Cell configuration
Then do your entire cell configuration in willDisplayCell method. Just create one method in your class that configures cell and here you go with better performance!
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
[self configureCell:cell forRowAtIndexPath:indexPath];
}
- (void)configureCell:(UITableViewCell *)cell
forRowAtIndexPath:(NSIndexPath *)indexPath {
// Configure your cell
}

iPad: SplitViewController with navigation

I'm following Apple sample code "MultipleDetailViews" but what I want to do is that:
at start, shows the RootViewController (table view) display the default detailViewController (1st detailView)
when user selected a table cell, push into the stack, display the SubCategoriesVC (table view) in the master of the splitView but don't update the detailView.
in SubCategoriesVC, selecting a table cell.. update the detailViewController (2nd detailView)
So, in RootViewController.m, I push another navigation
...
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
SubCatVC *browseSubCatView = [[SubCatVC alloc] initWithNibName:#"SubCatVC" bundle:nil];
[self.navigationController pushViewController:browseSubCatView animated:YES];
[browseSubCatView release];
}
Then, in SubCatVC.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UIViewController <SubstitutableDetailViewController> *detailViewController = nil;
SecondDetailViewController *newDetailViewController = [[SecondDetailViewController alloc] initWithNibName:#"SecondDetailViewController" bundle:nil];
detailViewController = newDetailViewController;
// Update the split view controller's view controllers array.
NSArray *viewControllers = [[NSArray alloc] initWithObjects:self.navigationController, detailViewController, nil];
self.splitViewController.viewControllers = viewControllers;
[viewControllers release];
// Dismiss the popover if it's present.
if (self.popoverController != nil) {
[self.popoverController dismissPopoverAnimated:YES];
}
// Configure the new view controller's popover button (after the view has been displayed and its toolbar/navigation bar has been created).
if (self.rootPopoverButtonItem != nil) {
[detailViewController showRootPopoverButtonItem:self.rootPopoverButtonItem];
}
[detailViewController release];
[[NSNotificationCenter defaultCenter] postNotificationName:#"updateProduct" object:nil];
}
but it didn't update my detailView.. so I don't know what's wrong?
Src here: http://pastebin.com/iy6SqLqt
Hope someone can advise me. Thanks
I Have not looked at your source, but but a common problem with Split views are delegates.
When you Push a new rootController ont the nav stack, you need to make sure it has the pointer to the detailViewController that you want it to talk to. You can check htis my logging the delegate before you try to update it:
In your SubCatVC (or any root for that matter):
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
//do stuff, init alloc vc's....
NSLog(#"DELEGATE: %#",self.delegate);
//push/delegate etc..
}
If you find its nil, copy the original roots delegate, or when your putting your new detail in, notify/set the root you want to comunicate with it.
If you need any more detail, just ask.