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
Related
I'm using a Split View Controller for an iPad app. I'm trying to send a label change to the detailReceiving Controller from the rootSending Controll when a button is pushed. I've read through tutorials on protocols and came up with the code below. When I click the button on rootSending, nothing happens to the label on detailReceiving. Do I have to do something else with a splitViewContoller so that the label will update? Shouldn't detailReceiving change the label when it receives the message?
rootSending.h
#import <UIKit/UIKit.h>
#protocol TestDelegate <NSObject>
-(void)tester:(NSString*)testString;
#end
#interface rootSending : UIViewController
#property (nonatomic, assign) id <TestDelegate> delegate;
#end
rootSending.m
#import "rootSending.h"
#implementation rootSending
#synthesize delegate;
-(void)viewDidLoad{
}
-(IBAction)buttonPressed:(id)sender{
[delegate tester:#"button pressed"];
}
#end
detailReceiving.m
#import "detailReceiving.h"
#import "rootSending.h"
#interface detailReceiving ()<TestDelegate>{
IBOutlet UILabel *label2;
}
#end
#implementation detailReceiving
-(void)viewDidLoad{
rootSending *obj = [rootSending alloc];
obj.delegate = self ;
}
-(void)tester:(NSString *)testString{
label2.text = testString;
}
#end
First of all, never ever have an alloc without an init! But in this case, even if you did use alloc/init, it still wouldn't work because that just creates a new instance of rootSending, not the one that you have in your split view. You need to get a reference to the one you have, which you can get from the split view controller,
-(void)viewDidLoad{
rootSending *obj = (rootSending *)self.splitViewController.viewControllers.firstObject;
obj.delegate = self;
}
After Edit:
If your mate controller is embedded in a navigation controller, then you need to get the navigation controller's topViewController to get your reference.
-(void)viewDidLoad{
UINavigationController *nav = (UINavigationController *)self.splitViewController.viewControllers.firstObject;
xmlListOfItems *obj = (xmlListOfItems *)nav.topViewController;
obj.delegate = self;
}
To summarize my app, it's like an iBook : I have multiple pages filled in with an xml file (text and image).
Like in the iBook app, I want to use a UISlider to select and change page.
I use a UIViewController (appViewController) as contener of the different UIViews (contentViewController)
header of AppViewController :
#import <UIKit/UIKit.h>
#import "contentViewController.h"
#interface AppViewController : UIViewController <UIPageViewControllerDataSource>
{
UIPageViewController *pageController;
NSArray *pageContent;
NSDictionary *pageFields;
}
in AppViewController.m, I have :
// Create a new view controller and pass suitable data.
contentViewController *dataViewController = [[contentViewController alloc]initWithNibName:#"contentViewController" bundle:nil];
The header of the contentViewController is :
#import <UIKit/UIKit.h>
#class DCIEquipment;
#interface contentViewController : UIViewController
#property (nonatomic,strong) DCIEquipment *eqt;
#property (assign, nonatomic) NSUInteger pageIndex;
#property (assign, nonatomic) NSUInteger pageNumber;
#property (strong, nonatomic) IBOutlet UISlider *pageSlider;
#end
Because in iBook, the slider seems to follow the curling movement of the page, I put my UISlider on the contentViewController. Everything works good with the UISlider but I don't how know to do to informe the UIViewController to change the page (I assumed that the code of changing the page has to be done in this controller).
Please tell me if you need some more code. I hope that explainations are clear. I juste want to know where to put the UISlider (which view) and how to send value to the pageViewController.
Thank you in advance.
Raphael
Use the protocols. There are lots of examples. And you are using at least one of them (UIPageViewControllerDataSource).
Just create one for your contentViewController (in it's header file)
#class ContentViewController; // this is fast-forward declaration
#protocol ContentViewControllerDelegate
- (void)contentViewController:(ContentViewController *)controller didChangePage:(NSUInteger)pageIndex;
#end
#interface ContentViewController : UIViewController
// ...
#property (weak,nonatomic) id<ContentViewControllerDelegate> delegate; // don't forget to set the value with your appViewController
// ...
#end
In your ContentViewController-implementation file in some method just call the delegate method
if (self.delegate && [self.delegate respondsToSelector:#selector(contentViewController:didChangePage:)])
[self.delegate contentViewController:self didChangePage:newIndex];
And don't forget to implement this method in appViewController class.
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];
I'm trying to access some things from another viewcontroller (iOS).
I have my ViewController.h:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UITextFieldDelegate> {
...
}
#end
ViewController.m:
#import "ViewController.h"
#import "ViewController2.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
ViewController2.someVar = #"cakes"; // this is where I'm trying to set something in vc2
}
ViewController2.h:
#import <UIKit/UIKit.h>
#interface ViewController2 : UIViewController <UITableViewDataSource, UITableViewDelegate, UISearchDisplayDelegate>
{
...
}
#property (nonatomic, copy) NSString *someVar;
#end
ViewController2.m:
#import "ViewController2.h"
#interface ViewController2 ()
#end
#implementation ViewController2
#synthesize someVar;
etc.
But at the line where I try to access this var, it gives me the following error:
Property 'someVar' not found on object of type 'ViewController2'.
In what way would I achieve accessing this other view controller?
You have to create a ViewControlle2 object in your Viewcontroller.m.
ViewController2 *myVC2 = [[ViewController2 alloc] initWithNibName:#"ViewController2" bundle:nil];
myVC2.someVar = #"cakes";
Another way to do this is by using delegates. If you created ViewController1 in AppDelegate, you should also create ViewController2 in AppDelegate, or where ever you create your ViewControllers. Then you ViewController1 would send a message to AppDelegate to get the data from ViewController2 and vice versa. This makes ViewController1 and ViewController2 no longer dependent on each other.
So in AppDelegate.h we'd have something like this
#interface AppDelegate : NSObject <MyViewControllerDelegate>
#property (nonatomic) ViewController1 *viewController1;
#property (nonatomic) ViewController2 *viewController2;
#end
Then in both view controllers you can add this line in the .h
#property (nonatomic) id<MyViewControllerDelegate> delegate;
This just gives us a variable to use to refer to the delegate from within the ViewController's .m
You also need to create the MyViewControllerDelegate protocol, so in a file called MyViewControllerDelegate.h
#protocol MyViewControllerDelegate
- (ViewController1 *) viewController1;
- (ViewControlelr2 *) viewController2;
#end
Then when you create the ViewControllers in AppDelegate.m, you should also set AppDelegate as the ViewController's delegate.
self.viewController1 = [[ViewController1 alloc] init];
self.viewController1.delegate = self;
self.viewController2 = [[ViewController2 alloc] init];
self.viewController2.delegate = self;
So with all of this delegate set up done, you should be able to access viewController2.someVar from viewController1 through the delegate by using:
self.delegate.viewController2.someVar = #"Cakes";
Hope this isn't too long winded.
I am trying to equal the string of an UITextView from anotherViewController to the MainViewController . I mean users write something in UITextView from anotherViewController and when touch the done button the string in UITextView should equal to another string in MainViewController . How can I access UITextView ???
I did something like this but did not get any result !
#import "AnotherViewController"
#class AnotherViewController;
#interface MainViewContoller : UIViewController {
NSString *main_string;
AnotherViewController *textEntered;
}
-(void)viewDidLoad {
textEntered.TEXT = main_string
}
***TEXT is the name my UITextView on AnotherViewController .
EDITED :
#interface AnotherViewController : UIViewController {
UITextView *TEXT;
id delegate;
}
#property (nonatomic, retain) IBOutlet UITextView *TEXT;
#property (nonatomic ,retain) id delegate;
#end
#implementation AnotherViewController
#synthesize TEXT ,delegate;
- (IBAction)doneButton {
//!!! problem with compare ! the compiler got me some warning
[self dismissModalViewControllerAnimated:YES];
}
MAIN VIEW CONTROLLER
#import "AnotherViewController.h"
#class Another...;
#interface MainViewControlelr : UIViewController {
NSString *main_string;
TextViewController *textEntered;
}
- (void)viewDidLoad
{
textEntered.delegate = self;
}
- (void) compareText {
[textEntered.TEXT isEqual:main_string];
}
Set mainViewController object as the delegate of an object of anotherViewController type. And use that delegate from AnotherViewController to pass messages to MainViewController.
Inside MainViewController, when you create your AnotherViewController object do:
anotherVC.delegate = self;
And in AnotherViewController, when your button action is done and you want to pass the text back, say store in a string. Then pass it to MainViewController as:
[delegate compareText:textView.text];
compareText with a NSString argument would be a method in your MainViewController class.
EDIT:
In your AnotherViewController.h interface, declare an ivar:
id delegate;
Then use #property (in .h) and #synthesize (in .m) for getter and setter.
Then do the above.
I think you created an AnotherViewController pointer but did not set it.
before you can access textEntered.TEXT, you should set you textEntered pointer to your AnotherViewController object.
Here is how:
on iGhalamViewController class, create a property for setting textEntered object like this in your interface declaration (probably in iGhalamViewController.h)
#property (assign) AnotherViewController *textEntered;
So, at the root place where do you create this viewcontroller objects both. After you create AnotherViewController and iGhalamViewController, set your textEntered pointer like this.
AnotherViewController* a = [[AnotherViewController alloc] initWithBlah:blah];
iGhalamViewController* b = [[iGhalamViewController alloc] initWithBlah:blah];
b.textEntered = a;
Then it should work like you expected. But use it in other method than viewDidLoad. viewDidLoad probaby gets called before you can set textEntered. A button press event method should be fine.