Here is what I wish to do:
There is a parent ViewController. On parent's load, ChildVC is called which contains a UITableView.
Now on childView's table's didSelectRowAtIndexPath method, I wish to pass the selected cell content to parentView. And from parentView I wish to load a second viewController.
How do I do this by delegate?
Edited:
Child :
#class ViewController;
#protocol CustomViewControllerDelegate;
#interface CustomViewController : UITableViewController
{
AppDelegate *appDelegate;
id<CustomViewControllerDelegate> delegate;
}
#property(nonatomic, weak) id<CustomViewControllerDelegate> delegate;
#end
#protocol CustomViewControllerDelegate
-(void)didSelectRow:(NSString *)str;
#end
parent
#class CustomViewController;
#interface ViewController : UIViewController<CustomViewControllerDelegate> // i get the error here
{
AppDelegate *appDelegate;
}
On ChildVC declare a protocol:
#protocol ChildVCDelegate
- (void)didSelectCell:(SomeContent *)content;
#end
Also add the delegate:
#property (nonatomic, weak) id<ChildVCDelegate> delegate;
In the implementation of didSelectRowAtIndexPath, add:
if (_delegate) {
[_delegate didSelectCell:someContent];
}
In the parent view controller implement didSelectCell and when it creates/shows the ChildVC, set it as the delegate.
I'm not sure what kind of content you want to pass to the parent, so I represented it as SomeContent, but it can be whatever you want to pass.
Related
I'm trying to dismiss a popover when selecting a cell inside of it.
I have created a custom delegate to support this however it is not working:
In my class that houses the PopOver and table View I have the following:
In .h:
#protocol DismissDelegate <NSObject>
-(void)didTap;
#end
#interface AssistanceNeededAtPopOverViewController : UIViewController<UITableViewDataSource,UITableViewDelegate>
#property (nonatomic, assign) id <DismissDelegate> delegate;
In .m:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[self.delegate didTap];
}
In .h of the viewcontroller where the popover lives in:
#interface GlobalPageSideDetailViewController : BaseViewController <UITextFieldDelegate, UIAlertViewDelegate,UIPopoverControllerDelegate,DismissDelegate>
and in .m:
AssistanceNeededAtPopOverViewController *classpop = [[AssistanceNeededAtPopOverViewController alloc]init];
classpop.delegate = self;
-(void)didTap{
if (self.assistanceNeededAtPopover != nil) {
[self.assistanceNeededAtPopover dismissPopoverAnimated:YES ];
self.assistanceNeededAtPopover = nil;
}
}
this should be read and the popover should be dismissed...any help would be appreciated...
You have to set the delegate of your AssistanceNeededAtPopOverViewController that pops the controllerview, as the new GlobalPageSideDetailViewController.
Here you're setting the delegate of a controller you just instantiate and not the one which poped the controller.
I'm creating a custom UIView subclass (shareView) from a Nib.
I created a custom protocol for shareView like this:
#protocol sharePopupDelegate
#required
-(void)userPublishedContent;
-(void)userAbortedPublish;
#end
#interface shareView : UIView
{
id<sharePopupDelegate> delegate;
}
In my main.storyboard I created a custom UIViewController myViewController with a shareView view instance called "popup" inside.
So now I got
#property (weak, nonatomic) IBOutlet shareView *popup;
I would like now to delegate myViewController from shareView methods i declared, so I did
self.popup.delegate = self;
inside myViewController but the protocols' methods are not being called inside myViewController.
So i correctly see the shareView instance but cannot interface to its delegate.
Can you help me please?
Thanks in advance
Make sure that you have the protocol declared in myViewController.
For example
#interface MyViewController : UIViewCOntroller <sharePopupDelegate>
In this section of the code:
#interface shareView : UIView
{
id<sharePopupDelegate> delegate;
}
You are creating a strong reference to the delegate, which is not what you want most of the time. Change it to this:
#interface shareView : UIView
#property(weak, nonatomic) id<sharePopupDelegate> delegate;
The shareView class itself must have some way to know when a user publishes content. Maybe you have an action linked up to the shareView which calls a method in the shareView class. For examaple:
- (void)publishButtonTapped {
// some code
}
What you want to do is let the delegate know in that method, something like this:
- (void)publishButtonTapped {
// some code
[self.delegate userPublishedContent];
}
Then whatever action the user takes to cancel:
- (void)cancelButtonTapped {
// some code
[self.delegate userAbortedPublish];
}
Hope this helps.
I have this problem that I want to hide the container view from the parent VC when I tap a table cell at the last VC on the right.
I tried hooking up a protocol delegate but it did not work.
Here is my failed attempt:
I added the Protocol on the GOCategoryMenuViewController.
#protocol GOCategoryMenuViewControllerDelegate <NSObject>
-(void)hideMenu;
#end
#interface GOCategoryMenuViewController : UIViewController
#property(weak, nonatomic) id <GOCategoryMenuViewControllerDelegate> delegate;
#end
Implement hideMenu in the .m file
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.delegate hideMenu];
}
Import the header and delegate to the parentVC
#import "GOCategoryMenuViewController.h"
#interface ViewController : UIViewController<GOCategoryMenuViewControllerDelegate>
Implement the hideMenu in the .m of ParentVC
-(void)hideMenu
{
NSLog(#"Hide the menu");
}
I believe I need to also declare self on the delegate, but I don't know how and I tried searching for a solution on the web to no avail. It's why I'm asking directly now to you all. Please help and thanks!
Your protocols is true, only thing you have to do is when you init instance of GOCategoryMenuViewController you should give it a delegate sth like this:
GOCategoryMenuViewController *category = [[GOCategoryMenuViewController alloc] init];
//if you don't give delegate, never your delegate method will get called
category.delegate = self;
You have to delegate your instance of GOCategoryMenuViewController class.
If you want to solve it with delegates only, then you must pass the parent view controllers controls delegates to the child view controllers with declaring the properties that has the same type with the parent control in the child view controller. Then you can do any operation on the parent view's control in the child view controller.
ParentViewController.h class
#interface ParentViewController : UIViewController
{
NSMutableDictionary *dictOfPeople;
}
#property(nonatomic, retain) NSMutableDictionary *dictOfPeople;
ParentViewController.m class
#synthesize dictOfPeople;
- (void)anyMethod
{
//initialize child view controller
ChildViewController *childViewController = [[ChildViewController alloc] init];
// here is important
childViewController.owner = self;
}
ChildViewController.h class
#interface ChildViewController : UIViewController
{
id owner;
}
#property(nonatomic, assign) id owner;
ChildViewController.m class
#synthesize owner;
- (void)anyMethod
{
// You can access parent view controllers dictOfPeople dictionary like this
int totalNum = [((ParentViewController *)self.owner).dictOfPeople count];
//...
}
I have an initial ViewController, lets call it HomeViewController, that has a button which calls a modal view controller, lets call it ModalViewController. Inside that ModalViewController I have a table view with two sections. If you click on any cell from section 0 it sends information back to HomeViewController (this part I have working with Protocol). If you click on any of the cells from section 1 it pushes to another view controller with options, lets call it OptionsViewController. Here is where it gets tricky for me. If you click any of those options, dismiss OptionsViewController and close ModalViewcontroller and send that information to HomeViewController, just like ModalViewController to HomeViewController. I have tried to set up a protocol similar to the one in ModalViewController but it is never called.
OptionsViewController protocol & .h file
#protocol OptionsViewControllerDelegate <NSObject>
#optional
-(void) optionsInfo:(NSArray *)optionsViewArray;
#end
#interface OptionsViewController : UITableViewController
#property (retain) id delegate;
#property (nonatomic, strong) NSArray *sendArray;
#end
OptionsViewController.m where it's called to pop off the stack.
{
[self dismissOptionsView];
}
-(void) viewWillDisappear:(BOOL)animated
{
NSLog(#"Send Array: %#", self.sendArray);
[[self delegate] optionsInfo:sendArray];
}
-(void)dismissOptionsView
{
[self.navigationController popViewControllerAnimated:YES];
}
Inside ModalViewController.h
#protocol ModalViewControllerDelegate <NSObject>
#optional
-(void) sendInformation:(NSArray *)infoArray;
#end
#interface ModalViewController : UITableViewController <ConditionsViewControllerDelegate, UISearchBarDelegate>
{
UISearchBar *searchDrugBar;
}
#property (retain) id delegate;
#property (nonatomic, strong) IBOutlet UISearchBar *searchDrugBar;
#property (nonatomic, strong) NSArray *infoArray;
#end
ModalViewController.m where OptionsInfo is supposed to come in.
-(void) optionsInfo:(NSArray *)optionsViewArray
{
//IT NEVER REACHES HERE :(
NSLog(#"HERE");
self.infoArray = optionsViewArray;
NSLog(#"Finished");
[self dismissViewControllerAnimated:YES completion:nil];
}
Has any one has done something similar like this or knows the solution to this? Any information, link, guidance and etc. to the right direction will be appreciated. Thanks in advance.
You need to set the delegate in your OptionsViewController below:-
In your OptionsViewController.m Include below line on your method
[self setDelegate:ModalViewController];
In UINavigationController this is child controller
.h
#protocol childProtocol <NSObject>
-(void)childMethod:(NSArray*)params;
#end
#property (strong, nonatomic) id<childProtocol>childDelegate;
#property (weak, nonatomic) parentVC *pVC;
.m
if([self.childDelegate respondsToSelector:#selector(childMethod:)]) {
[self.childDelegate performSelector:#selector(childMethod:) withObject:self.arry];
}
This is my parent controller
.m
-(void)childMethod:(NSArray *)params {
// some work
}
...
childVC *cVC = [[childVC alloc]init];
cVC.pVC = self;
But childMethod: is not getting called so I searched on internet and got this post
UINavigationControllers: How to pass value to higher (parent?) controller in stack?
I tried to create a weak reference but dont know how to use to make delegate pass data from child to parent?
Try this. Check the sample project attached
ParentViewController.h
#import <UIKit/UIKit.h>
#interface ParentViewController : UIViewController
- (void)passData:(NSString *)strText;
#end
ParentViewController.m
- (IBAction)btnGoToSecondView:(id)sender {
ChildViewController *secondVC = [[ChildViewController alloc] initWithNibName:#"ChildViewController" bundle:nil];
secondVC.delegate = self;
[self presentViewController:secondVC animated:YES completion:nil];
}
- (void)passData:(NSString *)strText {
NSLog(#"Data Passed = %#",strText);
}
ChildViewController.h
#import <UIKit/UIKit.h>
#import "ParentViewController.h"
#class ParentViewController;
#interface ChildViewController : UIViewController
#property(nonatomic, assign) ParentViewController *delegate;
#end
ChildViewController.m
- (IBAction)btnPassDataBack:(id)sender {
if([self.delegate respondsToSelector:#selector(passData:)]) {
[self.delegate passData:#"Hello"];
}
[self dismissViewControllerAnimated:YES completion:nil];
}
Sample Project
This is child controller.h
#protocol childProtocol <NSObject>
-(void)childMethod:(NSArray*)params;
#end
#property (strong, nonatomic) id<childProtocol>childDelegate;
#property (weak, nonatomic) parentVC *pVC;
.m
if([self.childDelegate respondsToSelector:#selector(childMethod:)]) {
[self.childDelegate performSelector:#selector(childMethod:) withObject:self.arry];
}
This is my parent controller.h
#import <UIKit/UIKit.h>
#import "ChildController.h"
#interface perentController : UIViewController < childProtocol >
.m
- (void)childMethod:(NSArray *)params {
// some work
}
EDITED :
And Dont Forget to add childViewOBJ.childDelegate = self; at the time of create ChildViewController's object. such like,
childVC *cVC = [[childVC alloc]init];
cVC.childDelegate = self;
cVC.pVC = self;
[self presentModalViewController:cVC animated:YES];
For More information about How to create/use of Protocol.
First of all, you are not checking for the same selector as you declared in your protocol declaration so it won't respond to that. You declared the method childMethod: whereas you are checking if your childDelegate responds to myMethod: selector which does not so it won't go into the if condition.
Also the parent view controller is missing the implementation the method childMethod: in its .m. Implement that in your parent view controller or it will crash because of not finding the exact selector definition.
Since you are using a UINavigationController, the parent view controller won't be lost till the child view controller exist so the childDelegate property must not be strong unless you intend to hold onto your delegate in child view controller for some reason.