Multiview app. cannot change text field values - iphone

hey guys i'm making an app that has 2 views. the first view is where the user inputs the numbers and when they hit calculate button.. its takes them to a new view where the answer is displayed on a textfield. the calculation is handled by a different file. "calc.h " and "calc.m"
this is the main view files (the view where the user enters the numbers )
#import <UIKit/UIKit.h>
#interface test2ViewController : UIViewController {
IBOutlet UITextField *num1; //input number 1
IBOutlet UITextField *num2; // input number2
}
#property (nonatomic,retain) UITextField *num1;
#property(nonatomic, retain)UITextField *num2;
-(IBAction)calculate:(id)sender; //the calculate button
-(IBAction)exit:(id)sender;
#end
the answer is displayed in a different view that shows up when the user hits the calculate button. below is the code for that !
#import "test2ViewController.h"
#import "answer.h"
#import "calculate.h"
#implementation test2ViewController
#synthesize num1,num2;
-(IBAction)calculate:(id)sender{
calculate *testclass = [[calculate alloc]init];
answer *view = [[answer alloc]initWithNibName:nil bundle:nil];
[self presentModalViewController:view animated:YES];
int i = [[num1 text] intValue];
testclass.number1 = i;
int j = [[num2 text] intValue];
testclass.number2 = j;
[testclass calc];
}
".h" file of the view that displays the answer
#import <UIKit/UIKit.h>
#interface answer : UIViewController {
IBOutlet UITextField *text;//textfield to display answer
}
#property(nonatomic,retain) UITextField *text;
-(IBAction)back:(id)sender;
#end
".m" file
#import "answer.h"
#import "test2ViewController.h"
#import "calculate.h"
#implementation answer
#synthesize text;
-(IBAction)back:(id)sender{
test2ViewController *view = [[test2ViewController alloc]initWithNibName:nil bundle:nil];
[self presentModalViewController:view animated:YES];
}
the next is an objective c class file that does the calculation. it has one function that does the calculation and here is the ".h" and ".m" file
".h"
#import <Foundation/Foundation.h>
#interface calculate : NSObject {
int number1;
int number2;
NSString *ans;
}
#property int number1;
#property int number2;
#property (nonatomic , retain) NSString *ans;
-(void)calc;
#end
".m"
#import "calculate.h"
#import "answer.h"
#import "test2ViewController.h"
#implementation calculate
#synthesize number1,number2,ans;
-(void)calc{
int i = number1 + number2;
answer *ans1 = [[answer alloc]init];
ans = [NSString stringWithFormat:#"%d",i];
ans1.text.text = ans;
}
#end
so as you can see the above function calculates the answer..puts it into a string and sets that to the textfield. but the textfield doesn't show anything..so the problem here is that i cannot access the textfield even though i created an object from it....

Im a bit confused to what your trying to accomplish, do you want to use an NSString or the text UITextField in another class? If thats the case give the string that is carrying whatever you want to be displayed a #property, then set whatever you want the strings value to it, next import the calc.h (#import "calc.h") in the second class, then in the interface create this calc *getString; create a #property for that, #synthesize it. Then to get the value of the string from calc do something like this getString.SomeStringName, now you are able to do whatever you want with it.
I think this is what you want? if not feel free to comment. Good Day :)
Edit: Im going to give you an example because this is a bit confusing the way i wrote it lol
So here is your calc.h file, also remember im typing this online and not in xcode, so if i spell something wrong or make a simple mistake, thats why:
#interface calc : UIViewController {
NSString *answer;
}
#property (nonatomic, retain) NSString *answer;
#end
Your .h could have more
Now lets hop into your .m
#implementation calc
#synthesize answer;
//do all the work to get the answer, once you have it do this
[answer retain];
//load your new view controller
Lets hop into your other view controller that will be loaded
this is .h file of it
#import "calc.h"
#interface secondController : UIViewController {
calc *getAnswer;
}
#property (nonatomic, retain) calc *getAnswer;
#end
Then go to your .m
#implementation secondController
#synthesize getAnswer;
-(void)viewDidLoad{
WhateverYouWantTheStringToBeSetTo.text = getAnswer.Answer;
}
This should then grab the string from the other controller and allow you to use it in this one..
Hope this helps :)

The problem is that your "ans" UIViewController did not load yet.
The most standard way to do this is to give your UIViewController "ans" a #property with the result. Then in the "ans" viewDidLoad method, set the text field to the appropriate value.

Related

EXD_BAD_ACCESS passing data back to delegate

I'm a relatively new iPhone developer and am making great progress building my 2nd iPhone app. In the app I'm building now I'm doing some code separation with some protocols and delegates so that I car re-use some of my code in a variety of places throughout my code.
Here's what I want to happen:
CITRootViewController creates an instance of a CITReportCreator class, passing itself as a property so that the reportCreator can open additional view controllers and such.
CITReportCreator class is declared as implementing the CITImageCaptureDelegate protocol, which is declared in the CITImageCaptureViewController file.
CITImageCaptureViewController defines the delegate protocol and has a method that passes back data and references to the child view controller so that CITReportCreator can interact with it's data, close the related XIB, etc.
I believe I'm getting the delegate and protocol established correctly, and verified that my 'delegate' object still contains data when it is called, but I'm getting a EXC_BAD_ACCESS method when my view controller tries to pass data back to the delegate in this line of code:
[self.delegate childViewControllerDidFinish:self];
Here's a good portion of the rest of my code. I had this working by using CITRootViewController as my delegate instead of the CITReportCreator class, but now that I'm separating the code, something has broke.
CITReootViewController.m (the view controller that calls the Report Creator)
//create a nrew report
-(IBAction)createReport:(id)sender {
CITReportCreator *report = [CITReportCreator alloc];
[report createNewReport:self];
}
CITReportCreator.h
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "CITImageCaptureViewController.h"
#interface CITReportCreator : NSObject <CITImageCaptureDelegate>
#property (strong, nonatomic) NSArray *imageList;
#property (nonatomic) NSInteger imageIndex;
-(int) createNewReport:(UIViewController *)parent ;
//Delegate Methods
-(void) childViewControllerDidFinish:(UIViewController*)viewController;
#end
And CITReportCreator.m
#import "CITReportCreator.h"
#implementation CITReportCreator
{
UIViewController *parentController;
}
#synthesize imageList;
#synthesize imageIndex;
-(int) createNewReport:(UIViewController *)parent
{
//store a reference to the parent view controller
parentController = parent;
// init code....
//head to the first image capture view
[self startImageCapture];
return 0;
}
-(int)startImageCapture
{
//pull the image name from the array of images
NSString *imageName = [imageList objectAtIndex:imageIndex];
//prep the image capture controller
CITImageCaptureViewController *capture = [[CITImageCaptureViewController alloc] initWithNibName:#"CITImageCaptureViewController" bundle:nil];
//Assign the capture controller's delegate
capture.imageName = imageName;
capture.delegate = self;
//Display the capture controller
[parentController presentModalViewController:capture animated:YES];
return 0;
}
//a break point set here never gets hit.
-(void) childViewControllerDidFinish:(UIViewController*)viewController;
{
[viewController dismissModalViewControllerAnimated:YES];
}
#end
And finally, the CITImageCaptureViewControllers
CITImageCaptureViewController.h
#import <UIKit/UIKit.h>
#protocol CITImageCaptureDelegate <NSObject>
-(void) childViewControllerDidFinish:(UIViewController*)viewController;
#end
#interface CITImageCaptureViewController : UIViewController
{
id<CITImageCaptureDelegate> delegate;
}
#property (nonatomic,assign) id<CITImageCaptureDelegate> delegate;
#property (nonatomic, assign) NSString *imageName;
//continue button pressed method
-(IBAction)continueButtonPressed:(id)sender;
#end
And the .m file
#import "CITImageCaptureViewController.h"
#interface CITImageCaptureViewController ()
#end
#implementation CITImageCaptureViewController
#synthesize navItem;
#synthesize imageName;
#synthesize delegate = _delegate; //i think this may be part of the problem
//cutting out initWithNibName, viewDidLoad, etc...
- (IBAction)continueButtonPressed:(id)sender
{
[self.delegate childViewControllerDidFinish:self];
}
#end
I find nothing with delegates and protocols all that simple, but I'm guessing I'm missing a small change somewhere. Can you help me head in the right direction?

Changing variables from one nib to another

Let's say I have:
FirstViewController.h
FirstViewController.m
FirstViewController.xib
SecondViewController.h
SecondViewController.m
SecondViewController.xib
In the FirstViewController.h there is:
#interface FirstViewController : UIViewController
{
int number;
}
#property (nonatomic, retain) int number;
#end
And in FirstViewController.m there is:
- (void)viewDidLoad
{
int number = 4;
}
Is there a way that I could write a function for SecondViewController that could change the value for int number from 4 to let's say 9?
I don't know how to change variables from another XIB or .m file...
First, you probably don't mean to retain an `int.
Second, you do not need to declare int number = 4; but just number = 4;.
Third, if the SecondViewController can access an instance of the FirstViewController *firstViewController, then it can change the value by
[firstViewController setNumber:9];
Depending on your hierarchy, you may be able to access firstViewController through the navController stack, for example.

How to pass a string from one view to another in tab based app

I have created a tab based application having 4 tabs and 4 views respective to these tabs.
I have a string in first view and when I printing this string in second view it printing null.
In first view.h
NSString *dateString;
#property(nonatomic,retain) NSString *dateString;
In first view.m
#synthesize dateString;
dateString=button6.titleLabel.text;
NSLog(#"dateString:%#",dateString);
In second view.h
NSString *dateString;
#property(nonatomic,retain) NSString *dateString;
In second view.m
#synthesize dateString;
- (void)viewDidLoad { [super viewDidLoad];
NSLog(#"dateString:%#",self.dateString);
}
Add your view controllers as properties for the application delegate (if the app is a relatively simple design).
Then you can reference the properties of the second view controller from the first view controller, by way of the app delegate. (One such property could be the string you want the second VC to copy or retain.)
Create NSString variable in Application delegate class and set the Property and make synthesize that variable.
And set the #"" (blank) value in applicationDidFinishLaunching method.
For Example - my variable name is str, then initialize str in applicationDidFinishLaunching like self.str = [NSString stringWithFormat:#""];
And now you can use it in any tab *view* and set the value as per your require.
More code
AppDelegate.h
#interface AppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
NSString *baseURL;
}
#property (nonatomic, retain) NSString *baseURL;
#end
AppDelegate.m
#import "AppDelegate.h"
#implementation AppDelegate
#synthesize window;
#synthesize baseURL;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
self.baseURL = [NSString stringWithFormat:#""];
}
- (void)dealloc
{
[baseURL release];
[window release];
[super dealloc];
}
#end
ViewController1.h
#class AppDelegate;
#interface ViewController1 : UIViewController <UITextFieldDelegate>
{
AppDelegate *appDelegate;
}
#end
ViewController1.m
#import "AppDelegate.h"
#import "ViewController1.h"
#implementation ViewController1
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
NSLog(#"value - %#",appDelegate.baseURL); // Here you can set or get the value.
}
it may not be the best answer.but creating a string variable in the appdelgate and passing the variable to this from the first view and fetching it from the second view works for me
Really, did we lose focus of MVC and the most awesome of abilities that is easy to do in iPhone Development?
How about a delegate?
#protocol ViewOneDelegate
- (void)getStringVariable;
#end
#interface ViewOneModel : NSObject
{
NSString* _stringVariable;
id<ViewOneDelegate> _theDelegate;
}
#property (nonatomic, retain) id<ViewOneDelegate> theDelegate;
#end
Assign a controller to be the delegate for the ViewOneModel.
Here is a simple solution, but not the best one, Create a global variable, and just use that.
Header
extern NSString *GlobalString;
#interface GlobalVariables : NSObject {
}
#end
implementation
#import "GlobalVariables.h"
#implementation GlobalVariables
NSString *GlobalString;
#end
And now to have access to the variable just import the header in the file you want to use.
You'll probably want to check if it's initiated before you use it.

Button not working

Hey there, I'm a designer thats really new to programming with xcode or Objective-C in general. I'm trying to create a few simple apps to try to get a better hang on programming the iPhone. Currently, I'm working on a very basic app which has 3 textfields, a name field and two number fields, and when you click the button, it shows in the label "name, the answer is answer" problem is, when i click the button, nothing is appearing in the label.
im pretty sure i have the code done right, i may be mistaken, i think i might have missed an outlet or something silly of the like. this is the part i get really lost on. any suggestions?
the .h:
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#interface fordaddyAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
IBOutlet UITextField *name;
IBOutlet UITextField *myInt1;
IBOutlet UITextField *myInt2;
IBOutlet UILabel *sum;
IBOutlet UIButton *click;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
-(IBAction)click:(id)sender;
#end
the .m:
#import "fordaddyAppDelegate.h"
#implementation fordaddyAppDelegate
#synthesize window;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
[window makeKeyAndVisible];
}
-(IBAction)click:(id)sender;
{
int sum;
sum = myInt1, myInt2;
NSLog (name, #", the answer is %i", sum);
}
- (void)dealloc {
[window release];
[super dealloc];
}
#end
and im terribly sorry in advance, the preview doesnt look to pretty :/
your problem is that you are just writting a message to the console, not displaying the result in the label...
Here's what it should be:
- (IBAction)click:(id)sender {
int sum = [myInt1.text intValue] + [myInt2.text intValue];
label.text = [NSString stringWithFormat:#"%# the answer is %d", name.text, sum];
}
That makes a variable 'sum' which is the result of the integer values of the text fields being added together. you access the string of a UITextView by using the .text. Then you have to convert it into an integer for addition, so you call the intValue method on it. You then make an NSString with stringWithFormat, and have it contain the name.text and the sum. I would highly recommend doing some more reading about Objective-C in general before you start with all this GUI stuff... just a suggestion.
Your problem is this:
int sum;
sum = myInt1, myInt2;
sum is an integer. myInt1 and myInt2 are UITextFields. The comma does not do what you're expecting.
You need to extract the intValue from each of the textfields, and add them together using a "+" (just like you would with regular math).

iPhone: initialize object in controller

I am very new to objective-c and having a problem to initialize an object in view controller. The problem I am having is that when setTemp method is called, "0" is printed on the screen instead of the value of cTemp I would like it to be. Can anyone help me on this problem?
Below are excerpts of the code I have.
SJT.h
#import <Foundation/Foundation.h>
#import <stdlib.h>
#interface SJT : NSObject {
int cTemp;
}
- (int) newTemp;
#end
SJT.m
#import "SJT.h"
#implementation SJT
- (int) newTemp
{
cTemp = 25 + rand() % 8;
return cTemp;
}
#end
SJTViewController.h
#import <UIKit/UIKit.h>
#class SJT;
#interface SJTViewController : UIViewController {
IBOutlet UILabel *temp;
SJT *sjt;
}
#property (retain, nonatomic) UILabel *temp;
#property (retain, nonatomic) SJT *sjt;
- (IBAction) setTemp: (id) sender;
#end
SJTViewController.m
#import "SJTViewController.h"
#import "SJT.h"
#implementation SJTViewController
#synthesize temp;
#synthesize sjt;
- (IBAction) setTemp: (id) sender
{
NSString *tempText = [[NSString alloc] initWithFormat:#"%d",sjt.newTemp];
temp.text = tempText;
[tempText release];
}
.
.
.
#end
The problem is that you're mistaking property syntax for a method call; i.e.
sjt.newTemp
would become a call to [sjt newTemp]. Which happens to be exactly what you want, except that you have not specified in your header/implementation that there actually is a property called newTemp.
So, in this scenario what you want to do is either a) define the property in the header:
#property(nonatomic, readonly) int newTemp;
or b), just call the method newTemp:
[sjt newTemp]
Are you certain that sjt is not nil? You don't provide the code where and instance of SJT is constructed. In Objective-C you can call a method on a nil reference without error, and if you do so on a method that returns an int it will return 0.
So sjt.newTemp will return 0 if sjt is nil.
Both Jacob and teabot have pointed out valid possible reasons -- which one is correct (or both!) depends on pieces of code we can't see in your post.
Based on what you've written so far, you might not be thinking of newTemp as a property, but more as a function call, so I would suggest changing your code to:
- (IBAction) setTemp: (id) sender {
int tempInt = [self.sjt newTemp];
self.temp.text = [NSString stringWithFormat:#"%d", tempInt];
}
which is functionally equivalent. Note the convenience constructor stringWithFormat: returns an autoreleased object, which is then retained by the retain property text of the temp UILabel.
The other thing to double-check in your code is that self.sjt is not nil, which is exactly what teabot said. Objective-C returns 0 on method calls invoked on a nil pointer.