Load a particular NIB based on tableview selection - iphone

I have an initial table view that I created as the initial menu within my app. Obviously each option will access something different including NIBs. Part of the constants for the menu options is the NIB. When each option is pulled from a PLIST, I also include which NIB I would like to be called upon.
Am I missing something or am I just going the wrong way entirely?
Right now a selection does nothing.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSMutableString *targetnib = [[self.menuoptions objectAtIndex:indexPath.row] objectForKey:NIB_KEY];
if (targetnib == #"HospitalDirectoryViewController") {
HospitalDirectoryViewController *hospitalDirectoryViewController = [[HospitalDirectoryViewController alloc] initWithNibName:#"HospitalDirectoryViewController" bundle:nil];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:hospitalDirectoryViewController animated:YES];
[hospitalDirectoryViewController release];
}
if (targetnib == #"PhysicianDirectoryViewController") {
PhysicianDirectoryViewController *physicianDirectoryViewController = [[PhysicianDirectoryViewController alloc] initWithNibName:#"PhysicianDirectoryViewController" bundle:nil];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:physicianDirectoryViewController animated:YES];
[physicianDirectoryViewController release];
}
}

Try using [targetnib isEqualToString: #"TheNibName"]. In your posted code, you're comparing pointers, not the text.

Related

iOS 6 pass data from TableView to Detail View

I've a table view with some rows and each row has its Detail Disclosure button.
I want that when the user taps on that button, another table view (customized by storyboard) appears and shows some relative data.
From TableViewController.m
-(void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath {
DetailViewController *detailViewController = [[detailViewController alloc] init];
//creating a parse object
PFObject *checkin = [_dataSourceArray objectAtIndex:indexPath.row];
//getting data i want
NSString *trainNumb = [checkin objectForKey:#"trainNumber"];
//passing the data
detailViewController.trainNumber = trainNumb;
}
From the DetailTableViewController.m
- (void)viewDidLoad {
[_trainNumberLabel setText:_trainNumber];
}
The problem is that in the DetailTableView the NSString results to be null.
What I'm missing here? Thank you!
If this code actually compiles, this may be your problem:
DetailViewController *detailViewController = [[detailViewController alloc] init];
It should be:
DetailViewController *detailViewController = [[DetailViewController alloc] init];
But you shouldn't be alloc/initing your view controller in the first place. When you customize a view controller in Interface Builder, you've got to instantiate it like this if you want those customizations:
[self.storyboard instantiateViewControllerWithIdentifier:#"MyStoryboardIdentifier"]`
And you've got to set the controller's storyboard ID to "MyStoryboardIdentifier" or whatever identifier you want to use.
Also, as you've indicated in the comments, you've got a timing issue: your detail controller's viewDidLoad runs before you set the train number. A better approach would be to ensure that it works regardless of the sequence:
- (void)updateTrainNumberLabel
{
self.trainNumberLabel.text = self.trainNumber;
}
- (void)setTrainNumber:(NSString *)trainNumber
{
_trainNumber = trainNumber;
[self updateTrainNumberLabel];
}
- (void)viewDidLoad
{
...
[self updateTrainNumberLabel];
}
In other words, you configure your label in a separate method, in this case updateTrainNumberLabel, and when anything that could affect the label happens, e.g. the view loading or the number being changed, you call the method.

UINavigationController with two copies of the same view controller on stack

I am using a UINavigationController to push a UIViewController onto the stack, then when the user selects a row in the table view I allocate a new version of the view controller and push it onto the stack this works fine but then when I start pressing the back button the NSMutableArray that I am using to store the information seems to be keeping the value from the view controller that was just poped from the stack.
Here is the method that is pushing the new onto the stack:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
if (indexPath.section == 1) {
if (hasLoadedResponses && [responses count] == 0) {
return;
}
VideoDetailViewController_iPhone *nextView = [[VideoDetailViewController_iPhone alloc] initWithNibName:#"VideoDetailViewController_iPhone" bundle:nil withVideoArray:[responses objectAtIndex:indexPath.row]];
nextView.navController = navController;
[navController pushViewController:nextView animated:YES];
[nextView release];
}
}
I'm sure there is something stupid I am missing, but can't seem to find it right now.
Assuming the mutable array is [responses objectAtIndex:indexPath.row] because is the only value you pass to the new pushed view controller, then if you are modifying it in you have to take in account that is the same object and so modifications are shared.
You can write:
. withVideoArray:[NSMutableArray arrayWithArray:[responses objectAtIndex:indexPath.row]];
As I said, I assume that object is the mutable array of your problem.
Another smarter solution is defining the property you use to store the mutable array as 'copy' instead of 'retain'.

iphone UITableVIew (Navigation-based )

I'm working on a navigation-based application.
My rootViewController contains 3 cells
-When the first one is pressed a UIViewController is pushed (THIS WORKS)
-The problem is with the 2nd and 3rd cells that are supposed to push a UITableViewController
The app is running with no errors and it is NOT crashing at all, but when i navigate to the tableview, an empty table is viewed with no elements in it.
Is the problem with this part of the code?? :
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UIViewController *detailViewController = [[UIViewController alloc] initWithNibName:#"Introduction" bundle:nil];
detailViewController.title=#"Introduction";
UITableViewController *myPictures = [[UITableViewController alloc] initWithNibName:#"Pictures" bundle:nil];
myPictures.title=#"Pictures";
UITableViewController *myImages = [[UITableViewController alloc] initWithNibName:#"ImagesViewController" bundle:nil];
myImages.title=#"Images";
// Pass the selected object to the new view controller.
if (0 == indexPath.row)
[self.navigationController pushViewController:detailViewController animated:YES];
if (1== indexPath.row)
[self.navigationController pushViewController:myPictures animated:YES];
if (2== indexPath.row)
[self.navigationController pushViewController:myImages animated:YES];
[detailViewController release];
[myPictures release];
[myImages release];
What you're doing it very wrong (apart from your original problem). Why are you instantiating each view controller and then only using the one based on the current 'cell selection'? This will slow your app down depending on how much time it would take to load each of these separate views. You should only instantiate the relevant view controller inside the "if (indexPath.row == 2) {" block.
Apart from that there are many things wrong about your approach. What you are doing will never work since instantiating a generic UITableViewController (even if you supply your own nib) will obviously only show you an empty view. You need to have a class of your own which the nib is tied to as a delegate which will then supply the TableView with data.
I believe when you created these nib files (for example "Pictures") xcode also give you a 'PicturesViewController.h and PicturesViewController.m" files? If so, you need to write the appropriate code there and ensure the Tableview in the "Pictures" nib file has its 'datasource' and 'delegate' set to 'PicturesViewController'. Then when you want to show that view do this instead:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == 1) {
...
} else if (indexPath.row == 2) {
PicturesViewController *myPictures = [[PicturesViewController alloc] initWithNibName:#"Pictures" bundle:nil];
[self.navigationController pushViewController:myPictures animated:YES];
[myPictures release];
}
}

How do I create a UIViewController programmatically?

I am working in a app where i have data in UITableView. It is like a drill down application. User will click on a row and will go to next page showing more records in a UITableView. But problem in my case is that i dont know upto how many level user can drill. The number of levels are not fixed. So now i am thinking to create and add the viewcontrollers programmatically. Is it possible?? if yes how?
thanks in advance.
UIViewController *controller = [[UIViewController alloc] init];
controller.view = whateverViewYouHave;
Do you have your own view controller that you coded? In that case you probably don't need to set the view property as it has been set in IB if that is what you used. When you have your controller you can push it onto the navigationController or view it modally etc.
UIViewControllers are always created programmatically. It sounds like you just need to have the same class for each level of view controller, e.g.:
//CoolViewController:UITableViewController
//CoolViewController.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (!self.isAtTopLevel) {
CoolViewController *cvc = [[CoolViewController alloc] initWithRecord:[self.records objectAtIndex:indexPath.row]];
[self.navigationController pushViewController:cvc animated:YES];
[cvc release];
} else {
//do something else
}
}
In this case, thingies would be some sort of recursive NSArray (i.e. an array of arrays).

commit object to next TableViewController

i got a tableview controller.
if a cell is selected i perform the following:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
ablogSingleCatTableViewController *singleCatTableViewController = [[ablogSingleCatTableViewController alloc] initWithStyle:UITableViewStylePlain];
// Push the detail view controller.
[[self navigationController] pushViewController:singleCatTableViewController animated:YES];
[singleCatTableViewController release];
}
i want to commit an object to the next view controller that slides in after this row is selected.
do i have to do something like this?
ablogSingleCatTableViewController *singleCatTableViewController = [[ablogSingleCatTableViewController alloc] initWithStyle:UITableViewStylePlain];
[singleTableViewController setMyObject:superDuperObject];
or is there an easier way to do something like that?
i need this object directly after this tableviewcontroller is initialized, to fill it with specific data that belongs to this object.
please give me some advices.
thanks
You can also pass the object to the next view controller when you init the view controller.
To do so, you need to implement your own initializer for the view controller.
For example:
- (id)initWithStyle:(UITableViewStyle)style superDuper:(SuperDuper*)superDuperObject {
if (self = [super initWithStyle:style]) {
superDuper = superDuperObject;
}
return self;
}
Then,
ablogSingleCatTableViewController *singleCatTableViewController =
[[ablogSingleCatTableViewController alloc] initWithStyle:UITableViewStylePlain superDuper:superDuperObject];