Accessing a UITextField from an array in Objective-C - iphone

I have 4 UITextFields that I'm dynamically creating, in the viewDidLoad, which works good. I want to reference those objects when the UISlider value changes. Right now I'm storing those objects in a NSMutableArray and accessing them like so from the sliderChanged method:
NSInteger labelIndex = [newText intValue];
labelIndex--;
NSUInteger firstValue = (int)0;
NSMutableArray *holeArray = [pointsArray objectAtIndex:labelIndex];
UITextField *textField = [textFieldArray objectAtIndex:firstValue];
NSString *newLabel1Text = [[NSString alloc] initWithString:[[holeArray objectAtIndex:firstValue] stringValue]];
[textField setText: newLabel1Text];
[newLabel1Text release];
Everything is working good, but the program crashes on the setText: method. The last message I get from the program is: [UILabel drawTextInRect:] and then I get a EXC_BAD_ACCESS failure.
I want to be able to acces that dynamically created UITextField, but I must be going about it the wrong way.
Thanks!

Uh, yea, you create a text field, but you aren't displaying the field itself, just creating it.
If you want to do what I think you want to do, I would just do if statements.
ex.
if (firstValue == 1)
{
fieldone.text = #"whatever";
}
else if (firstValue == 2)
{
fieldtwo.text = #"whatever";
}

Related

How can I read UITextField value in an IBAction. I'm creating UITextField programmatically

How can I read UITextField value in an IBAction? I'm creating UITextField programmatically. So I can't set #property and #synthesize using Xcode. The code to generate UITextField is as follows:
for(i=0; i<[fieldName count]; i++)
{
UITextField *name = [fieldName objectAtIndex:i];
frame = CGRectMake(fromLeft, fromTop, totalWidth, totalHeight);
name = [[[UITextField alloc] initWithFrame:frame] autorelease];
name.borderStyle = UITextBorderStyleRoundedRect;
name.returnKeyType = UIReturnKeyDone;
//name.placeholder = [fieldName objectAtIndex:i];
name.autocapitalizationType = UITextAutocapitalizationTypeWords;
name.adjustsFontSizeToFitWidth = TRUE;
name.keyboardType = UIKeyboardTypeDefault;
[name addTarget:self action:#selector(doneEditing:) forControlEvents:UIControlEventEditingDidEndOnExit];
[scroller addSubview:name];
fromTop = fromTop + 40;
}
Now I want to read values of each textbox in a button click (IBAction). Can anyone help me please?
You could use something like this to loop through all UITextFields that are subviews of self.view and add their text to a NSMutableArray:
for (UITextField *field in self.view.subviews) {
if ([field isKindOfClass:[UITextField class]]) {
if ([[field text] length] > 0) {
[someMutableArray addObject:field.text];
}
}
}
if your doneEditing: looks like this doneEditing:(id)sender then you can say:
UITextField *field = (UITextField *)sender;
NSString *myText = field.text;
EDIT:
To access a UITextField without setting as an instance variable you need to tag it when you create it:
[textField setTag:1];
then whenever you want to access it you can get it from its parent view by the tag:
UITextField *myTextField = [scroller viewWithTag:1];
NSString *myString = myTextField.text;
in your case, set the tag to i+1 for example to have all the textfield with unique tags.
implement the IBAction function like the following:
-(IBAction) doneEditing:(UITextField*)sender
{
NSString * val = sender.text;
}
try using the UITextFieldDelegate , i think its better for your case.
add each UITextField a Tag and by that you will recognise the UITextField.
NSString *value = sender.text;
If inside an IBAction, of course.
Which ignores that there is a set of text fields, and a single button action.
The simplest solution to the overall problem would be to store a set (or array) of text fields in an instance variable, and iterate over that set in the button action. But that is a rather coarse approach; it is probably better to use the text field delegate method and store text values directly in an array, using the button to trigger the save.
In addition, Apple HIG would tell you that you should update your data model as the text fields are edited, rather than use a "Save" button - which is poor UX design - unless, of course, the values of individual fields can interact.

App crash in button

I have face strange problem on UIButton.
When i tap button the app is crash .
I wrote below code for that...
-(IBAction)renameTest:(id)sender
{
NSLog(#"Tapped");
// UIButton *button = (UIButton *)sender;
NSUInteger row = 1;//button.tag;
NSString * titlename = [titleArray objectAtIndex:row];
RenameTest *renameVC = [[RenameTest alloc]initWithNibName:#"RenameTest" bundle:nil];
renameVC.titlespell = titlename;
NSLog(#"titlespell = %#",renameVC.titlespell);
NSLog(#"title = %#",titlename);
// [button release];
[self.navigationController pushViewController:renameVC animated:YES]; //here APP is cresh
[renameVC release];
}
I check also my .Xib file name .It is ok and files are there.
error msg is below :
2012-07-11 14:28:29.079 TestApp[238:207] -[__NSCFDictionary _isNaturallyRTL]: unrecognized selector sent to instance 0x73d8a80
Thanks in Advance.
[button release] is causing the problem. Remove it and check.
_isNaturallyRTL is an NSString method (private), and it looks like you are passing a dictionary instead of a string somewhere.
Breaking on the exception and showing us the call stack at that point would help tremendously.
If u have created the button in xib file then u cannot release it because you have not allocated it and claimed ownership.. U should call release only on objects you have allocated by calling alloc..
Remove the [button release] statement .. that should fix the crash!
You have a crash which is related to a dictionary and your titlename string is set equal to, titleArray objectAtIndex:row. I believe, without seeing the declaration of your variables, that titleArray is a dictionary, or is a NSMutableArray importing from a plist of dictionaries, either way you need to use objectForKey, when using dictionaries, like this:
[[titleArray objectAtIndex:(NSUInteger *)] objectForKey:(NSString *)]
Obviously replace (NSUInteger *) with your integer row and (NSString *) with the name of your key. This may not be the answer but from your crash report and visible code, this is what I assume.

NSArray of UITextFields, how can i find a specific one?

i loaded up an array with UITextFields, they are all created dynamically (and locally) and i need to keep reference to them for a later point.
my text fields are name, textField01, textField02, etc.
i want to pull out textField02 out and change the data. how can i search through my array of them get it out? i tried "isEqualToString" and failed. i can't use the .tag cause i'm using that for something else. i can't compare to the .text value cause i don't know what it will be (entered by user).
You could use NSDictionary here. Add each text field with a named key that you'll use for retrieval later.
If you are naming them sequentially why not just add them to an NSMutableArray
Then you can get at them by index.
NSMutableArray *textFields = [[NSMutableArray alloc] initWithCapacity:10];
UITextField *textField = nil;
for (int i = 0; i < 10; i++) {
textField = [[UITextField alloc] initWithFrame:myFrame];
[self.view addSubview:textField];
[textFields addObject:textField];
[textField release]; textField = nil;
}
Later on
UITextField *myTextField = [textFields objectAtIndex:1];

iPhone SDK: Can I nab in instance variable from one view and access it in another?

I'm pretty new to OOP in general and just really started working with Obj-c a few months back. So, please be gentle! I appreciate your help in advance. Now to the question!
I have 3 Text Fields where a user inputs name, phone, and email.
I collect and place them in a label using an NSString like this [this is the one for the name]:
- (IBAction)changeGreeting:(id)sender {
self.name = textInput.text;
NSString *nameString = name;
if([nameString length] == 0) {
nameString = #"I Forgot";
}
NSString *greeting = [[NSString alloc]
initWithFormat:#"Hello, my name is %#! Really!", nameString];
label.text = greeting;
[greeting release];
}
With this I have been able to place the text from text.input into my label (as stated in label.text = greeting;)
I have another view where I'd like to have someone review this information (view a label too). I need to have access to name or Textinput.text in that other view.
How can I accomplish this?
If you don't need to communicate changes between the two view controllers, you may want to pass it in using a custom init method. This may be best for a confirmation screen, where the prompt would make no sense without this string.
- (id)initWithFrame:(CGRect)aRect username:(NSString*)aName {
if((self = [super initWithFrame:aRect])) {
_myName = [aName retain];
}
return self
}
Another option is to implement a method on the first view controller and call it from the second.
- (NSString*)enteredUsername {
return _myName;
}

Class variable type gets changed

So in my view controller, I run code to populate an NSArray of Customer (custom class) objects. This custom class has objects that are of ANOTHER custom class called Address (a customer has a billing address and a shipping address). In the view controller when a customer in the list is selected, it passes a new view controller a customer object, like so:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
InfoViewController *customerinfoViewController = [[InfoViewController alloc] initWithStyle:UITableViewStyleGrouped andCustomer:[[[customers objectAtIndex:indexPath.section] objectAtIndex:indexPath.row] retain]];
[self.navigationController pushViewController:customerinfoViewController animated:YES];
[customerinfoViewController release];
}
The first time I visit this view controller while running the application, it works fine. However, when I revisit the view controller, something interesting happens. The application crashes, with unrecognized selector sent to instance 0x00whatever. Using the mouseover debugging feature in xCode, I am finding that the first object of the customer's shipAddress variable has its type changed from NSString to NSIndexPath. This does not happen to the customer's billAddress object. Anyone have any idea what is going on here? It seems like I may be having memory management issues but I would definitely like a confirmation on this before I tear my code apart tracking down all the retains and releases....
EDIT: More information here. with the following code, I have an NSMutableArray at the class level. At each iteration of the loop, I am looping through nodes in XML (which works fine). Every time a new letter is detected as the first letter of the name, I create a new subarray and add the customer to it, thus filling my class-level NSMutableArray (customers) with subArrays of customers for each letter of the alphabet detected. My question is about the retains and releases of the cycling customer object. Clang Static says there is an over-retaining error on the customer, but when I fix it according to Clang, the loop crashes. what gives? Related code below:
DDXMLDocument *rootDoc = [[[DDXMLDocument alloc] initWithData:xmlData options:0 error:nil] autorelease];
NSArray *elems = [rootDoc nodesForXPath:#"QBXML/QBXMLMsgsRs/CustomerQueryRs/CustomerRet" error:nil];
DDXMLNode *node;
sectionTitles = [[[NSMutableArray alloc] initWithCapacity:1] retain]; // Letters for UITableView section titles
NSMutableArray *subArray;
NSString *lastchar = #"A";
NSString *testchar;
int indexCount = -1;
customers = [[[NSMutableArray alloc] initWithCapacity:[elems count]] retain];
Customer *newCust;
for (int i = 0; i < [elems count]; i++) {
node = [elems objectAtIndex:i];
newCust = [[Customer alloc] initWithCustomerRetNode:node];
testchar = [[newCust fullName] substringToIndex:1];
if (i == 0 || ![[testchar uppercaseString] isEqualToString:lastchar]) {
[sectionTitles addObject:testchar];
lastchar = testchar;
indexCount++;
subArray = [[NSMutableArray alloc] initWithCapacity:1];
[customers addObject:subArray];
[subArray release];
[[customers lastObject] addObject:[newCust retain]];
}
else {
[[customers lastObject] addObject:[newCust retain]];
}
[newCust release];
}
NOTE: this code works for the most part, but clang doesn't like it.
EDIT: Addresses in the Customer class are assigned like so (which now does not work after Clang fixes)
...
else if ([tempname isEqualToString:#"BillAddress"])
billAddress = [billAddress initWithAddressNode:tempnode];
else if ([tempname isEqualToString:#"ShipAddress"])
shipAddress = [shipAddress initWithAddressNode:tempnode];
...
It sounds like you are having a over release issue, so yes memory management, you might be overreleasing that array you are storing your objects in.Cant really tell from the snippet of code though. Youll have to go and look through the code and find the source. Also using Clang Static Analyzer might be of help to you.