Pass value from controller to controller - ios

I'm building my first iOS app to try and learn iOS coding. However, I need to pass a value xAuthToken from one controller to the other. I can't seem to get it working to. I init the value in the first controller ViewController, but then I need it in SettingsController. I keep getting errors and the one it throws now is: Property 'ViewController' not found on object of type 'ViewController'
What am I doing wrong?
ViewController.h
#import <UIKit/UIKit.h>
#import "SettingsController.h"
#interface ViewController : UIViewController <UITextFieldDelegate>
#property (weak, nonatomic) IBOutlet UITextField *txtUsername;
#property (weak, nonatomic) IBOutlet UITextField *txtPassword;
- (IBAction)sigininClicked:(id)sender;
- (IBAction)backgroundTap:(id)sender;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#property (nonatomic) NSString *xAuthToken;
#end
#implementation ViewController
- (IBAction)sigininClicked:(id)sender {
NSString *xAuthToken = #"0";
self.viewController = [[SettingsController alloc] init];
self.viewController.xAuthToken = xAuthToken;
[self performSegueWithIdentifier:#"login_success" sender:self];
}
SettingsController.h
#import <Foundation/Foundation.h>
#interface SettingsController : UIViewController
#end
SettingsController.m
#interface SettingsController ()
#property (weak, nonatomic) IBOutlet UITextField *myTextField;
#property (weak, nonatomic) IBOutlet UISwitch *mySwitch;
#end
#implementation SettingsController
//THIS IS WHERE I NEED XAUTHTOKEN

If you have a segue that presents your SettingsController, pass the information it needs in prepareForSegue. Don't create a new local SettingsController.

You can do something like
viewController = [self.storyboard instantiateviewcontrollerwithidentifier:#"your vc name"];
viewController.Xauthtoken = data;
// Do something else with this.
Or another way ( I don't know if it's good or bad, use it while your vc is already active ):
Use NSNotificationCenter and pass values between it.
Third way is create delegate for first Viewcontroller.

Try this in your ViewController.m:
#import "ViewController.h"
#interface ViewController ()
#property (nonatomic) NSString *xAuthToken;
#end
#implementation ViewController
- (IBAction)sigininClicked:(id)sender {
xAuthToken = #"Your Value Here";
[self performSegueWithIdentifier:#"login_success" sender:self];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"login_success"]) {
SettingsController *destViewController = segue.destinationViewController;
destViewController.xAuthToken = xAuthToken;
}
}
And in your SettingsController.h
#import <Foundation/Foundation.h>
#interface SettingsController : UIViewController
#property (nonatomic,strong) NSString *xAuthToken;
#end
SettingsController.m
#interface SettingsController ()
#property (weak, nonatomic) IBOutlet UITextField *myTextField;
#property (weak, nonatomic) IBOutlet UISwitch *mySwitch;
#end
#implementation SettingsController
-(void)viewDidLoad{
NSLog("%#",xAuthToken);
}

Related

Property not found although it's in the header

I have one view and one View Controller. I am trying to have a reference to View Controller from the view.
PlusCalendarView.h
#interface PlusCalendarView : TSQCalendarView
#property (nonatomic, strong) UIViewController *initialVC;
#end
ViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
[self setUpCalendarView:self.myCalendarView];
self.myCalendarView.initialVC = self; // ERROR: Property initialVC not found on object of type "PlusCalendarView"
}
How come it cannot find initialVC property?
Update:
ViewController.h
#import <UIKit/UIKit.h>
#import <TimesSquare/TimesSquare.h>
#interface PlusCalendarView : TSQCalendarView;
#end
#interface ViewController : UIViewController
#property (nonatomic, strong) NSCalendar *calendar;
#property (strong, nonatomic) IBOutlet PlusCalendarView *myCalendarView;
#end
The problem is that you're declaring PlusCalendarView in ViewController.h AND PlusCalendarView.h. You should remove the #interface declaration from ViewController.h.
Instead, add #class PlusCalendarView in ViewController.h then #import "PlusCalendarView.h" in ViewController.m

How come "self.canDisplayBannerAds = YES;" makes app crash on iOS 8?

I would like to point out that self is a WelcomeViewController and that it inherits from UIViewController :
WelcomeViewController.h
#import <UIKit/UIKit.h>
#interface WelcomeViewController : UIViewController
#property (strong, nonatomic) NSString* score;
#property (strong, nonatomic) NSUserDefaults* preferences;
#end
WelcomeViewController.m
#import "WelcomeViewController.h"
#import "GESceneController.h"
#import <iAd/iAd.h>
#interface WelcomeViewController ()
#property (weak, nonatomic) IBOutlet UILabel *scoreLabel;
#property (weak, nonatomic) IBOutlet UILabel *highScoreLabel;
#end
#implementation WelcomeViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.canDisplayBannerAds = YES;
[self.scoreLabel setText:self.score];
NSString* highScoreText = [NSString stringWithFormat:#"Meilleur score : %ld",
[self.preferences integerForKey:#"highscore"]];
[self.highScoreLabel setText:highScoreText];
// Do any additional setup after loading the view.
}
and I get the error : [WelcomeViewController setCanDisplayBannerAds:]: unrecognized selector sent to instance 0x7d97f080
Have you imported the iAd file into your linked frameworks and libraries? If not, goto your build info and scroll all the way to the bottom, there you will find 'linked frameworks..' and add the framework into you app.

Simple delegate example for iOS not working

I know there are tons of questions out there about passing messages between different view controllers. I've checked them all but I can't get it working.
I've followed this tutorial: http://www.youtube.com/watch?v=XZWT0IV8FrI replacing the storyboard with a navigation controller but I run across the following issue over and over again: 'Cannot find protocol declaration for...'
Here is the code:
FirstViewController.h
#import "SecondViewController.h"
#interface FirstViewController : UIViewController <SecondViewControllerDelegate>{
//In this line above is where I get the error 'Cannot find protocol declaration for SecondViewControllerDelegate'
IBOutlet UITextField *userNameTextField;
}
#property (nonatomic, strong) UITextField *userNameTextField;
-(IBAction)goNext:(id)sender;
#end
FirstViewController.m
#import "FirstViewController.h"
#interface FirstViewController ()
#end
#implementation FirstViewController
#synthesize userNameTextField;
-(void)goNext:(id)sender{
SecondViewController *secondVC = [[SecondViewController alloc]init];
secondVC.delegate = self;
[self.navigationController pushViewController:secondVC animated:YES];
}
-(void)done:(NSString*)name{
NSLog(#"BACK in firstVC");
userNameTextField.text = name;
}
#end
SecondViewController.h
#import "FirstViewController.h"
#protocol SecondViewControllerDelegate <NSObject>
-(void)done:(NSString*)someText;
#end
#interface SecondViewController : UIViewController{
IBOutlet UITextField *someText;
IBOutlet UIButton *returnButton;
id delegate;
}
#property (assign, nonatomic) id <SecondViewControllerDelegate> delegate;
#property (strong, nonatomic) UITextField *someText;
-(IBAction)goBack:(id)sender;
#end
SecondViewController.m
#import "SecondViewController.h"
#interface SecondViewController ()
#end
#implementation SecondViewController
#synthesize someText;
#synthesize delegate = _delegate;
-(void)goBack:(id)sender{
[self.delegate done:someText.text];
FirstViewController *firstVC = [[FirstViewController alloc]init];
[self.navigationController pushViewController:firstVC animated:YES];
}
#end
In your SecondViewController goBack implementation you are creating a new FirstViewController rather than popping your navigation controller, code should read...
-(void)goBack:(id)sender{
[self.delegate done:someText.text];
[self.navigationController popViewControllerAnimated:YES];
}
And also in your SecondViewController.h remover this #import "FirstViewController.h" as it is no longer needed and could be confusing the compiler
Your protocol name is EYSSecondViewControllerDelegate:
#protocol EYSSecondViewControllerDelegate <NSObject>
but you call it SecondViewControllerDelegate in two places:
#interface EYSFirstViewController : UIViewController <SecondViewControllerDelegate>{...
#property (assign, nonatomic) id <SecondViewControllerDelegate> delegate;...
Make sure that the name match and it should works fine.
In SecondViewController.h
remove line id delegate;
In SecondViewController.m
Update code -> [delegate done:someText.text];
'self.' remove
Try it

'NSInvalidArgumentException', reason: '-[UINavigationController setMed:]: unrecognized selector sent to instance 0x746dda0'

I am making an app that will help people with certain health conditions manage their medication. I have created a modal to add medication which works and saves the new medication using core data.
I am now trying to allow people to edit their medication after it has been saved. To do this I am trying to send a managed object of the medication to a "fibromappMedsEditViewController" and assign the information in the viewDidLoad method of the class.
I keep getting this error:
'NSInvalidArgumentException', reason: '-[UINavigationController setMed:]: unrecognized selector sent to instance 0x746dda0'
Could anybody tell me what I am doing wrong?
relevant methods in fibromappMedsListViewController.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{ //selMed declared at top of file as NSManagedObject *selMed;
selMed = [self.meds objectAtIndex:indexPath.row];
NSLog(#"SELECTED MED: %#",[selMed valueForKey:#"name"] );
UIStoryboardSegue *segueString = [NSString stringWithFormat:#"%#",#"editMeds"];
NSLog(#"%#",segueString);
[self performSegueWithIdentifier:#"editMeds" sender:indexPath];
}
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
NSLog(#"%#",segue.destinationViewController);
NSLog(#"%#",[selMed valueForKey:#"name"] );
fibroMappMedsEditViewController *dest = segue.destinationViewController;
dest.med = selMed;
}
The fibroMappMedsEditViewController.h
#import <UIKit/UIKit.h>
#interface fibroMappMedsEditViewController : UITableViewController
- (IBAction)saveChanges:(id)sender;
- (IBAction)deleteBtnPressed:(id)sender;
- (IBAction)dosageChanged:(id)sender;
- (IBAction)maxDosageChanged:(id)sender;
- (IBAction)cancel:(id)sender;
- (IBAction)typeChanged:(id)sender;
#property (weak, nonatomic) IBOutlet UITextField *tbName;
#property (weak, nonatomic) IBOutlet UITextField *tbDose;
#property (weak, nonatomic) IBOutlet UITextField *tbMaxDose;
#property (weak, nonatomic) IBOutlet UITextField *tbType;
#property (weak, nonatomic) IBOutlet UIStepper *stepperDose;
#property (weak, nonatomic) IBOutlet UIStepper *stepperMaxDose;
#property (weak, nonatomic) IBOutlet UISegmentedControl *changeMeasure;
#property (strong, nonatomic) NSManagedObject *med;
#end
The fibroMappMedsEditViewController.m - just the parts I altered that affect the way the controller loads
#import "fibroMappMedsEditViewController.h"
#import "fibroMappAppDelegate.h"
#import <CoreData/CoreData.h>
#interface fibroMappMedsEditViewController ()
#end
#implementation fibroMappMedsEditViewController
#synthesize tbName;
#synthesize tbDose;
#synthesize tbMaxDose;
#synthesize tbType;
#synthesize med;
double dose;
double maxDose;
- (void)viewDidLoad
{
[super viewDidLoad];
tbName.text = [med valueForKey:#"name"];//name is a string in the model
tbDose.text = [med valueForKey:#"dose"];//dose is a double in the model
tbMaxDose.text = [med valueForKey:#"maxDose"];//maxDose is a double in the model
tbType.text = [med valueForKey:#"type"];//type is a string in the model
}
If you need to see anything else please just ask.
Also, I am using storyboards for this app.
It appears from that log, that your fibroMappMedsEditViewController (which should start with a capital letter BTW) is embedded in a navigation controller. You need to get to that navigation controller's root view controller.
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
UINavigationController *nav = segue.destinationViewController;
fibroMappMedsEditViewController *dest = (fibroMappMedsEditViewController *)nav.topViewController;
dest.med = selMed;
}

iPhone delegation bug

I've got 2 views. The firstView and the secondView. The firstView needs the favourites array from the secondView, so I try to call the getFavourites method defined in the protocol. This returns null however, which seems strange to me because everything makes sense.
Here is the firstViewController.h:
#import <UIKit/UIKit.h>
#import "Drink.h"
#protocol firstViewControllerDelegate;
#interface FirstViewController : UIViewController
{
id <firstViewControllerDelegate> delegate;
NSMutableArray *labels;
UIButton *button1;
UIButton *button2;
UIButton *button3;
UIButton *button4;
}
- (IBAction) buttonClick: (id) sender;
#property (nonatomic, assign) id <firstViewControllerDelegate> delegate;
#property (nonatomic, retain) IBOutlet UIButton *button1;
#property (nonatomic, retain) IBOutlet UIButton *button2;
#property (nonatomic, retain) IBOutlet UIButton *button3;
#property (nonatomic, retain) IBOutlet UIButton *button4;
#end
#protocol firstViewControllerDelegate
- (NSMutableArray *) getFavourites;
- (void) setFavourites: NSMutableArray;
#end
firstViewController.m
#synthesize delegate;
.......
- (void) viewWillAppear:(BOOL)animated
{
NSMutableArray *favourites = [delegate getFavourites]; // favourites is empty after this line
[button1 setTitle:[[favourites objectAtIndex:1] name] forState:UIControlStateNormal];
NSLog(#"VIEW APPEARED. BUTTON TITLE IS: %#", button1.currentTitle);
}
SecondViewController.h
#import <UIKit/UIKit.h>
#import "FirstViewController.h"
#interface SecondViewController: UIViewController <UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate, firstViewControllerDelegate>
{
NSMutableArray *favourites;
NSMutableArray *drinks;
}
#property (nonatomic, retain) NSMutableArray *drinks;
#property (nonatomic, retain, getter = getFavourites) NSMutableArray *favourites;
- (void) addDrink: (NSString *) name;
#end
Does anybody have any idea why this isn't working?
Are you sure you're setting the delegate property of FirstViewController? i.e.:
FirstViewController *firstController = // Instantiate the controller;
firstController.delegate = secondController;
[self.navigationController pushViewController:firstController animated:YES];
secondController should exist before instantiation, otherwise you're setting a nil value

Resources