Passing Segue Gives Error - iphone

Hi I have currently made a push on select to get my table view to push to a detail view. I also have this code to send the name of the table cell that was selected:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *acell = [tableView cellForRowAtIndexPath:indexPath];
selectedCell = acell.textLabel.text;
DetailViewController *myDetViewCont = [[DetailViewController alloc] initWithNibName:#"DetailViewController" bundle:[NSBundle mainBundle]];
myDetViewCont.navigationItem.title = selectedCell;
[self.navigationController pushViewController:myDetViewCont animated:YES];
}
It builds successfully but in the simulator It throws an error:
#autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
Thread: 1 signal: SIGABRT
I've looked up similar problems but havent found a solution.
Any Help?
Ok additional info on the error:
[self.navigationController pushViewController:myDetViewCont animated:YES];

If you're using storyboards, then the following line doesn't make sense:
DetailViewController *myDetViewCont = [[DetailViewController alloc] initWithNibName:#"DetailViewController" bundle:[NSBundle mainBundle]];
Do you have a NIB file called DetailViewController.xib in your project? Presumably not. Thus myDetViewCont will be nil and you'll get an exception. If you do have that NIB, then what is the push segue going between (because you can't segue from a storyboard to a NIB)?
Assuming that you really want to use storyboards, and not NIBs, if you already have a push segue between the controllers, give that segue an identifier (you do this in Interface Builder; in my code below I'll just use youridentifier as a placeholder for whatever you specify, which you'll replace with the correct identifier) and then you should transition using the segue:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *acell = [tableView cellForRowAtIndexPath:indexPath];
[self performSegueWithIdentifier:#"youridentifier" sender:acell];
}
If you want to send data to the new controller, you'd use prepareForSegue to do that:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"youridentifier"])
{
if ([sender isKindOfClass:[UITableViewCell class]])
{
UITableViewCell *selectedCell = sender;
UIViewController *myDetViewCont = segue.destinationViewController;
myDetViewCont.navigationItem.title = selectedCell.textLabel.text;
}
else
{
NSLog("%s Was expecting sender to be a tableviewcell", __FUNCTION__);
}
}
}

Found the solution to this. You need to have a UINavigationController in your story board. To do this take your first scene, click on it and go to tabs at top of xcode and do Editor>Embed in>Navigation controller, check the button to set the navigation controller as inital scene. Add the following code to hide the navbar at top.
self.navigationController.navigationBar.hidden = YES;
self.navigationController.navigationBar.translucent = NO;

Related

uitableView didSelectRowAtIndexPath "selected row not loading the detail view"

I have a table view with 7 rows, I want to click on my rows and load the detailView( uiViewController )
I can select the row and I can see the Log in console but it never loads the detail view
would you please give me some hits, what is the problem?
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
NSLog(#"selected rows");
MyBookDetailView *c = [[MyBookDetailView alloc] init];
[self.navigationController popToRootViewControllerAnimated:NO];
[self.navigationController pushViewController:c animated:YES];
}
I also try performSelectorOnMainThread but still it just clickable and I have problem to load my view controller, I also add delegate in - (void)viewDidLoad method,
Thanks in advance!
lates code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
MyBookDetailView *c = [[MyBookDetailView alloc] initWithNibName:#"MyBookDetailView" bundle:nil];
[self.navigationController pushViewController:c animated:YES];
}
Why you want to pop up all controllers withing navigationcontroller stack to root controller and same time your want to push up new MyBookDetailView (i hope its base class is UIViewController).
Anyways, MyBookDetailView *c = [[MyBookDetailView alloc] init]; also will not work for you. Because c object of UIViewController (MyBookDetailView) view is nil. I recommend use break point trace execution stack and variable that you trying to remove and adding on run time you will better know what going on in your program.
I think following code may work for you,
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
MyBookDetailView *c = [[MyBookDetailView alloc] initWithNibName:#"WriteYourNibNameIfYouCreate" bundle:nil];
[self.navigationController pushViewController:c animated:YES];
}

UITableView prepareForSegue assigning indexPath to sender?

In the code below I am just trying out setting up a segue directly from the UIViewController to a DetailViewController. I usually do the segue from the UITableViewCell (which I think is clearer) but this time I just wanted to try going directly from the ViewController using -tableView:didSelectRowAtIndexPath:
My question is: I got to a situation where I needed to access the UITableViewCell indexPath from within -prepareForSegue:sender: my solution was to send the indexPath via sender. Usually I would set sender to self here, I have looked around and I can't find any reference to this, I am just curious if using sender to pass an indexPath is acceptable? I am pretty sure it is, and I am sure I have read that you can somewhere before, but I can't find any reference to it now.
// ------------------------------------------------------------------- **
// DELEGATE: UITableView
// ------------------------------------------------------------------- **
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"%s", __PRETTY_FUNCTION__);
[self performSegueWithIdentifier:#"SEGUE_TWO" sender:indexPath];
}
// ------------------------------------------------------------------- **
// SEGUE: ViewController_ONE > DetailViewController
// ------------------------------------------------------------------- **
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
NSLog(#"%s", __PRETTY_FUNCTION__);
if([[segue identifier] isEqualToString:#"SEGUE_TWO"]) {
NSUInteger cellRow = [(NSIndexPath *)sender row];
DetailViewController *destinationController = [segue destinationViewController];
[destinationController setDataString:[[self dataList] objectAtIndex:cellRow]];
}
}
EDIT: What I was looking for in this case was
NSIndexPath *indexPath = [[self tableView] indexPathForSelectedRow];
essentially a way to get indexPath into -performForSegue:sender: without having to pass it via the sender parameter (in -performSegueWithIdentifier:sender:)
I typically avoid using the sender in prepareForSegue: because it could be anything. This makes asserting that your sender is what you are expecting more cumbersome and fragile. Also, I prefer to check for the class of the destinationViewController object rather than the segue name. Your functionality is tied to your object (or more specficially its interface), not the title of your segue, so checking your class makes it clear what you are trying to accomplish.
Below is the usual template I use in production when segueing from a UITableView. Note that you should always check if the destinationViewController is embedded in a nav controller and then check the class of the object as well to make sure you are handling it correctly. Finally, use an assert to ensure that somewhere down the line you haven't added some new segue that you forgot to handle.
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// unwrap the controller if it's embedded in the nav controller.
UIViewController *controller;
UIViewController *destVC = segue.destinationViewController;
if ([destVC isKindOfClass:[UINavigationController class]])
{
UINavigationController *navController = (UINavigationController *)destVC;
controller = [navController.viewControllers firstObject];
}
else
{
controller = destVC;
}
if ([controller isKindOfClass:[DetailViewController class]])
{
DetailViewController *vc = (DetailViewController *)controller;
NSIndexPath *ip = [self.tableView indexPathForSelectedRow];
[vc setDataString:[[self dataList] objectAtIndex:ip.row]];
}
else
{
NSAssert(NO, #"Unknown segue. All segues must be handled.");
}
}
You could use UITableView's method indexPathForCell. I hope you have a tableView instance variable.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if([sender isKindOfClass:[UITableViewCell class]]) {
NSIndexPath * indexPath = [self.tableView indexPathForCell:sender];
//Your code here
}
}

How to use pushViewController and popViewController

I want to A viewcontroller switch another B viewcontroller,First time,I push(press GuestBook Button)and TableView get information ok,and press back Button ok, push(press GuestBook Button) again,JSON data NSLog have message,but tableview data not appear!
what's happen?
PS:i use storyboard!Have a custom cell xib!
A.m
- (IBAction)toHostGuestBook:(id)sender {
hgbvc = [self.storyboard instantiateViewControllerWithIdentifier:#"ToHostGuestBookSegue"];
hgbvc.eventidStr = eventidStr;
NSLog(#"hgbvc.eventidStr:%#",hgbvc.eventidStr);
[self.navigationController pushViewController:hgbvc animated:YES];
}
B.m
- (IBAction)backToHostMainEventDetail:(id)sender {
[self.navigationController popViewControllerAnimated:YES];
}
B.m
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *GuestBookCellIdentifier = #"GuestBookCellIdentifier";
static BOOL nibsRegistered = NO;
if (!nibsRegistered) {
UINib *nib = [UINib nibWithNibName:#"GuestBookCell" bundle:nil];
[tableView registerNib:nib forCellReuseIdentifier:GuestBookCellIdentifier];
nibsRegistered = YES;
}
gbcell = [tableView dequeueReusableCellWithIdentifier:GuestBookCellIdentifier];
if (gbcell == nil) {
gbcell = [[GuestBookCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:GuestBookCellIdentifier];
}
NSDictionary *dict = [messageRows objectAtIndex: indexPath.row];
gbcell.nicknameStr = [dict objectForKey:#"vusr"];
gbcell.dateStr = [dict objectForKey:#"date"];
gbcell.messageStr = [dict objectForKey:#"message"];
return gbcell;
}
Add this and Try
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.tableView reloadData]; //your table view name
}
try to reload the table view data on below the code of popViewController this is work what you want
hgbvc the B controller is retained by the A controller. so, it doesn't released when the B controller poped out. When the B controller pushed again, the viewDidLoad method not called.
solution: extract the tableview load data method. call this method when you push B.
in B controller:
- (void)showDataWithEventId:(NSString *)eventId
{
//retrive data
//table view reload
}

Segue Headaches in Xcode

I have a tableview and I created a segue to push it to another view controller. Every now an then this segue breaks without me touching it I can guarantee. I didn't even edit the file I put it in.
My Code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *acell = [tableView cellForRowAtIndexPath:indexPath];
[self performSegueWithIdentifier:#"cellWasSelected" sender:acell];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"cellWasSelected"])
{
if ([sender isKindOfClass:[UITableViewCell class]])
{
UITableViewCell *selectedCell = sender;
ViewController *myDetViewCont = segue.destinationViewController;
myDetViewCont.navigationItem.title = selectedCell.textLabel.text;
}
}
}
First after clicking a cell xcode directs me to the file this segue pushes to.
It redirects me here: action:#selector(handleSingleTap:)];
I use this for my images to trigger this: [self.navigationController popToRootViewControllerAnimated:YES]
If I choose in Thread 1 my main view I see the problem is:
[self performSegueWithIdentifier:#"cellWasSelected" sender:acell];
But whats the problem I used this athousand times and it starts crashing without me changing it.
Your code don't have any bugs, the problem is somewhere else. May be you have not give the segue an identifier in interface builder. Try this code. It is working on my side, if your files don't have any problem it should run on your side too.
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
NSString* identifier = [segue identifier];
if ([identifier isEqualToString:#"cellWasSelected"]) {
NSLog(#"Performing Seque");
if ([sender isKindOfClass:[UITableViewCell class]]) {
NSLog(#"correct");
UITableViewCell *selectedCell = sender;
UIViewController* myDetViewCont = segue.destinationViewController;
myDetViewCont.navigationItem.title = selectedCell.textLabel.text;
}
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"%#",#"Cell Selected");
UITableViewCell* cell = [tableView cellForRowAtIndexPath:indexPath];
[self performSegueWithIdentifier:#"cellWasSelected" sender:cell];
}
P.S. If you are still having problems you, then may be you are new to storyboard and you need enough knowledge to work on them.
http://www.raywenderlich.com/5138/beginning-storyboards-in-ios-5-part-1

Pushing viewController from a tableview that is inside a viewController not working

I am having an issue pushing my view controller from a tableview that was dropped into a viewController, and not a TableViewController.
I have found a thread on here with a solution here
pushViewController is not pushing
The problem is.. I have done his solution and my view still does not push. I have connected my tableview via ctrl+drag to the view controller and set both the dataSource and delegate. In the post i mentioned, they say the solution was to 'create a referencing outlet from the tableview to the view controller.' But I don't exactly know what that means. So help with that would be good as well. I have followed this tutorial and am stuck on step 9 obviously.
The line of code not triggering is
[self.navigationController pushViewController:facility animated:YES];
My code is as follows...
viewTable methods
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSLog(#"list Size: %#",list);
return [list count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = (UITableViewCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
CustomerListData *customer = [self.list objectAtIndex:indexPath.row];
cell.textLabel.text = customer.facilityName;
// cell.textLabel.text = #"Detail";
return cell;
}
-(void)setValue:(NSMutableArray*)array
{
//NSMutableArray *newArray = [[NSMutableArray alloc] init];
list = array;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
FacilityMissionListViewController *facility = [self.storyboard instantiateViewControllerWithIdentifier:#"facilityMissionList"];
[self.navigationController pushViewController:facility animated:YES];
//UINavigationController* navController = self.navigationController;
}
the very last commented out line is there to check if navigationcontroller was null. It is not.
From what I have gathered the issue here lies in the fact the table view is inside the view controller and its not a "tableviewcontroller." This method apparently works if that is the case, but some other steps must be taken if not.. but I don't know them.
Thanks in advance.
It sounds like your NavigationController is not set up correctly. Could you post the code that sets it up?
Put a :
NSLog(#"%#", self.navigationController);
in your didSelectRowAtIndexPath method and you'll see if the method is being called and if the navigationController is nil. It might be one of this cases.
Otherwise make sure that the FacilityMissionListViewController is not nil either.