On a button press, I am trying to send data from Collection View Controller to my View Controller. Here is what I have so far:
CollectionViewController.h
#import <UIKit/UIKit.h>
#class CollectionViewController;
#protocol CollectionViewDelegate <NSObject>
-(void) sendTest;
#end
#interface CollectionViewController : UICollectionViewController
#property (nonatomic, weak) id<CollectionViewDelegate> deligate;
#end
CollectionViewController.m
-(void) viewDidLoad {
[super viewDidLoad];
}
...
NSLog(#"check");
[self.deligate sendTest];
NSLog(#"called");
FooViewController.m
#import "CollectionViewController.h"
#interface FooViewController () <CollectionViewDelegate> {}
#end
#implementation FooViewController
- (void)viewDidLoad {
[super viewDidLoad];
CollectionViewController *controler = [[CollectionViewController alloc] init];
controler.deligate = self;
}
- (void) sendTest {
NSLog(#"Delegates are great!");
}
Unfortunaly when I call [self.deligate sendTest]; nothing happens. I know it is called, because I get the check, called logs.
The main wrong thing is that you are creating a CollectionViewController yourself, but you shouldn't. The CollectionViewController that you want is instantiated automagically by the Storyboard. How to find this view controller?
1 - Catch it during the segue in FooViewController:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
CollectionViewController *collectionViewController =(CollectionViewController *) segue.destinationViewController;
collectionViewController.deligate = self;
}
2 - Find it in within the child view controllers in FooViewController
self.childViewControllers
Does it help you?
Related
I want to transfer data from view controller to second view controller using delegate. What mistake I am doing, why my protocol is not confirming on second view controller. Code:
"This Is my view Controller code"
ViewController.h
#import <UIKit/UIKit.h>
#import "SecondViewController.h"
#protocol ViewControllerProtocol <NSObject>
-(void)passData:(NSString*)data;
#end
#interface ViewController : UIViewController
#property id<ViewControllerProtocol>delegateVC;
#property (weak, nonatomic) IBOutlet UITextField *txtFieldVC;
- (IBAction)btnSendVC:(id)sender;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (IBAction)btnSendVC:(id)sender {
[self.delegateVC passData:self.txtFieldVC.text];
[self performSegueWithIdentifier:#"next" sender:self];
}
#end//
"This is my second view Controller code"
SecondViewController.h
#import <UIKit/UIKit.h>
#import "ViewController.h"
#interface SecondViewController : UIViewController<ViewControllerProtocol>
- (IBAction)btnSVC:(id)sender;
#property (weak, nonatomic) IBOutlet UITextField *txtFieldSVC;
#end
// SecondViewController.m
#import "SecondViewController.h"
#interface SecondViewController ()
#end
#implementation SecondViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)passData:(NSString *)data {
self.txtFieldSVC.text = [NSString stringWithFormat:#"%#",data];
NSLog(#"Data Received: %#",data);
}
- (IBAction)btnSVC:(id)sender {
[self.navigationController popViewControllerAnimated:YES];
}
#end
Where Iam wrong is that I am missing something...
If we use above code,it is not possible to send the data from First View Controller to Second View Controller using Custom Delegate.But if we want to send data from Second View Controller to First View Controller,it is possible.If you want to send the data from Next View Controller to Previous View Controller you can do it using Custom Delegate and Notification methods.
Now your requirement is you have to send the data from First View Controller to Second View or Next View Controller.For that you can use prepareForSegue and performSegueWithIdentifier method for storyboard.It is enough.
I am trying to get a string from a view controller to another using delegate method.But the delegate method is not getting called.Below is the code
#protocol CustomDelegate<NSObject>
-(void)didDataRecieved;
#end
#interface CustomController:UIViewController
#property id<CustomDelegate>delegate;
#property(retain,nonatomic)NSString *string;
#end
#implementaion CustomController
-(void)viewDidLoad
{
string=#"hello";
if([self.delegate respondsToSelector#selector(didDataRecived)]) {
[self.delegate didDataRecieved];
}
}
-(IBACTION)gotoViewController
{
ViewController *view=[self.storyboard instantiateViewController:#"View"];
[self.navigationController pushViewController:view aniamted:YES];
}
#end
#interface ViewController:UIViewController<CustomDelegate>
#property (nonatomic,retain)CustomController *cust;
#end
#implementation ViewController
-(void)viewDidLoad
{
self.cust=[[CustomController alloc]init];
self.cust.delegate=self;
}
-(void)didDataRecieved
{
NSLog(#"data %#",self.cust.string);
}
#end
Can anyone point out where am going wrong...plz help.
edited the code..tried this way too.
if([self.delegate respondsToSelector#selector(didDataRecived)]){
[self.delegate didDataRecieved];
}
I will give you the sample coding.Customize the below code.
Here we have two view controllers.
ViewController
and
SecondViewController
in SecondViewController
.h
#import <UIKit/UIKit.h>
#class SecondViewController;
#protocol SecondViewControllerDelegate <NSObject>
- (void)secondViewController:(SecondViewController *)secondViewController didEnterText:(NSString *)text;
#end
#interface SecondViewController : UIViewController
#property (nonatomic, assign)id<SecondViewControllerDelegate> delegate;
#property (nonatomic, strong) IBOutlet UITextField *nameTextField;//It must connect as outlet connection
- (IBAction)doneButtonTapped:(id)sender;
#end
.m
#import "SecondViewController.h"
#interface SecondViewController ()
#end
#implementation SecondViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
//Either use NSNotification or Delegate
- (IBAction)doneButtonTapped:(id)sender;
{
//Use Notification
[[NSNotificationCenter defaultCenter] postNotificationName:#"passingDataFromSecondViewToFirstView" object:self.nameTextField.text];
//OR Custom Delegate
[self.delegate secondViewController:self didEnterText:self.nameTextField.text];
[self.navigationController popViewControllerAnimated:YES];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
in ViewController
.h
#import <UIKit/UIKit.h>
#import "SecondViewController.h"
#interface ViewController : UIViewController<SecondViewControllerDelegate>
#property (nonatomic, strong) IBOutlet UILabel *labelName; //You must connect the label with outlet connection
- (IBAction)gotoNextView:(id)sender;
#end
.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
//addObserver here...
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(textFromPreviousViewControllerNotificationReceived:) name:#"passingDataFromSecondViewToFirstView" object:nil];
// Do any additional setup after loading the view, typically from a nib.
}
//addObserver Method here....
- (void)textFromPreviousViewControllerNotificationReceived:(NSNotification *)notification
{
// set text to label...
NSString *string = [notification object];
self.labelName.text = string;
}
- (IBAction)gotoNextView:(id)sender;
{
//If you use storyboard
SecondViewController *secondViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"SecondViewController"];
//OR If you use XIB
SecondViewController *secondViewController = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
secondViewController.delegate = self;
[self.navigationController pushViewController:secondViewController animated:YES];
}
//Calling custom delegate method
- (void)secondViewController:(SecondViewController *)secondViewController didEnterText:(NSString *)text
{
self.labelName.text = text; //Getting the data and assign the data to label here.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
For your understanding the code I create a simple passing data from one second view controller to first view controller.
First we navigate the view from first view controller to second view controller.
After that we send the data from second view controller to first view controller.
NOTE : You can either use NSNotification or Custom Delegate method for sending data from One View Controller to Other View Controller
If you use NSNotification, you need to set the postNotificationName for getting data in button action method.
Next you need to write addObserver in (sending data to your required View Controller) ViewController and call the addObserver method in same View Controller.
If you use custom delegate,
Usually we go with Custom Protocol Delegate and also we need to Assign the delegate here.
Very importantly we have to set the Custom Delegate Method in the Second View Controller.Because where we send the data to first view controller once we click the done button in second view controller.
Finally we must call the Custom Delegate Method in First View Controller, where we get the data and assign that data to label.Now you can see the passed data using custom delegate.
Likewise you can send the data to other view controller using Custom Delegate Methods
how you pushing your second controller? i cant see.
but your code working for me.
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
ViewController1 *vc = [ViewController1 new];
vc.delegate = self;
[self presentViewController:vc animated:YES completion:nil];
}
-(void)didDataRecieved
{
NSLog(#"recieved");
}
#end
I'm just starting to learn Objective-C and I'm not 100% on all the syntax yet, and I think that might be where I'm having trouble, then again I'm not sure. I'm trying to get one view controller to send a message to its parent/callee view controller. I have it set up like this:
//ParentViewController.h
#import "SubViewController.h"
#interface ParentViewController : UIViewController <SubViewControllerDelegate>
- (void) sendMessageToParent:(NSInteger)num;
#end
This is the implementation:
//ParentViewController.m
#implementation ParentViewController
- (void) sendMessageToParent:(NSInteger)num
{
NSLog(#"Message is %d", num);
}
- (void) buttonPushed
{
[self performSegueWithIdentifier:#"SubView" sender:sender];
}
#end
Here's the other view controller setup:
//SubViewController.h
#protocol SubViewControllerDelegate <NSObject>
- (void) sendMessageToParent:(NSInteger)num;
#end
#interface SubViewController : UIViewController
#property (nonatomic, weak) id <SubViewController> delegate;
#end
And implementation:
//SubViewController.m
#implementation SubViewController
#synthesize delegate;
- (void) something
{
[self.delegate sendMessageToParent:4];
[self.dismissViewControllerAnimated:YES completion:nil];
}
Appreciate any help, thanks.
You need to add to ParentViewController:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"SubView"])
{
SubViewController *vc = [segue destinationViewController];
vc.delegate = self;
}
}
You need to add handler for prepareForSegue and set .delegate properly there. I don't think your SubviewController has delegate set to the parent one.
Looks like you're not setting SubViewController's delegate to SuperViewController. You'd do this typically when you instantiate SubViewController. e.g. subViewController.delegate = self
ParentViewController.h
#interface ParentViewController : UIViewController
#end
ParentViewController.m
#implementation ParentViewController <SubViewControllerDelegate> // Better to place this in .m than .h
#pragma mark - SubViewController Delegate
- (void)sendMessageToParent:(NSInteger)num
{
NSLog(#"Message is %d", num);
}
- (void)buttonPushed
{
[self performSegueWithIdentifier:#"SubView" sender:sender];
}
#end
SubViewController.h
#protocol SubViewControllerDelegate <NSObject>
- (void)sendMessageToParent:(NSInteger)num;
#end
#interface SubViewController : UIViewController
#property (nonatomic, weak) id<SubViewController> delegate;
#end
SubViewController.m
#implementation SubViewController
// #synthesize delegate; // Not necessary, old fashioned
- (void)something
{
// Set a breakpoint here and step through, you're not setting your delegate, so this conditional is not being hit
if (self.delegate && [self.delegate respondsToSelector:#selector(sendMessageToParent:)])
{
[self.delegate sendMessageToParent:4];
}
[self.dismissViewControllerAnimated:YES completion:nil];
}
I have a tableViewCell that says Nickname and when you click on it, a segue takes you to a view controller with a text field where you can type a nickname, once you push the back button it should appear in the detailTextLabel of the main table view controller. I just keep getting an error I posted the code below where I get an error as well.
nickname text field code:
#import "NicknameViewController.h"
#interface NicknameViewController ()
#end
#implementation NicknameViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[self.delegate updateCarNickname:self.nicknameField];
}
#end
Here is the header file for the nickname view controller:
#import <UIKit/UIKit.h>
#protocol CarNicknameDelegate <NSObject>
#optional
- (void)updateCarNickname:(UITextField *)updateNickname;
#end
#interface NicknameViewController : UIViewController
#property (nonatomic, weak) id <CarNicknameDelegate> delegate;
#property (strong, nonatomic) IBOutlet UITextField *nicknameField;
#end
In the main view controller I keep getting errors on this code and can't seem to figure it out:
-(void)updateCarNickname:(UITextField *)updateNickname {
self.nicknameCell.detailTextLabel.text = updateNickname;
}
Before the segue begins I used this code:
if ([segue.identifier isEqualToString:#"nicknameSegue"]) {
NicknameViewController *controller = segue.destinationViewController;
controller.delegate = self;
}
All views in a view controller gets deallocated once the view controller's dealloc is called.
You should change your CarNicknameDelegate's parameter UITextField to NSString.
#protocol CarNicknameDelegate <NSObject>
#optional
- (void)updateCarNickname:(UITextField *)updateNickname;
#end
and change your NicknameViewController to something like this.
#interface NicknameViewController ()
#end
#implementation NicknameViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[self.delegate updateCarNickname:self.nicknameField.text];
}
#end
I am facing a problem related to delegation.I have 2 tabView. In first tabview i have 2 textfield and a button(to trigger the delegate method) and in the second tabview i have 2 label to display the content of textfield in the first tabview.Whats wrong with my code???
For first tabviewA the .h file
#import <UIKit/UIKit.h>
#class ViewControllerA;
#protocol ViewControllerADelegate <NSObject>
-(void)sayHello:(ViewControllerA*)viewController;
#end
#interface ViewControllerA : UIViewController<UITextFieldDelegate>
#property (nonatomic,strong)IBOutlet UITextField *textFieldFirst;
#property (nonatomic,strong)IBOutlet UITextField *textFieldSecond;
#property (nonatomic,strong)id<ViewControllerADelegate>delegate;
-(IBAction)next:(id)sender;
#end
and the .m file
#import "ViewControllerA.h"
#interface ViewControllerA ()
#end
#implementation ViewControllerA
#synthesize textFieldFirst=_textFieldFirst;
#synthesize textFieldSecond=_textFieldSecond;
#synthesize delegate=_delegate;
- (void)viewDidLoad
{
[super viewDidLoad];
_textFieldFirst.delegate=self;
_textFieldSecond.delegate=self;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return NO;
}
-(IBAction)next:(id)sender
{
[self.delegate sayHello:self];
}
#end
And for the second tabbarViewB the .h file
#import <UIKit/UIKit.h>
#import "ViewControllerA.h"
#interface ViewControllerB : UIViewController<ViewControllerADelegate>
#property (nonatomic,strong)IBOutlet UILabel *labelFirst;
#property (nonatomic,strong)IBOutlet UILabel *labelSecond;
#end
and the .m file
#import "ViewControllerB.h"
#interface ViewControllerB ()
#end
#implementation ViewControllerB
#synthesize labelFirst=_labelFirst;
#synthesize labelSecond=_labelSecond;
- (void)viewDidLoad
{
[super viewDidLoad];
ViewControllerA *viewControllerA=[self.tabBarController.viewControllers objectAtIndex:0];
viewControllerA.delegate=self;
// Do any additional setup after loading the view.
}
-(void)sayHello:(ViewControllerA *)viewController
{
_labelFirst.text=viewController.textFieldFirst.text;
_labelSecond.text=viewController.textFieldSecond.text;
}
#end
N.B: I have tried tabView B to tabview A with the same process and that worked fine. The reverse (i.e from A to B)is not working at all.Thanks
ViewControllerB sets itself as the delegate in its viewDidLoad method. This method is called as soon as the View Controller has loaded the view it manages (into its view property). That view is loaded only when someone tries to access the view controller's view property for the first time. See here. There's a good chance that ViewControllerB's view has not been loaded yet, so the viewDidLoad method has not been called yet.
If you override the awakeFromNib method like so:
(void) awakeFromNib {
[super awakeFromNib];
ViewControllerA *viewControllerA=[self.tabBarController.viewControllers
objectAtIndex:0];
viewControllerA.delegate = self;
}
it should work, since that method will be called when the view controller is initialized.