have a question. I have an ipad app that contains a View Controller with a UITableView and a detail view (which is basically another view controller to display details) on the same screen. I need to pass the row data from UITableView when the -didSelectRowAtIndexPath is executed to this detail view. I am not sure how to go about doing this? Any help/pointers/sample code on how to go about doing this?
Thanks for your help in advance
Define a delegate in the UITableView view controller, and implement it in the detail view controller. When didSelectRowAtIndexPath is invoked, call the delegate method, passing the row data to the detail view controller.
The delegate definition will look something like:
#class MyTopLevelViewController;
#protocol MyTopLevelViewControllerDelegate <NSObject>
-(void)showDetail:(DetailObject *)detail;
#interface MyTopLevelViewController : UIViewController
#property (nonatomic, weak) id <MyTopLevelViewControllerDelegate> delegate;
#end
and adding the delegate to the detail view controller header:
#interface MyDetailViewController : UIViewController <MyTopLevelViewControllerDelegate>
If you are willing to pass the data on another view controller in didSelectRowAtIndexPath on same screen, you can use array as you get "objectAtIndex:indexPath.row". Following code might help you:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
DetailFoodViewController *detailFoodViewController=[[DetailFoodViewController alloc] initWithNibName:#"DetailFoodViewController" bundle:nil];
JSCategory *jSCategory=[self.categoryResult.JSCategories objectAtIndex:indexPath.row];
detailFoodViewController.jsCategory=jSCategory;
detailFoodViewController.oldStoreLocationId=self.oldStoreId;
[self.view addSubview:detailFoodViewController.view];
[detailFoodViewController release];
}
Related
How do I transfer data from my UITableViewCell to a UIViewController through a UINavigationController? As an example, what I want to do is transfer the UITableViewCell label name from the cell to the ViewController's label. If you look at the two pictures, you will see what I mean. Also, on another note, how in general do I transfer data from one view to another? Thanks
in Receiver view controller
in .h file
#interface ViewController : UIViewController
#property (strong, nonatomic) NSString *strDataOfCell;
#end
here make it strong so stays in memory
in table view delegate method
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
ViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:#"yourViewIdentifer"];
NSString *strData = [self.yourArrayOfData objectAtIndex:indexPath.row]; // Here Put your code to Get value from data source array , which is loaded in tableview
vc.strDataOfCell = strData;
[self.navigationController pushViewController:vc animated:YES];
}
Hope it helps :)
You can declare properties in the view controller header file you want to transfer.
If you navigate through code. You can assign the label to this view controller in table view didSelectRowAtIndexPath.
If you navigate through storyboard segue. You can assign the label to this view controller in prepareForSegue:sender:.
The answer to my question resides in the "prepareForSegue" method. It's all about manipulating the sender object to send it's data to the next view controller, and the setting next view controller's data based on the sender. I casted the sender to a custom UITableViewCell, took the cell's title, set a navigation controller's rootview to the view controller that was going to receive the data, and boom, gave it the data.
I have a slide menu. It is implemented using component SWRevealViewController. To implement it I have 1 main UIViewController (VC) - SWRevealViewController. I have menu VC and I have push segues to navigate to different menu's VCs.
For the menu I use prototype cells with custom class for each menu.
My problem is that I need to call unwind segue to go to login VC, using alert view. To do that I try usual method [self performSegueWithIdentifier:#"unwSegReturnToLogin" sender:self]; on positive answer from the alert view (inside custom class for exit cell). I have such method declared in my login VC. I receive error during the compilation:
No visible #interface for 'tvcellExitMenuItem' declares
the selector 'performSegueWithIdentifier:sender:'
I suspect that the problem is that self in my case is table cell and that is not UIViewController.
How to refer parent VC if this is the case?
If not, please tell me where I am wrong in the logic.
A subview shouldn't have to know about its parent viewController. Instead, a common pattern that fits your need is the delegate pattern : define a delegate property & protocol for your cells' class.
// your cell class header might look like this
#class MyCellClass;
#protocol MyCellDelegate
- (void)onCellSelected:(MyCellClass *)cell;
#end
#interface MyCellClass
#property (nonatomic, weak) id<MyCellDelegate> delegate;
#end
For example, if your viewController is also your UITableViewDatasource , then in tableView:cellForRowAtIndexPath: you can set your cell's delegate to self, and call the segue methods in delegate method.
- (void)onCellSelected:(MyCellClass *)cell
{
// retrieve cell indexPath
NSIndexPath *cellIndexPath = [self.tableView indexPathForCell:cell];
// using indexPth, retrieve cell's data
// push segue with data selected
}
Of course, this is only an example, and there are other corrects ways to do that.
I have a button on UIViewController on click of that button an UIview gets poped up like alertview which has tableview in it.Now on selection of table cell i would like to segue to the detail viewcontroller
Here's the link to which i refered but none of them worked for me
For alertview i have used (https://github.com/kwent/ios-custom-alertview)
Thanks.
#yar1vn's answer is right, however, I'll describe more precisely what you need to do.
Custom alert view from your link has a delegate property, which should conform to protocol
#protocol CustomIOS7AlertViewDelegate
- (void)customIOS7dialogButtonTouchUpInside:(id)alertView clickedButtonAtIndex:(NSInteger)buttonIndex;
#end
that means you should implement this method in your UIViewController.
in .h file:
#interface YourViewController : UIViewController <YourViewController>
...
#end
in .m file:
#implementation YourViewController
...
- (void)customIOS7dialogButtonTouchUpInside:(id)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
[self performSegueWithIdentifier:#"YourSegue" sender:nil];
}
and set the delegate when creating alertView:
[alertView setDelegate:self];
#"YourSegue" is the segue from the controller which shows alertView to the detail view controller.
I disagree that you should use UIAlertController, since if your deployment target is iOS 7 (which is reasonable) you should not use new features of iOS 8
EDIT:
if you want to launch segue from tap on table view cell, you should call [self performSegueWithIdentifier:#"YourSegue" sender:nil] from tableView's delegate method -tableView:didSelectRowAtIndexPath:
I assume you have set current view controller as tableView's dataSource and delegate, so add to your view controller
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self performSegueWithIdentifier:#"YourSegue" sender:nil];
}
EDIT 2:
though setting the UIView as delegate is not the best approach, we can handle it :)
I see two solutions:
the first is to add the controller as the property to your view like this:
#interface YourView : UIView <UITableViewDelegate, UITableViewDataSource>
#property (nonatomic, weak) YourViewController *parentController;
...
somewhere (probably, in -viewDidLoad) you set this property as
youViewInstance.parentController = self;
and the in view's delegate method call
[self.parentController performSegueWithIdentifier:#"YouSegue" sender:nil]
the second one is to simply set the controller as tableView's delegate and call performSegue: from its method. And you should describe all details more completely :)
You shouldn't use 3rd party AlertViews anymore. You can use the AlertController provided with iOS 8 SDK.
I don't know how this AlertView works but the readme mentions a delegate. Did you try calling the segue from the delegate method?
This question already has answers here:
dismissModalViewController AND pass data back
(4 answers)
Closed 9 years ago.
I have a popoverview with a table, and I want to pass back some data when I click on a cell, but I don't know how to do...
Familiarize yourself with the delegate pattern.
Define a method in a protocol for passing down the data.
Set the view controller as the popover controller's delegate. The view controller should implement the protocol.
In the popover controller pass this data when the button is pressed.
In the view controller process this data accordingly.
Dude you can try delegates if the table view is in a different class or if table view is in the same class just see didSelectRowAtIndexPath:
Writing a delegate:
In .h file of popover table class:
#protocol PopOverSelectionDelegate;
#property (nonatomic,weak) id <PopOverSelectionDelegate> delegate;
#protocol PopOverSelectionDelegate
#optional
- (void)popOverItemSelected:(NSString *)selectedItem;
#end
In .m file
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.delegate popOverItemSelected: [yourArray objectAtIndex:indexPath.row]];
}
I have a UITableViewController within a UIViewController. While this table viewcontroller was the only one involved, it was pushing views just fine when the user would tap a row. However, ever since I moved it to be one of two contained within the UIViewController, the taps of rows suddenly do nothing.
I've tried searching around and I'm not the first to run into this problem, but none of the answers fit my circumstances or the questions have no working answers. That link was the closest I found, but I'm not using storyboards -- I'm using separate XIBs.
So how do I push a new view from a viewcontroller within a viewcontroller?
To recap:
Here is what I had, and it worked fine in taking users to a new screen!
// Normal table behavior, as illustrated by [another question][2].
- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
SomeView *detailViewController = [[SomeView alloc] initWithNibName:#"SomeView" bundle:nil];
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
}
Now I have the viewcontroller as a property in a view -- and the above code, which is in the file for the tableviewcontroller and not at the "main" view, doesn't cause a new screen to appear anymore!
Thanks for the comments! Here's some code to clarify my scenario.
The controllers within a controller. This is a file from a test project I've been using to test the concept out. In this case, I have a tableview controller within a tableview controller.
#interface SimpleTableViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
// This is the controller within the controller
#property IBOutlet SecondTableViewController *secondTableController;
#property IBOutlet UITableView *secondTable;
My SecondTableViewController has this fun bit.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here. Create and push another view controller.
UIViewController *detailViewController = [[UIViewController alloc] initWithNibName:#"SimpleNonTableViewController" bundle:nil];
// ...
// Pass the selected object to the new view controller.
[manualViewControllerParent.navigationController pushViewController:detailViewController animated:YES];
}
The view that the user interacts with is hooked up to SimpleTableViewController. In this way, SecondTableViewController is "within" SimpleTableViewController. Feel free to comment if you'd like more details!
I've put my test/concept project on github. https://github.com/hyliandanny/TableViewCeption
You need to use a custom container controller to do what you want. It would be easiest if you used a storyboard, but you can do it in code with xibs as well. The outer controller should be a UIViewController, not a table view controller. You can do something like this (in the outer controller):
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
UIViewController *detailViewController = [[UIViewController alloc] initWithNibName:#"SimpleNonTableViewController" bundle:nil];
[self addChildViewController:detailViewController];
detailViewController.view.frame = set the frame to what you want;
[self.view addSubview:detailViewController.view];
[detailViewController didMoveToParentViewController:self];
}
You should read up on Apple's documentation for custom container controllers.
What you need to make sure:
Your UITableView delegate is hooked up to your controller. Otherwise it wouldn't call didSelectRow. You can do this in xib or in viewDidLoad method.
Your self.navigationController is not nil
Your detailViewController is not nil
I also think that what you mean is you have UITableView inside your UIViewController. UITableView is only the view, whereas UITableViewController is a controller. You can't have a controller inside another controller.