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];
Related
I have the delegate method I implement to pass data from FirstViewController to SecondViewController.
First, I created a text Field and Button in FirstViewController. Second, I created a label to display the data in SecondViewController.
How it should work:
The user will press the button in FirstViewController and it will pass the data to the secondViewController.In addition,the user will be using a UISwipeGestureRecognizer to navigate to the second view controller, so there's no need to use the button to go to the second view controller.
How I test the application
1- I run the application. --> 2- I type "Hello" in Text field --> 3- I press the button --> 4- I swipe to the second view controller to see the data --> 5- I don't see any data in the label ??
First i created the delegate protocol
FirstViewController.h
#class FirstViewController;
#protocol FirstControllerDelegate
-(void) updateLabel:(NSString*)string
#end
#property (weak, nonatomic) id<FirstViewControllerDelegate>delegate;
#property (weak, nonatomic) IBOutlet UITextField *TextField;
- (IBAction)button:(id)sender;
FirstViewController.m
#interface FirstViewController. ()
#end
#implementation ViewController1
#synthesize delegate;
#synthesize TextField;
-(void)viewDidLoad{
[super viewDidLoad];
}
- (IBAction)Button:(id)sender {
ViewController2 *vc2 = [[ViewController2 alloc] init];
vc2.stringfromTextfield1 = self.TextField.text;
}
SecondViewController.h
#import "SecondViewController.h"
#import "FirstViewController.h"
#interface SecondViewController : UITableViewController<FirstControllerDelegate>
#end
#property (weak, nonatomic) IBOutlet UILabel *Label;
#property (strong, nonatomic) NSString *stringfromTextfield1;
SecondViewController.m
#interface SecondViewController. ()
#end
#implementation SecondViewController
-(void)viewDidLoad{
[super viewDidLoad];
self.label.text = self.stringfromTextfield1;
}
I appreciate your time and effort to help me out
You can use Singleton class for this, or you can use extern NSString for move the string value one to second View Controller.
in first view controller.
extern NSString *MyStr;
in the #interface define it.
#interface{
NSString *MyStr;
}
In the #Implementation assign the value what you want.
and the second view controller just #import the first view and use,
MyStr As a variable and its having the value also from first view controller.
This thing worked for me.
Or simply add an AppDelegate property to store the variable in both ViewControllers:
AppDelegate *appDel=[[UIApplication sharedApplication] delegate];
appDel.variable=#"text";
You can save data in App delegate and access it across view controllers in your application.You have to create a shared instance of app delegate.
AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
like this
Suppose you declare a NSString object *strthen you can access it in any view controller by appDelegate.str
Basically, I have two UIViewControllers, there are some buttons in one of them. Once the user touches the button in one of the View Controllers, I want to trigger some actions in another view controller. But it seems not working somehow. Basically, the "if" condition which is:
if (self.delegate && [self.delegate respondsToSelector:#selector(userDidTouchButtons:)])
{
[self.delegate userDidTouchButtons:self];
}
seems not working, because the [self.delegate respondToSelector]is always false.
This is the .h file of the first view controller, which has some buttons.
#import
#class RightSideMenuViewController;
#protocol RightSideMenuDelegate <NSObject>
- (void) userDidTouchButtons: (RightSideMenuViewController *) rightMenuViewController;
#end
#interface RightSideMenuViewController : UIViewController
#property (nonatomic, assign) id <RightSideMenuDelegate> delegate;
#end
This is the .m file of the first view controller.
- (IBAction)badmintonClicked:(UIButton *)sender
{
if (self.delegate && [self.delegate respondsToSelector:#selector(userDidTouchButtons:)])
{
[self.delegate userDidTouchButtons:self];
}
}
This is the .m file of the second view controller, where I want to trigger the action here, according to the buttons in the first view controller.
#import "RightSideMenuViewController.h"
#interface DiscoverTimelineTableViewController () <RightSideMenuDelegate>
#property (strong, nonatomic) RightSideMenuViewController *rightMeuViewController;
#end
- (void)viewDidLoad {
[super viewDidLoad];
self.rightMeuViewController.delegate = self;
}
#pragma mark - RIGHT MENU Delegate methods
- (void) userDidTouchButtons: (RightSideMenuViewController *) rightMenuViewController
{
NSLog(#"He touches me!!!");
}
Make sure that the delegate is properly set, i.e., self.rightMeuViewController should not be nil
it seems like you are not setting the rightMeuViewController property while navigating to second view controller
I am implementing one simple delegation between the Master and Detail views (Landscape orientation so both views are visible) in a SplitViewController. When I press a button, the table view in Detail should update.
Here is the declaration in
MasterViewController.h
#protocol DetailVCDelegate <NSObject>
- (void)requestTableUpdate;
#end
#interface MasterViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
- (IBAction)updateTable:(id)sender;
#property (nonatomic, weak) id <DetailVCDelegate> delegate;
in MVC.m i Do the following for the IBaction updateTable:
[self.delegate requestTableUpdate];
Then in the Detail.h
#import "MasterViewController.h"
#interface DetailViewController : UITableViewController <DetailVCDelegate>
And in the Detail.m
- (void)requestTableUpdate
{
NSLog(#"called");
[self.tableView reloadData];
}
The log is never called, nor the update for the tableView.
I would appreciate any suggestions of how to fix this, i guess I am missing some delegation rule that is specific for SplitViews
When you send a message to something and nothing happens, your first thought should be: hmm, maybe I'm sending a message to nil.
So, you say:
[self.delegate requestTableUpdate];
But nothing happens. So you should immediately check to see whether self.delegate is nil.
You have a declared a delegate property:
#property (nonatomic, weak) id <DetailVCDelegate> delegate;
But a property has no value until you give it one. It is up to you to set the delegate property of your MasterViewController instance to some other instance (of something that adopts the DetailVCDelegate protocol, obviously). Delegates are not born: they are made, deliberately.
i want to refresh my main view on slide menu did select method with categorically
i have used SWRevealViewController to load my slide menu and its working fine but i cant understand how to assign delegate to the slide menu controller and use it?
here is the link for awesome library by john lusch
slide menu controller.h
#protocol SlideViewControllerDelegate
#required
-(void)menuViewControllerDidFinishWithCategoryId:(NSInteger)categoryId;
#end
#interface SlideViewController :
UIViewController<UITableViewDataSource,UITableViewDelegate>
{
__weak id<SlideViewControllerDelegate> slideDelegate;
}
#property (nonatomic, weak) id <SlideViewControllerDelegate> slideDelegate;
#end
slide menu controller.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.slideDelegate menuViewControllerDidFinishWithCategoryId:indexPath.row];
}
viewController.h
#interface ViewController : UIViewController<UITableViewDataSource,UITableViewDelegate,SlideViewControllerDelegate>
viewController.m
in my view did load method
SlideViewController *slideView = [[SlideViewController alloc]init];
slideView.slideDelegate = self;
- (void)menuViewControllerDidFinishWithCategoryId:(NSInteger)categoryId
{
self.categId = [catIdArray objectAtIndex:categoryId];
NSLog(#"cat id %#",categId);
[self getQuestions];
[self.feedTableView reloadData];
}
//Log above is never executed
so i think may be i am wrong with assigning delegate to the swreveal view controller slide menu
got it to set a delegate to a reveal controller do like this
[(SlideViewController *)self.revealViewController.rearViewController setSlideDelegate:self];
Maybe you should init SlideViewController by
- (id)initWithRearViewController:(UIViewController *)rearViewController frontViewController:(UIViewController *)frontViewController;
which says in the README.md.
Remove that lines:
{
__weak id<SlideViewControllerDelegate> slideDelegate;
}
Your property:
#property (nonatomic, weak) id <SlideViewControllerDelegate> slideDelegate;
it's enought.
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.