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'.
Related
I'm new to iOS development and have a question regarding variables. I'm attempting to write an application with a tab bar and navigation controller, the tab bar being the rootViewController. I've set up my application to include a .plist that includes my table view's behaviors, a UITableViewController, and a detail view controller. I continue to get one error in the implementation file of my initial table view controller as I defined the navigation controller in my App delegate.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
//Get the dictionary of the selected data source.
NSDictionary *dictionary = [self.tableDataSource objectAtIndex:indexPath.row];
//Get the children of the present item.
NSArray *Children = [dictionary objectForKey:#"Children"];
if([Children count] == 0) {
DetailViewController *dvController = [[DetailViewController alloc] initWithNibName:#"DetailView" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:dvController animated:YES];
[dvController release];
}
else {
//Prepare to tableview.
IndustryTableViewController *industryTableViewController = [[IndustryTableViewController alloc] initWithNibName:#"IndustryTableViewController" bundle:[NSBundle mainBundle]];
//Increment the Current View
industryTableViewController.CurrentLevel += 1;
//Set the title;
industryTableViewController.CurrentTitle = [dictionary objectForKey:#"Title"];
//Push the new table view on the stack
[self.indNavControl pushViewController:industryTableViewController animated:YES];
industryTableViewController.tableDataSource = Children;
[industryTableViewController release];
}
}
I get the error when I push the new table view on the stack. I am importing the header file of my app delegate, but it still will not work, giving me the error, "Variable not defined in TableViewController.h". Is there a way for me to summon this variable, or is there a more effective way for me to solve this issue?
Thanks in advance, I can really use any help you give me.
You can get a pointer to your appDelegate and then get your variable like so:
YourAppDelegate *appDelegate = (YourAppDelegate *)[[UIApplication sharedApplication] delegate];
Another way would be to use dependency injection and inject the reference into your controller when you create it. So basically define an ivar in your controller to hold a reference and then do this:
[myController new];
[myController setController:otherController];
You are referring to navigationController with self.navigationController.
This implies that navigationController is a variable defined in your TableViewController class.
You should define this variable in your class and modify your init method of the tableviewcontroller to receive that variable.
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];
}
}
I want to build an app for playing local audio files on the iPhone but I'm stuck with some of my codes.
I'm wondering how you can push a view, come back to the uitableviewcontroller and use a button ( like the "NOW PLAYING" button in the media player) to come back to the view without pushing any new string into it..
THANK YOU
What should I change from my codes ?
in the uitableviewcontroller..
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath
*)indexPath {
selectedSong = [directoryContent objectAtIndex:indexPath.row];
NSString *storyLin = [[directoryContent objectAtIndex:[indexPath row]] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
patch = [NSString stringWithFormat:#"/%#", storyLin];
myDetViewCont = [[mPlayerViewController alloc] initWithNibName:#"mPlayerViewController" bundle:nil];
myDetViewCont.myProgLang = selectedSong; // assigning the correct value to the variable inside DetailViewController
[self.navigationController pushViewController:myDetViewCont animated:YES];
[myDetViewCont release]; // releasing controller from the memory
}
in mPlayerViewController.m
-(IBAction) backtoplayer{
myDetViewCont = [[mPlayerViewController alloc] initWithNibName:#"mPlayerViewController" bundle:nil];
}
If you have pushed a view onto the navigation controller, just pop it to review the view underneath.
That is, the view you push myDetViewCont should just be popped in the backtoplayer call.
- (IBAction)backToPlayer:(id)sender {
[self.navigationController popViewControllerAnimated:YES];
}
To Add to what Mark said.
Once you've popViewControllerAnimated and the user want to push the same controller again, you just need to keep the mPlayerViewController rather than release it.
Such as:
if (!myDetViewCont)
{ // We only need to create it once.
myDetViewCont = [[mPlayerViewController alloc] initWithNibName:#"mPlayerViewController" bundle:nil];
}
myDetViewCont.myProgLang = selectedSong;
[self.navigationController pushViewController:myDetViewCont animated:YES];
// no longer release here, move the release call to the dealloc
I have created a table view that pulls its cells from an array.
Each cell needs to push to a different view... and I cannot find the value of the tapped cell. It needs a conditional statement but without the value i cannot push the view :(
below is the snippet of my didSelectRowAtIndexPath
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Navigation logic may go here. Create and push another view controller.
if(){
SendSms *detailViewController = [[SendSms alloc] initWithNibName:#"SendSms" bundle:nil];
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
}
}
You will see the If statement is blank... I need the value of the column pushed to push to another view controller.
Please help! Thanks
I'll answer my own question for those who may be searching it out since i just worked it out :)
use:
if([InsertYourArrayOfDataHere objectAtIndex:indexPath.row] == #"StringInArray")
Hope that might help someone with the same problem
Even after Jonathan's answer I recommend to use this, It would be better to use
if([[InsertYourArrayOfDataHere objectAtIndex:indexPath.row] isEqualToString: #"StringInArray"]) {
//Your Code goes here.
}
If you are comparing string you should use isEqualToString method.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Navigation logic may go here. Create and push another view controller.
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
//you willget alldetail of cell here.
if(){
SendSms *detailViewController = [[SendSms alloc] initWithNibName:#"SendSms" bundle:nil];
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
}
you can find the value of the tapped cell like
indexpath.row,
when user will touch any cell values the indexpath.row will provide you a number then you can perform some actions like
if(indexpath.row == 0)
{
//here create the object for the view1 where you want to navigate
//show view 1
}
else
{
//show view 2
}
Hope this will solve your problem.
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.