I am trying to pass textfield text from one controller to another controller so I can email it. I am following an example, but I must be missing some little details. Basically the goal is to pass data textfield text from enteryournamecontroller controller to option controller's nsstring. The nsstring's string variable is being returned null.
EnterYourNameController.h
#interface EnterYourNameController : UIViewController{
UITextField *textField;
id <EnterYourNameController> delegate;
}
#property (strong, nonatomic) NSString *stringEntered;
#property (strong, nonatomic) UITextField *textField;
#property (strong, nonatomic) id delegate;
EnterYourNameController.m
-(void)button{
stringEntered=textField.text;
((Options *) (self.delegate)).string = stringEntered;
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
Options *vc = [storyboard instantiateViewControllerWithIdentifier:#"Options"];
[self.navigationController pushViewController:vc animated:YES];
}
options.h
#interface Options : UIViewController <MFMailComposeViewControllerDelegate> {
NSString *string;
}
#property (strong,nonatomic) NSString* string;
#end
option.m
NSString *emailBody = [NSString stringWithFormat:#"%#",string];
In -(void) button method, initialize the Options controller and set the value.
-(void)button{
stringEntered=textField.text;
Options *optViewController = [[Options alloc] init];
optViewController.string = stringEntered;
//call your optViewController here
}
I hope, your string in option VC wouldn't live, when you switch between views. So, you must retain string property like this:
-(void)button
{
Options *optViewController = [[Options alloc] init];
optViewController.string = [[NSString stringWithString:textField.text] retain];
//call your optViewController here
}
Related
My code which normally works fine for passing an object to another view controller is not working when the view controller is in a different storyboard.
My code loads the correct view controller embedded in its navigation controller but without any data. (The data object is nil in the destination VC).
Here is the code I'm trying to use;
UIStoryboard *sb2 = [UIStoryboard storyboardWithName:#"secondSB" bundle:nil];
UINavigationController* nav = [sb2 instantiateViewControllerWithIdentifier:#"userNav"];
userDetail *destVC = (userDetail * )nav.topViewController;
NSLog(#"user name%#",user.name);//Logs name showing the user is not empty
destVC.user = user;
[self presentViewController:nav animated:YES completion:nil];
The above loads a VC with no data.
I am able to pass the data object to the VC if I present the VC directly without the navigation controller. But in that case, I lose the navigation functionality which I need.
UIStoryboard *sb2 = [UIStoryboard storyboardWithName:#"secondSB" bundle:nil];
userDetail *destVC = [sb2 instantiateViewControllerWithIdentifier:#"userDetail"];
NSLog(#"user name%#",user.name);//Logs name showing the user is not empty
destVC.user = user;
[self presentViewController:destVC animated:YES completion:nil];
What could be wrong with the above code and what code should I use.
Edit:
I am able to pass a regular object such as a String to the VC embedded in the nav. Or I can pass a custom object to the VC when it is not embedded in the nav. I just can't pass a custom object such as user or I created another NSObject for testing to the VC when embedded in a nav. Perhaps this is some weird glitch when using a different storyboard.
Edit 2
Here is the object code for a light version of user I created in case there was something wrong with the original user object:
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
#interface lightUser : NSObject
#property (nonatomic, retain) NSString * name;
#property (nonatomic, retain) NSNumber * userid;
#property (nonatomic, retain) NSString * descript;
#end
It is a property in the VC:
#import "lightServer.h"
//in interface
#property (weak, nonatomic) lightUser* user;
The following code in ViewDidLoad does not have any effect and the user appears as nil:
self.user.name = #"Hello there";//
po self.user.name in debugger shows nil
po self.user in debuggers shows nil
Not sure without seeing a full example of your code, but I you must be missing something...
Here is a complete example. It should be obvious what gets connected to #IBOutlet and #IBAction (and Storyboard IDs):
UserObject.h
//
// UserObject.h
// Created by Don Mag on 4/1/20.
//
#import <Foundation/Foundation.h>
#interface UserObject : NSObject
#property (strong, nonatomic) NSString *firstName;
#property (strong, nonatomic) NSString *lastName;
#property (assign, readwrite) NSInteger age;
- (NSString *)name;
#end
UserObject.m
//
// UserObject.m
// Created by Don Mag on 4/1/20.
//
#import "UserObject.h"
#implementation UserObject
- (NSString *)name {
return [NSString stringWithFormat:#"%#, %#", _lastName, _firstName];
}
#end
** FirstViewController.h**
//
// FirstViewController.h
// Created by Don Mag on 4/1/20.
//
#import <UIKit/UIKit.h>
#interface FirstViewController : UIViewController
#end
** FirstViewController.m**
//
// FirstViewController.m
// Created by Don Mag on 4/1/20.
//
#import "FirstViewController.h"
#import "UserDetailViewController.h"
#import "UserObject.h"
#interface FirstViewController ()
#property (strong, nonatomic) UserObject *aUserObject;
#property (assign, readwrite) NSInteger iAge;
#end
#implementation FirstViewController
- (void)viewDidLoad {
[super viewDidLoad];
// initialize age
_iAge = 25;
// initialize a new UserObject
_aUserObject = [UserObject new];
_aUserObject.firstName = #"John";
_aUserObject.lastName = #"Smith";
_aUserObject.age = _iAge;
}
- (IBAction)didTap:(id)sender {
UIStoryboard *sb2 = [UIStoryboard storyboardWithName:#"secondSB" bundle:nil];
UINavigationController* nav = [sb2 instantiateViewControllerWithIdentifier:#"userNav"];
UserDetailViewController *destVC = (UserDetailViewController * )nav.topViewController;
// increment age, so it changes each time we call this method
_iAge++;
_aUserObject.age = _iAge;
destVC.userObj = _aUserObject;
[self presentViewController:nav animated:YES completion:nil];
}
#end
UserDetailViewController.h (VC is in second storyboard)
//
// UserDetailViewController.h
// Created by Don Mag on 3/31/20.
//
#import <UIKit/UIKit.h>
#import "UserObject.h"
#interface UserDetailViewController : UIViewController
#property (strong, nonatomic) UserObject *userObj;
#end
UserDetailViewController.m
//
// UserDetailViewController.m
// Created by Don Mag on 3/31/20.
//
#import "UserDetailViewController.h"
#interface UserDetailViewController ()
#property (strong, nonatomic) IBOutlet UILabel *userLabel;
#end
#implementation UserDetailViewController
- (void)viewDidLoad {
[super viewDidLoad];
_userLabel.text = [NSString stringWithFormat:
#"_useObj.firstName: %# \n" \
"_userObj.lastName: %# \n" \
"_userObj.age: %ld \n" \
"_userObj name method: %#",
_userObj.firstName,
_userObj.lastName,
_userObj.age,
[_userObj name]];
}
#end
In case it's not completely clear, here is a working example app: https://github.com/DonMag/DataObjectPassing
I would like to pass some variables from my first controller:
float user_distance;
UIImage *user;
float user_battery;
NSString *user_name;
To a second controller.
The connection between the two is made by the function:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
in this manner:
UserViewController *secondViewController = [[UserViewController alloc] initWithNibName:#"UserViewController" bundle:nil];
[self.navigationController pushViewController:secondViewController animated:YES];
How is it possible to recover the values in from this function?
Thanks in advance!
Add the properties you need to your second controller in your .h file ..
//SecondController.h
#interface SecondController : UIViewController
#property (nonatomic) float *property1;
#property (nonatomic, strong) UIImage *property2;
#property (nonatomic) float *property3;
#property (nonatomic, strong) NSString *property4;
#end
Then import your second controller .h file in your first controller .m file..
And set the properties before pushing the second controller.
//FirstController.m
#import "SecondController.h"
...
...
UserViewController *secondViewController = [[UserViewController alloc] initWithNibName:#"UserViewController" bundle:nil];
secondViewController.property1 = ;//your value here
secondViewController.property2 = ;//your value here
secondViewController.property3 = ;//your value here
secondViewController.property4 = ;//your value here
[self.navigationController pushViewController:secondViewController animated:YES];
I've got 2 view controller,
i want to pass data between them, in the first view controller i use this method to switch to other view controller and passing data :
- (void)loginViewFetchedUserInfo:(FBLoginView *)loginView
user:(id<FBGraphUser>)user {
NSString *userName = [user username];
NSString *userId = [user id];
dashBoardViewController *dashBoardViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"dashBoardViewController"];
dashBoardViewController.first_name = userName;
dashBoardViewController.id = userId;
[self presentModalViewController:dashBoardViewController animated:YES];
}
having this on view controller.h
#interface ViewController : UIViewController <FBLoginViewDelegate>
#property (weak, nonatomic) IBOutlet FBLoginView *loginButton;
#property (weak, nonatomic) IBOutlet UIButton *showEvent;
#property (weak, nonatomic) IBOutlet UIButton *goQrcode;
#property (retain, nonatomic) NSString *id;
#property (retain, nonatomic) NSString *first_name;
in the second view controller i have this method to read the variable and switch to another view controller:
- (IBAction)gotoEvents:(id)sender {
events *events;
events.first_name = _first_name;
events.userid = _id;
[self.storyboard instantiateViewControllerWithIdentifier:#"events"];
[self presentModalViewController:events animated:YES];
}
and this on my header file:
#property (nonatomic, retain) NSString *first_name;
#property (nonatomic, retain) NSString *id;
- (IBAction)gotoEvents:(id)sender;
it says me
property 'first_name' not found on object of type 'events'
Try this,
events *events = [self.storyboard instantiateViewControllerWithIdentifier:#"events"];
events.first_name = _first_name; //class name Should Start With capital letter and should use camel case for naming.
events should be named as Events, as it the class name
I have a program with multiple views, one of them has labels (LabelView for this question), the other has text fields(TextView for this question). I would like to take the info from the text fields, and put it on the label, I think the easiest way to do this by calling a method LabelView from TextView.
I have tried a couple things:
I tried putting a method in LabelView that changed the label's values with parameters. Then calling the method in TextView and passing the data through the parameters.
I tried making a delegate, using this question. Unfortunately the last step (add settingView.viewControllerDelegate=self to the viewDidLoad method) failed. settingView was an undeclared identifier.
Does anyone know what I should do?
EDIT: Here is some I have done, using Xman's Parent/Child view idea. This is in TextView.m:
NSInteger curScore = [self.ToP1Score.text integerValue];
NSInteger curPhase = [self.ToP1Phase.text integerValue];
self.ToP1Score.text = [NSString stringWithFormat:#"%d", (curScore += [self.player1Txt.text integerValue])];
if ([self.player1Txt.text integerValue] < 50) {
self.ToP1Phase.text = [NSString stringWithFormat:#"%d", (curPhase += 1)];
}
Two ways to achieve this.
1) Make ChildView as a childView of ParentView so that you can directly access ParentView properties in ChildView as following
ParentView.h
#interface ParentView : UIView
#property (nonatomic,strong) UITextField *mytextField;
#end
ChildView.h
#import "ParentView.h"
#interface ChildView : ParentView
#property (nonatomic,strong) UILabel *myLabel;
#end
2) Use Notification
Put this in FirstView where the textField is :
[[NSNotificationCenter defaultCenter] postNotificationName:#"sendData" object:yourTextFiels userInfo:nil];
Put this in SecondView where your Label is.
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(changeLabelValue:) name:#"sendData" object:nil];
and also this method
-(void)changeLabelValue(NSNotification *)iRecognizer {
UITextField *myTextField = iRecognizer object];
//Here You can change the value of label
}
Hope this will help you.
suppose you are passing some text from firststViewController to secondViewController,
then in firststviewcontroller add these lines of code
-(IBAction)goToNextScreen:(id)sender
{
secondViewController *newVc = [[secondViewController alloc]initWithNibName:#"secondViewController" bundle:nil];
// or if you are using storyboard
// NewViewController *newVc = [self.storyboard instantiateViewControllerWithIdentifier:#"identifier"];
newVc.text = #" Your text ";
[self.navigationController pushViewController:newVc animated:YES];
}
in 2ndViewController.h file
#import <UIKit/UIKit.h>
#interface secondViewController : UIViewController
{
NSString text;
}
#property(nonatomic, retain)NSString text;
#property (weak, nonatomic) IBOutlet UILabel *lbl;
#end
in .m file
#import "secondViewController.h"
#interface secondViewController ()
#end
#implementation secondViewController
#synthesize text,lbl;
- (void)viewDidLoad
{
lbl.text = text;
}
#end
hope this will help you.. Dont forget to up vote...
I have a subview that is linking to a detail subview. See below. This .h is EXACTLY the same in the two header files I am currently using, except for the #interface _ (JohnAdams on one and GeorgeWashington on the other.
#interface JohnAdams : UIViewController {
NSString *selectedCountry;
IBOutlet UIButton *bio;
IBOutlet UIButton *wiki;
}
#property (nonatomic, retain) NSString *selectedCountry;
#property (nonatomic, retain) UIButton *wiki;
#property (nonatomic, retain) UIButton *bio;
-(IBAction)wikiButtonPressed:(id)sender;
-(IBAction)bioButtonPressed:(id)sender;
#end
However, take a look at the two .m's
//George Washington.m
-(IBAction)wikibuttonPressed:(id)sender {
WebView1 *detailvc = [[WebView1 alloc] initWithNibName:#"WebView1" bundle:nil];
[detailvc setTitle:#"Wikipedia"];
[self.navigationController pushViewController:detailvc animated:YES];
[detailvc release];
}
-(IBAction)biobuttonPressed:(id)sender {
WebView2 *detailvc2 = [[WebView2 alloc] initWithNibName:#"WebView2" bundle:nil];
[detailvc2 setTitle:#"The White House"];
[self.navigationController pushViewController:detailvc2 animated:YES];
[detailvc2 release];
}
//JohnAdams.m
-(IBAction)biobuttonPressed:(id)sender {
WebView4 *detailvc4 = [[WebView4 alloc] initWithNibName:#"WebView4" bundle:nil];
[detailvc4 setTitle:#"The White House"];
[self.navigationController pushViewController:detailvc4 animated:YES];
[detailvc4 release];
}
-(IBAction)wikibuttonPressed:(id)sender {
WebView3 *detailvc3 = [[WebView3 alloc] initWithNibName:#"WebView3" bundle:nil];
[detailvc3 setTitle:#"Wikipedia"];
[self.navigationController pushViewController:detailvc3 animated:YES];
[detailvc3 release];
}
In John Adams.m, rather than loading WebView3 and WebView4, it loads WebView1 and WebView2. Additionally, John Adams.m receives a warning that method definition for both -wikiButtonPressed and bioButtonPressed are undefined (but not on GeorgeWashington.m). What am I doing wrong?
Are you using the interface builder?
(Apparently you do because you are declaring IBOutlets)
If so then check the class name of the files owner of JohnAdams.xib.