Can not pass value of textfield to other viewcontroller in ios - iphone

I want to pass value of textfield in LoginView to uploadview but UserLogin1 always is NULL ( 0x000000)
This is my codes:
loginvuew.h
#property (nonatomic,retain) IBOutlet UITextField *username;
loginview.m
-(IBAction)LoginButton:(id)sender{
uploadview= [[UploadTab alloc] initWithFrame:CGRectMake(0,0,0,0) andUsertring:username.text];
}
uploadview.h
#property (nonatomic, copy) NSString *UserLogin1;
- (id)initWithFrame:(CGRect)frame andUsertring:(NSString *)strUser;
uploadview.m
- (id)initWithFrame:(CGRect)frame andUsertring:(NSString *)strUser
{
if (self) {
UserLogin1=[[NSString alloc] init];
UserLogin1 = strUser;
}
return self;
}
- (void)viewDidLoad
{
NSLog(#"User login: %#",UserLogin1);
self.navigationItem.title = [NSString stringWithFormat: #"Hello, %#",UserLogin1];
}
WHen run in initWithFrame(), string passing correct but in ViewDidLoad is not correct. And UserLogin1 variable always is 0x00000. DO you have sugesstions? Thansk in advance

You are messing up things I think. What class is an UploadTab ? The view does not have a method viewDidload ! It's UIViewController's one. If it is ViewController then you should allocate it properly with initWithNibName:bundle or smth like that.
ADDED:
Your code missing actual alloc-init method
- (id)initWithFrame:(CGRect)frame andUsertring:(NSString *)strUser
{
// self is nil here! It is in almost every cases done like self = [[super alloc] initBlaBla]
if (self) {
UserLogin1=[[NSString alloc] init];
UserLogin1 = strUser;
}
return self;
}

Related

Copy of string from one view to another view in iphone

hi i am new to iphone development.
I'm trying with sample where I need to copy a string from the textfield of viewController and display it on the next view with a Label.
On the first view there is button bellow the textfield.1
I am not able to fix some issues showing BAD ACESS can anyone help me in solving this.
Let me know what i'm doing Wrong.
Thank you.
//copystring.h
#interface CopystringViewController : UIViewController{
UITextField *myTextField;
NSString *somestring;
}
#property(nonatomic,retain)IBOutlet UITextField *myTextfield;
#property(nonatomic,retain)NSString *somestring;
-(IBAction)next:(id)sender;
//.m file
#synthesize myTextfield,somestring;
-(IBAction)next:(id)sender;
{
NextView * next = [[NextView alloc] initWithNewString: myTextField.text];
[self.navigationController presentModalViewController: next animated: YES];
}
NextView.h
#interface NextView : UIViewController{
UILabel *string2;
}
#property(nonatomic,retain)IBOutlet UILabel *string2;
- (id)initWithNewString:(NSString*)someString;
//.m file
#synthesize string2;
-(id)initWithNewString:(NSString*)someString {
string2 = someString;
return self;
}
Just replace method.it may run.
-(IBAction)next:(id)sender; {
NextView * next = [[NextView alloc] initWithNibName:#"NextView" bundle:nil];
next.string2=myTextField.text;
[self.navigationController presentModalViewController:next animated: YES];
}
hey string2 is a label so try string2.text = somestring;
-(id)initWithNewString:(NSString*)someString {
string2.text = someString;
return self;
}
It looks like the problem is that you're assigning an NSString (someString) to a UILabel (string2).
AppleVijay's answer should do the trick.
If you don't like dot-notation in ObjC you can also write it like this:
[string2 setText:someString]
U can declare ur somestring in to the delagate h/m file that way it wil be the global string. u can use it with appdaligateobj.stringname.
U dont evn need init u can directly add to viewdidload of next view.
string2.text = AppDalegateobj.stringName.
Delegation is the usual way to move data around like this. I wrote a very simple example project to show this in action.
You need init you view and retain you string:
-(id)initWithNewString:(NSString*)someString {
self = [super init];
if (self) {
string2.text = someString;
}
return self;
}
/
/AppDelegate.h
NSString *String1;
#property (nonatomic, retain) NSString * String1;
//AppDelegate.m
#synthesize String1
//ViewController1.h
AppDelegate * objAppDelegate;
UILable *lblstring;
#property (nonatomic, retain) UILable *lblstring;
//ViewController1.m
#synthesize lblstring
//On View Did Load.
objAppDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
lblstring.text = objAppDelegate.String1;

Passing of UITextField text from one view to another

I defined a UITextField on my firstViewController as follow
// firstViewController.h
IBOutlet UITextField *PickUpAddress
#property (nonatomic, retain) UITextField *PickUpAddress;
//firstViewController.m
#synthesize PickUpAddress;
// Push secondView when the 'Done' keyboard button is pressed
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
if (textField == PickUpAddress) {
SecondViewController *secondViewController= [[SecondViewController alloc]
initWithNibName:#"SecondViewController"
bundle:nil];
secondViewController.hidesBottomBarWhenPushed = YES;
[self.navigationController pushViewController:secondViewController animated:YES];
[secondViewController release];
}
return NO;
}
Then I tried to retrive it in my secondViewController during viewWillAppear
- (void)viewWillAppear:(BOOL)animated {
BookingViewController *bookingViewController = [[BookingViewController alloc] init];
NSString *addressString = [[NSString alloc] init];
addressString = bookingViewController.PickUpAddress.text;
NSLog(#"addressString is %#", bookingViewController.PickUpAddress.text);
}
But it returns as NULL on my console. Why is that so?
Thanks in advance :)
in secondViewController.h add
NSString *text;
#property (nonatomic, retain) NSString *text;
-(void)setTextFromText:(NSString *)fromText;
in secondViewController.m add following
- (void)setTextFromText:(NSString *)fromText
{
[text release];
[fromText retain];
text = fromText;
}
in firstViewController.m
before
[self.navigationController pushViewController:secondViewController animated:YES];
add
[secondViewContoller setTextFromText:PickUpAddress.text];
Now let me explain the code.
You are adding an NSString to second view , where we will store the text from the UITextField. Then, we've written a method, which will set that NSString from some other NSString.
Before pushing secondViewController to navigationController, you're just calling that method to set our text from PickUpAddress.text.
Hope that helped.
Problem is in your code. You are creating new object, bookingViewController, to retrieve the textField value. So it will obviously provide NULL. Rather you should use one unique object application wide to access the value.

iPhone Application Error Problem

Bear with me on this one.
I have an iphone application. It is a questionnaire application. There are several types of question, some have a slider, some have text input etc. I have developed a view controller for each type of question.
Two example types of question controllers are: TextInputQuestionViewController and SliderQuestionViewController.
I have a rootViewcontroller named QuestionnaireViewController. This is defined as follows:
#import <UIKit/UIKit.h>
#import "JSONKit.h";
#import "dbConnector.h"
#import "SliderQuestionViewController.h";
#import "TextInputQuestionViewController.h";
#import "MainMenuProtocol.h";
#interface QuestionnaireViewController : UIViewController {
NSDictionary* questions;
NSMutableArray* questionArray;
NSMutableArray* answerArray;
dbConnector* db;
SliderQuestionViewController* currQ; //need to create a generic var
TextInputQuestionViewController* currQ;
NSInteger currQNum;
NSString* qaTitle;
NSString* secId;
id<MainMenuProtocol>delegate;
}
#property(nonatomic, retain) NSDictionary* questions;
#property(nonatomic, retain) NSMutableArray* questionArray;
#property(nonatomic, retain) NSMutableArray* answerArray;
#property(nonatomic, retain) dbConnector* db;
#property(nonatomic, retain) SliderQuestionViewController* currQ;
#property(nonatomic, retain) TextInputQuestionViewController* currTI;
#property(nonatomic) NSInteger currQNum;
#property(nonatomic, retain) NSString* qaTitle;
#property(nonatomic, retain) NSString* secId;
#property(nonatomic, retain) id <MainMenuProtocol> delegate;
-(void) setQuestions;
-(void) startQuestion:(NSInteger)index isLast:(BOOL)last;
-(void) loadQuestions;
-(void) initialise;
-(void) finishQuestionnaire:(id)sender;
-(void) switchViews:(id)sender;
#end
#import "QuestionnaireViewController.h"
#import "dbConnector.h"
#import "ASIHTTPRequest.h"
#import "JSONKit.h";
#import "Answer.h";
#implementation QuestionnaireViewController
#synthesize questions, questionArray, db, currQ, currQNum, answerArray, qaTitle, secId, delegate;
-(void)viewDidLoad{
[self initialise];
answerArray = [[NSMutableArray alloc]init];
[super viewDidLoad];
self.title = qaTitle; //set to whatever section is
}
-(void) initialise {
currQNum = 0;
[self loadQuestions];
UIBarButtonItem *anotherButton = [[UIBarButtonItem alloc] initWithTitle:#"Start" style:UIBarButtonItemStylePlain target:self action:#selector(switchViews:)];
self.navigationItem.rightBarButtonItem = anotherButton;
}
-(void) loadQuestions {
db = [[dbConnector alloc]init];
//code to initialise view
[db getQuestions:secId from:#"http://dev.speechlink.co.uk/David/get_questions.php" respondToDelegate:self];
}
//called when questions finished loading
//stores dictionary of questions
- (void)requestFinished:(ASIHTTPRequest *)request
{
NSData *responseData = [request responseData];
NSString *json = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
NSDictionary *qs = [json objectFromJSONString];
self.questions = qs;
[json release];
[qs release];
[self setQuestions];
}
//assigns JSON to question objects
-(void) setQuestions {
questionArray = [[NSMutableArray alloc] init];
for (NSDictionary *q in self.questions) {
/* Create Question object and populate it */
id question;
if([[q objectForKey:#"type"] isEqualToString:#"Slider"]){
question = [[SliderQuestionViewController alloc]init];
//set min max values
}else if([[q objectForKey:#"type"] isEqualToString:#"Option"]){
}else if([[q objectForKey:#"type"] isEqualToString:#"TextInput"]){
question = [[TextInputQuestionViewController alloc]init];
}else if([[q objectForKey:#"type"] isEqualToString:#"ImagePicker"]){
}else{
//comments
}
//if else to create appropriate view controller - NEED to identify question type
[question setQuestionId:[q objectForKey:#"questionId"] withTitle:[q objectForKey:#"question"] number:[q objectForKey:#"questionNumber"] section:[q objectForKey:#"sectionId"] questionType: [q objectForKey:#"type"]];
/* Add it to question (mutable) array */
[questionArray addObject:question];
[question release];
}
}
-(void) startQuestion:(NSInteger)index isLast:(BOOL)last{
//currQ = [[QuestionViewController alloc]init];
currQ = [questionArray objectAtIndex:index];
//push currQ onto navigationcontroller stack
[self.navigationController pushViewController:currQ animated:YES];
[currQ addButton:self isLast: last];
}
//pushes new view onto navigation controller stack
-(void) switchViews:(id)sender{
Answer* ans = currQ.question.answer;
ans.questionId = currQ.question.qId;
ans.entryId = #"1";//temporary;
if(currQNum < [questionArray count] - 1){
if(currQNum > 0){
//if else for different input types
NSString* qt = currQ.question.qType;
if([qt isEqualToString:#"Slider"]){
ans.answer = currQ.sliderLabel.text;
}else if([qt isEqualToString:#"Option"]){
}else if([qt isEqualToString:#"TextInput"]){
//NSLog(#"%#", currQ.inputAnswer);
ans.answer = currQ.inputAnswer.text;
}else if([qt isEqualToString:#"ImagePicker"]){
}else{
}
[answerArray addObject: ans];
[ans release];
}
[self startQuestion:currQNum isLast:FALSE];
currQNum++;
}else{
ans.answer = currQ.sliderLabel.text;
[answerArray addObject: ans];
//store data temporarily - section finished
[self startQuestion:currQNum isLast:TRUE];
currQNum++;
}
[ans release];
}
-(void) finishQuestionnaire:(id)sender{
//go back to main manual
//if else statement for answers
NSString* answ = currQ.sliderLabel.text;
[answerArray addObject: answ];
[delegate finishedSection:answerArray section:secId];
[answ release];
[self.navigationController popToRootViewControllerAnimated:YES];
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
self.questions = nil;
self.currQ = nil;
[super viewDidUnload];
}
//hide back button in navigation bar
- (void) viewWillAppear:(BOOL)animated{
self.navigationItem.hidesBackButton = YES;
}
- (void)dealloc {
[currQ release];
[db release];
[questionArray release];
[questions release];
[super dealloc];
}
#end
the problematic lines with the above are in the switchViews function. I need to make the answer equal to the specific input component in that question view (slider value, text input value). So I need to make currQ a type that can be instantiated using any view controller.
I therefore need a generic variable to hold the current question. currQ holds the current question, but at the moment is of type SliderQuestionViewController. I tried to change this to id, but it throws a load of "Request For member...not a structure of union" and also a load of misassigned pointer issues.
Let me know if you need more code.
This reads like you want a pointer for a UIViewController, so just use that as the type. Then you can cast it down to whatever subclass you like later. For example:
-(void)myAction:(UIViewController *)vc {
SpecialViewController *svc = (SpecialViewController *)vc;
...
}
In your case, declare
UIViewController* currQ;
and then cast it as needed in the implementation to access the different properties and methods of your two subclasses.
If you're looking for a 'generic' variable, you should be able to use id. Make sure you don't define the type as id*, the asterisk should not be present.
A better idea, though, is to create a superclass for your question viewcontrollers. Create a superclass called QuestionViewController that inherits from UIViewController and have the Slider and TextInput (and any others) inherit from QuestionViewController. Then you can define your variable as: QuestionViewController* currQ; You can put any common functionality in that superclass as well and eliminate duplication.

Subclassed controls not being released

We have found a large memory issue in our application. We have subclassed UITextField and add these to all of our main views. The main views are being dealloced correctly, however the dealloc method in our subclass never gets hit. Here is our subclass:
Header:
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "MyEntities.h"
#import "MyControlHelper.h"
#interface MyTextField : UITextField {
MyControlHelper *myHelper;
UIView *disabledEffect;
}
#property (nonatomic, retain) MyControlHelper *myHelper;
#property (nonatomic, retain) UIView *disabledEffect;
#end
Implementation:
#import "MyTextField.h"
#implementation MyTextField
#synthesize myHelper;
#synthesize disabledEffect;
-(id) initWithCoder:(NSCoder *)aDecoder{
if (self = [super initWithCoder:aDecoder]){
myHelper = [[MyControlHelper alloc] init];
[myHelper setBoundTextField:self];
[myHelper SetupKeyboardListener];
[self setReturnKeyType:UIReturnKeyDone];
self.autocorrectionType = FALSE;
self.delegate = myHelper;
}
return self;
}
-(id) init{
if (self = [super init]){
myHelper = [[MyControlHelper alloc] init];
[myHelper setBoundTextField:self];
[myHelper SetupKeyboardListener];
[self setReturnKeyType:UIReturnKeyDone];
self.autocorrectionType = FALSE;
self.delegate = myHelper;
}
return self;
}
-(id)initWithFrame:(CGRect)frame{
if (self = [super initWithFrame:frame]){
myHelper = [[MyControlHelper alloc] init];
[myHelper setBoundTextField:self];
[myHelper SetupKeyboardListener];
[self setReturnKeyType:UIReturnKeyDone];
self.autocorrectionType = FALSE;
self.delegate = myHelper;
}
return self;
}
-(void)dealloc{
self.myHelper = nil;
self.disabledEffect= nil;
[super dealloc];
}
#end
Any help would be greatly appreciated.
Cheers.
You might have an issue with your myHelper reference. You have declared it as (nonatomic, retain) property. If your MyControlHelper class has a property for your MyTextField also being retained, you are building a cyclic reference and your field is retaining myHelper and vice versa.
If this is the case I suggest you declare the property for the textfield within MyControlHelper with (nonatomic, assign) to resolve the cycle.
It would help to post the code for MyControlHelper, as well.

Data going missing when passed between threads using a Singleton

Edit:
Thanks #BlackFrog. I think I'm nearer now, but the values are still not get getting through...
The values are set as shown by logs within [progressController updateProgressSummary:...] but are nil when I log them in progressUpdate initWithProgressUpdate:.... as shown below.
I'm slightly confused over which property is used the one set for progressUpdate or the ones set for each of the 3 components of progressUpdate. I have changed the 3 individual properties from assign to retain as suggested and have also tried doing the same with the overall progressUpdate property too (not shown here).
progressController.h
......
#property (nonatomic, assign) ProgressUpdate *progressUpdate;
progressController.m
// Ask delegate to update and display Progress text
-(void) updateProgressSummary:(NSString *)summary detail:(NSString *)detail percentComplete:(NSNumber *)complete {
// These report the proper values
DLog(#"Reporting Summary - %s", [summary UTF8String]);
DLog(#"Reporting Detail - %s", [detail UTF8String]);
DLog(#"Reporting Complete - %i", [complete intValue]);
if (summary != nil)
self.progressUpdate.summaryText = summary;
self.progressUpdate.detailText = detail;
self.progressUpdate.percentComplete = complete;
ProgressUpdate *progressUpdateForIssue = [[ProgressUpdate alloc] initWithProgressUpdate:progressUpdate];
[self.delegate performSelectorOnMainThread:#selector(displayProgress:) withObject:progressUpdateForIssue waitUntilDone:NO];
[progressUpdateForIssue release];
}
But then a few milliseconds later...., inside the object....they're nil.
progressUpdate.h
.....
#property (nonatomic, retain) NSString *summaryText;
#property (nonatomic, retain) NSString *detailText;
#property (nonatomic, retain) NSNumber *percentComplete;
progressUpdate.m
-(id) initWithProgressUpdate:(ProgressUpdate *)update {
if ((self = [super init])) {
summaryText = [update.summaryText copy];
detailText = [update.detailText copy];
percentComplete = [[NSNumber alloc] initWithFloat:[update.percentComplete floatValue]];
}
// These report nil values
DLog(#"Reporting in progUpdate summaryText - %s", [summaryText UTF8String]);
DLog(#"Reporting in progUpdate detailText - %s", [detailText UTF8String]);
DLog(#"Reporting in progUpdate percentComplete - %i", [percentComplete intValue]);
return self;
}
end of update
I need some help with passing data in a custom class from one thread to another. Its there before the pass but then disappears upon arrival. I've tried everything I know, but to no avail.
My background thread calls ProgressController and passes it details of the current progress. That in turn does performSelectorOnMainThread on ProgressController's delegate (the view controller) to display the details.
It was all working fine when I was passing through a single NSString, but I need to pass two strings and a number and as performSelectorOnMainThread can only pass one object, I have encapsulated these in a custom object - ProgressUpdate.
The data gets through to ProgressController correctly but is null by the time that it appears in the View Controller. I know this as I've put NSLogs in various places.
I wonder if its to do with:
multithreading and custom objects
the fact that ProgressController is a singleton, which is why I have then alloc'd a new ProgressUpdate each time its called, but that has not helped.
Any ideas welcome. For clarity, the code is below.
ProgressUpdate.h
#import <Foundation/Foundation.h>
#interface ProgressUpdate : NSObject {
NSString *summaryText;
NSString *detailText;
NSNumber *percentComplete;
}
#property (nonatomic, assign) NSString *summaryText;
#property (nonatomic, assign) NSString *detailText;
#property (nonatomic, assign) NSNumber *percentComplete;
-(id) initWith:(ProgressUpdate *)update;
#end
ProgressUpdate.m
#import "ProgressUpdate.h"
#implementation ProgressUpdate
#synthesize summaryText, detailText, percentComplete;
-(id) initWith:(ProgressUpdate *)update {
self = [super init];
self.summaryText = update.summaryText;
self.detailText = update.detailText;
self.percentComplete = update.percentComplete;
return self;
}
#end
ProgressController.m
static ProgressController *sharedInstance;
+ (ProgressController *)sharedInstance {
#synchronized(self) {
if (!sharedInstance)
[[ProgressController alloc] init];
}
return sharedInstance;
}
+(id)alloc {
#synchronized(self) {
NSAssert(sharedInstance == nil, NSLocalizedString(#"Attempted to allocate a second instance of a singleton ProgressController.", #"Attempted to allocate a second instance of a singleton ProgressController."));
sharedInstance = [super alloc];
}
return sharedInstance;
}
-(id) init {
if (self = [super init]) {
[self open];
}
return self;
}
.........
// Ask delegate to update and display Progress text
-(void) updateProgressSummary:(NSString *)summary detail:(NSString *)detail percentComplete:(NSNumber *)complete {
if (summary != nil)
self.progressUpdate.summaryText = summary;
self.progressUpdate.detailText = detail;
self.progressUpdate.percentComplete = complete;
ProgressUpdate *progressUpdateForIssue = [[ProgressUpdate alloc] initWith:progressUpdate];
[self.delegate performSelectorOnMainThread:#selector(displayProgress:) withObject:progressUpdateForIssue waitUntilDone:NO];
[progressUpdateForIssue release];
}
RootViewController.m
// Delegate method to display specific text in Progress label
- (void) displayProgress:(ProgressUpdate *)update {
[progressSummaryLabel setText:update.summaryText];
[progressDetailLabel setText:update.detailText];
[progressBar setProgress:[update.percentComplete intValue]];
[progressView setNeedsDisplay];
}
In the init method, you are only assigning the ivars and not retaining them in the new object.
Redo your init method as the following:
-(id) initWithProgressUpdate:(ProgressUpdate *)update {
if ((self = [super init])) {
summaryText = [update.summaryText copy];
detailText = [update.detailText copy];
percentComplete = [[NSNumber alloc] initWithFloat:[update.percentComplete floatValue];
}
return self;
}
Couple of points:
You should not use accessor in the init method
Rename your init method to be a lot clear
In the #property, change the assign to retain
Try removing the statement '[progressUpdateForIssue release];' in the method
'-(void) updateProgressSummary:(NSString *)summary detail:(NSString *)detail percentComplete:(NSNumber *)complete '.
Also change the property attribute from 'assign' to 'retain' in your class ProgressUpdate.
You could release those properties in the dealloc method .
Good luck.