In the storyboard from the UITableView added one segue named bSegue and bSegue Identifier class name is abcViewController.
In the code writing it as
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UIViewController *viewController;
switch (indexPath.row) {
case PDF:
viewController = [self.storyboard instantiateViewControllerWithIdentifier:#"bSegue"];
break;
default:
viewController = [[UIViewController alloc] init];
}
[self.navigationController pushViewController:viewController animated:YES];
}
but when tried to run app it shows error NSInvalidArgumentException', reason: 'Storyboard () doesn't contain a view controller with identifier 'bSegue'
I double checked it segue identifier is correct then why it is giving this error.
Any ideas.
Thanks
You are confusing view controller identifiers with segue identifiers.
Your line [self.storyboard instantiateViewControllerWithIdentifier:#"bSegue"]
is looking in the storyboard for a view controller with a Storyboard ID of bSegue.
What you want to do is call the segue identifier you have created with performSegueWithIdentifier:sender:
so it would look like [self performSegueWithIdentifier:#"bSegue" sender:nil];
Related
I am having an app which has a UITableViewController which is my settings page. I am pushing the UITableViewController with a presentModalViewController using self.navigationController (using storyboard ID). however each time I try to see that page, it's showing exception. After reading few posts I tried implementing two methods
- (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section
{
return 3;
}
- (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [super tableView:tableView
cellForRowAtIndexPath:indexPath];
return cell;
}
**my .h File**
#interface Setting : UITableViewController<UITableViewDelegate,UITableViewDataSource>
I have done all UI settings in IB so I didn't change anything in above two implemented methods.
In mainviewcontroller from where I am pushing the view to UITableViewController, I am using the below code
Setting *nextController = [[self storyboard] instantiateViewControllerWithIdentifier:#"setting"];
[self presentModalViewController:nextController animated:YES];
Setting *dvc = [[Setting alloc] init];
[self.navigationController pushViewController:dvc animated:YES];
As I already set all UIs in IB why do I need to implement those methods? At least I can seen the view correctly.
It looks like you're trying to initialize the same viewController twice. You don't need to alloc] init] after you instantiateViewControllerWithIdentifier. At least, from my experience you don't. Try this:
Setting *nextController = [[self storyboard] instantiateViewControllerWithIdentifier:#"setting"];
[self.navigationController pushViewController:nextController animated:YES];
That will "push" the nextController with the storyBoardID of "setting" from the right into your existing NavigationController.
However, using my intuition, I believe you want to present a settings view modally, that has it's own NavigationController. In that case, try this code, which wraps the Settings ViewController into a NavigationController, and presents that whole thing modally, so you can navigate within settings:
Setting *nextController = [self.storyboard instantiateViewControllerWithIdentifier:#"setting"];
UINavigationController *navcont = [[UINavigationController alloc] initWithRootViewController:nextController];
navcont.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentViewController:navcont animated:YES completion:nil];
Alternatively, you could do all of this in the Storyboard itself. Select your settings view controller, and go to Editor Menu > Embed In... > Navigation Controller. Then make a segue from your button to the navigation controller that holds the settings controller. Set the segue to "Modal" and you're all done.
Problem: On selection of a particular uitableviewcell, a new DetailViewController should be opened. I have written the code in didSelectRowAtIndexPath but when I click on the cell it is showing me a runtime error.
I have tried calling with [self.navigationController presentModalViewController:jacket animated:YES ]; but when I do my view controller is not getting opened.
Another method I tried is by [self.navigationController performSegueWithIdentifier:#"JacketDetails" sender:self ];.
I have Specified Identifier in the segued has "JacketDetails" in the inspector but here I am getting a run yime error. I have Hooked Segue from UITABLEVIEWCELL to VIEWCONTROLLER.
When I click on the row JacketDetailViewController Should be open. I have Created Class JacketDetailViewController and for New ViewController I have set the class for this in the inspector.
I don't know why it is showing no segue , I have given the identifier in the inspector and properly hooked from tableviewcell to new view controller.
In JacketDetailViewController I want to display a list of Jackets. Presently it is blank ViewController.
My code is below. Would you please suggest a solution? I am a self-teaching beginner in this field. I might have made some minor mistakes. I have Googled my problem and tried to solve it but I have been stuck here for a few days.
TshirtDetailViewController.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here. Create and push another view controller.
[tableView deselectRowAtIndexPath:indexPath animated:YES ];
JacketDetailController *jacket =[[JacketDetailController alloc]init];
NSInteger index =indexPath.row;
NSLog(#"Row:%d",index);
NSString *titleString = [[NSString alloc] initWithFormat:[jackets objectAtIndex:indexPath.row]];
NSLog(#"%#",titleString);
jacket.title=titleString;
// ...
// Pass the selected object to the new view controller.
[self.navigationController performSegueWithIdentifier:#"JacketDetails" sender:self ];
// [self.navigationController presentModalViewController:jacket animated:YES ];
}
#end
Error in Console:
2013-01-07 10:52:21.020 KidsShopee[617:f803] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Receiver (<UINavigationController: 0x6a5fac0>) has no segue with identifier 'JacketDetails''
*** First throw call stack:
(0x13bf052 0x1550d0a 0xdd24b 0x3e8e 0xa671d 0xa6952 0x92e86d 0x1393966 0x1393407 0x12f67c0 0x12f5db4 0x12f5ccb 0x12a8879 0x12a893e 0x16a9b 0x1b08 0x1a65 0x1)
terminate called throwing an exception(gdb)
Try to open view with these lines:
YoutubeViewController *objYoutubeViewController = [[YoutubeViewController alloc]initWithNibName:#"YoutubeViewController" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:objYoutubeViewController animated:YES];
[objYoutubeViewController release];
In place of YoutubeViewController give your view controller class name & change these lines
According to you & check.Ok if you using storyboard then try like below:
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
bookmarkViewController *myVC = (bookmarkViewController *)[mainStoryboard instantiateViewControllerWithIdentifier:#"bookmarkViewController"]
[self presentModalViewController:myVC animated:YES];
in place of bookmarkViewController give your controller name & check. in drag & drop view
controller in main storyboard give right class name like below images:
in place of my bookmarkViewController name give your view controller name that you want to open.
Don't call performSegueWithIdentifier:sender: on the navigation controller! Only your custom viewController can have segues. Call it on self.
Replace
[self.navigationController performSegueWithIdentifier:#"JacketDetails" sender:self ];
with
[self performSegueWithIdentifier:#"JacketDetails" sender:[tableView cellForRowAtIndexPath:indexPath]];
If you hooked up a segue in the storyboard from the table view cell to another controller, then you don't need any of this code at all to make the segue fire. You should be implementing prepareForSegue to pass the information you need to the detail controller, but no other code is necessary.
Based on the error you are getting "has no segue with identifier 'JacketDetails'", something is not right with your call to the segue. I have found that I have problems with seque names working properly unless I copy and paste from the name I gave the seque in the storyboard into my .m file. Even if the spelling and case is correct, I have found many times, copying and pasting has fixed the problem.
Can try with this-
JacketDetailController *jacket =[[JacketDetailController alloc]initWithNibName:#"JacketDetailController" bundle:nil];];///Change string as your nib name.
Then if its navigation base application-
[self.navigationController pushViewController:jacket animated:YES];
Then is its viewController base application-
[self presentModalViewController:jacket animated:YES];
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 am doing a book kinda application using a viewBased application. The mainView acts as the backgroundView for loading pages. Each page is a different view and have its own nib. When i swipe on a page(actually on the mainView which have loaded the current view/page), that page will be removed and the next/previous page will be added.
[currentPage.view removeFromSuperview];
[self.view insertSubview:nextPage.view atIndex:0];
I have added a popoverController with a barbutton in this mainView. Its intialized with a tableviewController class named popClass. PopClass is another UITableViewController class which will act as the parent for the popViewController.
self.myPopController = [[PopController alloc] initWithStyle:UITableViewStylePlain];
self.myPopOverController = [[UIPopoverController alloc] initWithContentViewController:myPopController];
When I select certain row in the popover, I want the backgroundview(mainView) to load the page corresponding to the number of the row.
For that I have written a function in bookView(mainView) Controller class. And is calling it from the popOver's parent class when i select certain row.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSInteger toPageNumber = indexPath.row + 1;
[viewController changeToPage:toPageNumber];
}
Function and the lines of code are executing but nothing is happening. Even the log lines are printed but no action takes place. The code is the same for removing a page and adding another page which is working successfully when i swipe the view/page.
What is the problem? OR is there anyother way to make the view change in mainView by using the popover?
You need to have refernce of the background view controller in the popover controller.
In the PopController controller you should have a delagate like:
#interface PopController: UITablViewController{
//// other varibales;
id delegate;
}
#property (nonatomic, retain) id delgate;
Now from the class in which you are showing the popovercontroller
you should add this line:
[myPopController setDelegate:self];
Then you can easily acces any method of the main view controller class. By using
[delegate callTheRequiredMethod];
Hope this helps.
Thanks,
Madhup
It's hard to tell what's going wrong without looking at the code. That said, here's what I'd do:
(1) When a row is selected in mainView, present the popoverController modally:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
PopoverViewController *vc = [[PopoverViewController alloc] init];
[self.navigationController presentModalViewController:vc animated:YES];
[vc release];
}
(2) When something changes in the popoverController, for example a row is selected, set a value in the parentViewController (which should be the MainView):
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
self.parentViewController.value = someValue;
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
(3) Dismiss the popoverController where-ever you choose by calling:
[self dismissModalViewControllerAnimated:YES]`
I have an UIViewController, this controller is contained in a navigationController.
I add an UITableViewController in this viewController. I would like to call a pushViewController method when I press on a cell of my tableView.
I tried this :
UITableViewController
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
FirstView *myViewController = [[FirstView alloc] init];
[f myViewController];
}
UIViewController (FirstView)
-(void)pushIt
{
SecondView *sCont = [[SecondView alloc] initWithNibName:#"SecondView" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:sCont animated:YES];
NSLog(#"didSelect"); // is printed
[sCont release];
sCont = nil;
}
But nothing happen. I put NSLog() to my pushIt method and I can see it. So I don't understand why I can't push it.
Any idea?
UIViewController has a property named navigationController that will return a UINavigationController if one exists for the view controller its called from.
Using this property, you can push view controllers onto the navigation stack from your table view's didSelectRowAtIndexPath: method.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
SecondView *sCont = [[SecondView alloc] initWithNibName:#"SecondView" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:sCont animated:YES];
[sCont release];
}
The reason your current code isn't working is probably because of the following:
You already have an instance of FirstViewController, as you said you have added a table view as its subview
You try and create a new instance of a FirstViewController when the user taps a cell, which isn't on the navigation stack, so trying to push a view controller onto the stack from there doesn't work, because the navigationController property returns nil.
You alloc and init myViewController but never push it to navigation or window or whatever else, then you push sCont to myViewController, that isn't present at window. First, try not using myViewController, next try to push myViewController to navigation before pushing sCont into it.