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]];
}
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?
My storyboard application flows like this:
When a button(let me call it "BtnA") is clicked it loads a table view(Let me call it "TblA").
Once clicked on particular cell, a corresponding image("ImgA") will be loaded in a image view.
On image view's top bar there is another button(let me call it "BtnB").When I click on the button(BtnB) one table view(Let me call it "TblB") as popover is loaded; And, its cell values as same as the previously loaded tableview("TblA") cell(that is tableview loaded after my initial button click).
Now, What I want is, when popover tableview("TblB") cell is selected I want to load my corresponding image("ImgA") back to the image view.How Can I do this?
Note: .Button("BtnB") is connected tableview("TblB") as popover segue.
I was referring to this(load images in an image view from a table in a popover ), but, its seems that its bit different as its loading tableview's cell image to the image view.
Hope my question explanation is understandable.Please help.
You can use delegation in this case. What you can is, create a protocol in TblB controller
#protocol TblBDelegate <NSObject>
-(void)didSelectCellWithImage:(UIImage*)image
#end
I passed the image here, but you can pass whatever you need.
You create a delegate property in TblB
#property (nonatomic, assign) id< TblBDelegate> delegate
Now you said you are presenting TblB popover with a segue. So in TblA, you implement prepareForSegue method and set TblA controller as the delegate
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"SEGUE NAME"]) {
TblBController *controller = (TblBController*)[segue destinationViewController];
controller.delegate = self;
}
}
Now in your TblA controller, you conform to protocol TblBDelegate, and implement the method
#interface TblAController <TblBDelegate>
#end
and in your .m file
-(void)didSelectCellWithImage:(UIImage*)image
{
// Update your imageView with new image
}
and in your TblB controller
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Get selected image
// and call your delegate method
if (self.delegate && [self.delegate respondsToSelector:#selector(didSelectCellWithImage:)]) {
[self.delegate didSelectCellWithImage:selectedImage]
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
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];
}