Memory leak at text field in iphone sdk - iphone

I am getting memory leak at text fiels please suggest me how to resolve it.
I written the code in init() as:
eventTextField = nil;
eventTextField = [[UITextField alloc]initWithFrame:CGRectMake(10, 15, 300, 50)];
eventTextField.placeholder = #"Event Name";
[eventTextField setFont:[UIFont boldSystemFontOfSize:14]];
eventTextField.returnKeyType = UIReturnKeyDone;
eventTextField.keyboardAppearance = UIKeyboardAppearanceDefault;//Showing leak at this line
eventTextField.keyboardType = UIKeyboardTypeDefault;
eventTextField.delegate=self;
and I released it in dealloc method.
and in cellForRowIndex I am adding it as subview.
- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MasterViewIdentifier"];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:#"MasterViewIdentifier"] autorelease];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
UIView* elementView = [[UIView alloc] initWithFrame:CGRectMake(20,170,320,280)];
elementView.tag = 0;
elementView.backgroundColor=[UIColor clearColor];
[cell.contentView addSubview:elementView];
[elementView release];
}
UIView* elementView = [cell.contentView viewWithTag:0];
elementView.backgroundColor=[UIColor clearColor];
for(UIView* subView in elementView.subviews)
{
[subView removeFromSuperview];
}
if(indexPath.section == 0 && indexPath.row == 0)
{
CorkItAppDelegate* appDelegate = (CorkItAppDelegate*)[[UIApplication sharedApplication] delegate];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
wineNameTitleLabel.numberOfLines = 0;
[wineNameTitleLabel setFont:[UIFont boldSystemFontOfSize:14]];
if(appDelegate.isNewWine == YES)
{
wineNameTitleLabel.textColor = [UIColor blackColor] ;
wineNameTitleLabel.text = appDelegate.getNewWineName;
}
else
{
if([event.eventWineName length]>0)
{
wineNameTitleLabel.textColor = [UIColor blackColor] ;
wineNameTitleLabel.text = event.eventWineName;
}
else
{
wineNameTitleLabel.text = #"Wine Name";
}
}
[elementView addSubview:wineNameTitleLabel];
}
else if(indexPath.section == 1)
{
if(isRightButton == YES)
{
eventTextField.enabled = NO;
}
else
{
eventTextField.enabled = YES;
}
if([event.eventName length] > 0)
{
eventTextField.text = event.eventName;
}
else
{
eventTextField.text = #"";
}
[elementView addSubview:eventTextField];
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
Hope I get wucik response from your side.
Thanks in advance,
Monish.

If you still need the eventTextField. You should create a property and instance variable for it. So that, you can your class own the eventTextField and release it in the dealloc. Like this:
#interface A {
UITextField *eventTextField;
}
#property (nonatomic, retain) UITextField *eventTextField;
#end
#implementation A
#synthesize eventTextField;
- (id)init {
eventTextField = [[UITextField alloc]init];
}
- (void)dealloc {
[eventTextField release];
}
#end

you should release the UITextField after adding it to the subview
[foo addSubview:eventTextField];
[eventTextField release];
eventTextField = nil; is unnecessary btw as eventTextField is a ivar is already zeroed (pointer set to 0x0(nil))

Related

Access the contents of a row in UITableView

So, I am creating a login screen with UITableView. There are two textfields for email and password. When the user presses 'Login' button, I want to store the contents of those two textfields in two NSStrings. How do I do that? Here is the code for cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *kCellIdentifier = #"Cell";
UITextField *tf = [[UITextField alloc] init];
UITableViewCell *cell = [self.tView dequeueReusableCellWithIdentifier:kCellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:kCellIdentifier];
cell.accessoryType = UITableViewCellAccessoryNone;
if ([indexPath section] == 0) {
UITextField *playerTextField = [[UITextField alloc] initWithFrame:CGRectMake(10, 10, 250, 30)];
playerTextField.adjustsFontSizeToFitWidth = YES;
playerTextField.textColor = [UIColor blackColor];
if ([indexPath row] == 0) {
playerTextField.placeholder = #"Email";
playerTextField.keyboardType = UIKeyboardTypeEmailAddress;
playerTextField.returnKeyType = UIReturnKeyNext;
tf = jidField = [self makeTextField:#"" placeholder:playerTextField.placeholder];
[cell addSubview:jidField];
}
else {
playerTextField.placeholder = #"Password";
playerTextField.keyboardType = UIKeyboardTypeDefault;
playerTextField.returnKeyType = UIReturnKeyDone;
playerTextField.secureTextEntry = YES;
}
//playerTextField.backgroundColor = [UIColor whiteColor];
playerTextField.autocorrectionType = UITextAutocorrectionTypeNo; // no auto correction support
playerTextField.autocapitalizationType = UITextAutocapitalizationTypeNone; // no auto capitalization support
playerTextField.textAlignment = NSTextAlignmentLeft;
// playerTextField.tag = 0;
//playerTextField.delegate = self;
playerTextField.clearButtonMode = YES; // no clear 'x' button to the right
[playerTextField setEnabled: YES];
[cell addSubview:playerTextField];
}
}
return cell;
}
In cellForRowAtIndexPath, set tag for userid and password field and retrieve the textfields with its tag identifier. Please find following implementation of loginAction method.
- (void)loginAction:(id)sender {
NSIndexPath *userIdRow = [NSIndexPath indexPathForRow:0 inSection:0];
NSIndexPath *passwordFieldRow = [NSIndexPath indexPathForRow:1 inSection:0];
UITableViewCell *userIdTableCell = (UITableViewCell *)[tableview cellForRowAtIndexPath:userIdRow];
UITableViewCell *passwordFieldTableCell = (UITableViewCell *)[tableview cellForRowAtIndexPath:userIdRow];
UITextField *userIDField = (UITextField *)[userIdTableCell viewWithTag:1001];
UITextField *passwordField = (UITextField *)[passwordFieldTableCell viewWithTag:1002];
// You can store now text to either your instance variables or properties in the following statements
NSLog(#"%#", userIDField.text];
NSLog(#"%#", passwordField.text];
}
In cellForRowAtIndexPath, you have to tag your's textfields
if ([indexPath row] == 0) {
playerTextField.tag = 1001;
} else {
playerTextField.tag = 1002;
}
Just like Tarek said, this is how you do it.
In your *.h file
#interface v1ViewController : UITableViewController
{
UITextField IBOutlet *playerEmailTxt;
UITextField IBOutlet *playerPassword;
}
#property (nonatomic, retain) UITextField IBOutlet *playerEmailTxt;
#property (nonatomic, retain) UITextField IBOutlet *playerPassword;
In your *.m file
...
#synthesize playerEmailTxt;
#synthesize playerPassword;
...
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *kCellIdentifier = #"Cell";
UITableViewCell *cell = [self.tView dequeueReusableCellWithIdentifier:kCellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:kCellIdentifier];
cell.accessoryType = UITableViewCellAccessoryNone;
if (indexPath.section == 1)
{
if (indexPath.row == 0)
{
playerEmailTxt = [[UITextField alloc] initWithFrame:CGRectMake(10, 10, 250, 30)];
playerEmailTxt.adjustsFontSizeToFitWidth = YES;
playerEmailTxt.textColor = [UIColor blackColor];
playerEmailTxt.placeholder = #"Email";
playerEmailTxt.keyboardType = UIKeyboardTypeEmailAddress;
playerEmailTxt.returnKeyType = UIReturnKeyNext;
[cell addSubview:playerEmailTxt];
}
else if (indexPath.row == 1)
{
playerPassword = [[UITextField alloc] initWithFrame:CGRectMake(10, 10, 250, 30)];
playerPassword.adjustsFontSizeToFitWidth = YES;
playerPassword.textColor = [UIColor blackColor];
playerPassword.placeholder = #"Password";
playerPassword.keyboardType = UIKeyboardTypeDefault;
playerPassword.returnKeyType = UIReturnKeyDone;
playerPassword.secureTextEntry = YES;
[cell addSubview:playerPassword];
}
}
return cell;
}
Now add your login action
-(IBAction)LoginAction
{
NSMutableString *usrEmailStr = [NSMutableString stringWithFormat:#"%#", playerEmailTxt];
NSMutableString *usrPasswdStr = [NSMutableString stringWithFormat:#"%#", playerPassword];
//Do whatever you want with these strings
}
I'd also recommend you check out the free Sensible TableView framework. Seems like a perfect fit for what you're trying to do, since the framework will automatically fetch the data from your fields and store them in any data structure you wish.

returning null value from cell's textField

I've created a custom cell with a textField but I'm not able to retrieve its value.
In my tableView, there are 3 of these custom cells, together with other default cells.
When I try this:
NSString *string = customCell.textField.text;
I always get a null value...
This is my code:
TextFieldCell.m
#import "TextFieldCell.h"
#implementation TextFieldCell
#synthesize label;
#synthesize textField;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self)
{
label = [[UILabel alloc] initWithFrame:CGRectZero];
label.backgroundColor = [UIColor clearColor];
label.textAlignment = UITextAlignmentRight;
label.textColor = [UIColor blackColor];
label.font = [UIFont boldSystemFontOfSize:16.0];
label.adjustsFontSizeToFitWidth = YES;
label.baselineAdjustment = UIBaselineAdjustmentNone;
label.numberOfLines = 20;
[self.contentView addSubview:label];
textField = [[UITextField alloc] initWithFrame:CGRectZero];
textField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
textField.backgroundColor = [UIColor clearColor];
textField.font = [UIFont boldSystemFontOfSize:16.0];
textField.delegate = self;
textField.returnKeyType = UIReturnKeyDone;
[self.contentView addSubview:textField];
}
return self;
}
-(void)layoutSubviews
{
[super layoutSubviews];
CGRect r = CGRectInset(self.contentView.bounds, 8, 8);
CGRect r1 = CGRectInset(self.contentView.bounds, 8, 8);
if (label.text != nil)
{
r.size = CGSizeMake(12, 27);
label.frame = r;
r1.origin.x += self.label.frame.size.width + 6;
r1.size.width -= self.label.frame.size.width + 6;
textField.frame = r1;
}
else
{
textField.frame = r;
}
}
-(BOOL)textFieldShouldReturn:(UITextField *)aTextField
{
[textField resignFirstResponder];
return NO;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
}
#end
Table View Data Source
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 0)
{
if (indexPath.row == 0)
{
return [self textFieldCellForTableView:tableView atIndexPath:indexPath];
}
else if (indexPath.row == 1)
{
return [self textFieldCellForTableView:tableView atIndexPath:indexPath];
}
else
{
return [self defaultCellForTableView:tableView atIndexPath:indexPath];
}
}
else if (indexPath.section == 1)
{
if (indexPath.row == 0)
{
return [self textFieldCellForTableView:tableView atIndexPath:indexPath];
}
else
{
return [self defaultCellForTableView:tableView atIndexPath:indexPath];
}
}
else if (indexPath.section == 2)
{
return [self defaultCellForTableView:tableView atIndexPath:indexPath];
}
else
{
return [self chooseFotoCellForTableView:tableView atIndexPath:indexPath];
}
}
-(TextFieldCell *)textFieldCellForTableView:(UITableView *)tableView atIndexPath:(NSIndexPath *)indexPath
{
static NSString *TextFieldCellIdentifier = #"TextFieldCellIdentifier";
TextFieldCell *cell = [tableView dequeueReusableCellWithIdentifier:TextFieldCellIdentifier];
if (cell == nil)
{
cell = [[[TextFieldCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:TextFieldCellIdentifier] autorelease];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
if (indexPath.section == 0)
{
if (indexPath.row == 0)
{
cell.label.text = nil;
cell.textField.placeholder = NSLocalizedString(#"Nome", #"");
}
else
{
cell.label.text = [[NSLocale currentLocale] objectForKey:NSLocaleCurrencySymbol];
cell.textField.placeholder = NSLocalizedString(#"Costo", #"");
}
}
else
{
cell.label.text = nil;
cell.textField.placeholder = NSLocalizedString(#"URL", #"");
}
return cell;
}
Code To Retrieve TextField Value
TextFieldCell *nomeCell = (TextFieldCell *)[self tableView:self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
TextFieldCell *costoCell = (TextFieldCell *)[self tableView:self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:0]];
TextFieldCell *linkCell = (TextFieldCell *)[self tableView:self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:1]];
NSLog(#"nomeCell textField = %#", nomeCell.textField.text);
NSLog(#"costoCell textField = %#", costoCell.textField.text);
NSLog(#"linkCell textField = %#", linkCell.textField.text);
I tried to log nomeCell, costoCell and linkCell and they are correctly allocated and initialized and I'm not using ARC here...
Can anyone help me?
Thank you so much!
I assume that you have actually entered some text in the text field by the time you are trying to retrieve the values, and you are retrieving the values to update your data model rather than relying on the table view / cells to store your data?
Don't obtain the current cell by calling your table view controller's tableView:cellForRowAtIndexPath:. This should only be called by the table view when it needs a new cell.
Call the cellForRowAtIndexPath: method on the table view directly. Instead of this:
TextFieldCell *nomeCell = (TextFieldCell *)[self tableView:self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
Do this:
TextFieldCell *nomeCell = (TextFieldCell *)[self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
You are assigning text to placeholder property and you are logging textField.text.
textField = [[UITextField alloc] initWithFrame:CGRectZero];
textField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
textField.backgroundColor = [UIColor clearColor];
textField.font = [UIFont boldSystemFontOfSize:16.0];
textField.delegate = self;
//added
textField.tag = 101;
textField.returnKeyType = UIReturnKeyDone;
[self.contentView addSubview:textField];
Code To Retrieve TextField Value:
//fetch cell for which you want to get textfield then,
TextFieldCell *nomeCell = (TextFieldCell *)[cell.contentView viewWithTag:101];

Having trouble with cells repeating

I have the following method that loads cells into my table. The cell with text "No Results" is being repeated though as I scroll. What am I doing wrong with the dequeueing?
- (UITableViewCell *)tableView:(UITableView *)iTableView cellForRowAtIndexPath:(NSIndexPath *)iIndexPath {
static NSString *kCellID = #"cellID";
UITableViewCell *aCell = [iTableView dequeueReusableCellWithIdentifier:kCellID];
if (aCell == nil) {
aCell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:kCellID] autorelease];
}
if (iTableView == self.searchDisplayController.searchResultsTableView) {
if (self.isSearching) {
static NSString *aProgressIdentifier = #"SearchProgress";
aCell = [iTableView dequeueReusableCellWithIdentifier:aProgressIdentifier];
if (!aCell) {
aCell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:aProgressIdentifier] autorelease];
}
aCell.userInteractionEnabled = NO;
UILabel *aLabel = [[UILabel alloc] initWithFrame:CGRectZero];
aLabel.text = #"Searching...";
aLabel.font = [UIFont systemFontOfSize:16.0f];
aLabel.textColor = [UIColor grayColor];
aLabel.textAlignment = UITextAlignmentCenter;
[aLabel sizeToFit];
aLabel.frame = CGRectMake(floorf((self.view.frame.size.width / 2.0f) - (aLabel.frame.size.width / 2.0f)), floorf((aCell.frame.size.height / 2.0f) - (aLabel.frame.size.height / 2.0f)), aLabel.frame.size.width, aLabel.frame.size.height);
[aCell addSubview:aLabel];
[aLabel release];
UIActivityIndicatorView *aSpinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
[aCell addSubview:aSpinner];
aSpinner.frame = CGRectMake(floorf((aCell.frame.size.width / 2.0f) - (aSpinner.frame.size.width / 2.0f)) - floorf(aLabel.frame.size.width / 2.0f) - 20.0f, floorf((aCell.frame.size.height / 2.0f) - (aSpinner.frame.size.height / 2.0f)), aSpinner.frame.size.width, aSpinner.frame.size.height);
[aSpinner startAnimating];
[aSpinner release];
} else {
Class anObject = [self.masterArray objectAtIndex:iIndexPath.section];
if ([anObject isKindOfClass: [NSArray class]]) {
NSArray *sectionArray = [self.masterArray objectAtIndex:iIndexPath.section];
if (sectionArray.count > 0) {
id aCellObject = [sectionArray objectAtIndex:iIndexPath.row];
if ([aCellObject isKindOfClass:[CMACustomer class]]) {
CMACustomer *aCustomerObject = aCellObject;
aCell.textLabel.
text = aCustomerObject.customerFullName;
aCell.detailTextLabel.text = nil;
} else if ([aCellObject isKindOfClass:[CMAReservation class]]) {
CMAReservation *aReservationObject = aCellObject;
aCell.textLabel.text = aReservationObject.fullName;
aCell.detailTextLabel.text = aReservationObject.orderDescription;
// aCell.detailTextLabel.text = aReservationObject.reservationTimeAndDate;
}
} else {
aCell.userInteractionEnabled = NO;
UILabel *aLabel = [[UILabel alloc] initWithFrame:CGRectZero];
aLabel.text = #"No Results.";
aLabel.font = [UIFont systemFontOfSize:16.0f];
aLabel.textColor = [UIColor grayColor];
aLabel.textAlignment = UITextAlignmentCenter;
[aLabel sizeToFit];
aLabel.frame = CGRectMake(floorf((self.view.frame.size.width / 2.0f) - (aLabel.frame.size.width / 2.0f)), floorf((aCell.frame.size.height / 2.0f) - (aLabel.frame.size.height / 2.0f)), aLabel.frame.size.width, aLabel.frame.size.height);
[aCell addSubview:aLabel];
[aLabel release];
}
}
}
} else {
NSString *aLocalizedTitle = [[self.defaultScopeArray objectAtIndex:iIndexPath.row] objectForKey:#"localizedTitle"];
NSString *aDefaultTitle = [[self.defaultScopeArray objectAtIndex:iIndexPath.row] objectForKey:#"defaultTitle"];
aCell.textLabel.text = CMALocalizedStringWithDefaultValue(aLocalizedTitle, aDefaultTitle);
if ([[[self.currentScopeArray objectAtIndex:iIndexPath.row] objectForKey:#"enabledByDefault"] boolValue]) {
aCell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
aCell.accessoryType = UITableViewCellAccessoryNone;
}
}
return aCell;
}
A couple of things:
If you just want text labels in your cells there is no need to add a UILabel to the tableViewCell. Just use the textLabel property of the cell or the detailTextLabel property (depending on the tableviewcell type you're using).
If you do want to add a UILabel you should add it to the contentView property of the tableViewCell.
When you are adding views to a tableViewcell, you really shouldn't alloc/init it outside of the if(!Cell) {} block as every time you're recycling that tableViewcell, another another UILabel is alloc/init'd.
According to the code you posted and the problem you are seeing, it looks like sectionArrayis empty. Where is that being filled?

UITableview with textfields to arrays

I'm not sure if I am approaching this the correct way so I need some help. I have a table with 5 rows for data to be entered. After the user enters all the data there is a button on the navigation bar that will add the data to the arrays. I want to set up another view controller that displays all of the data that has been entered by the user. I hope this makes sense. Here's what I have so far.
- (void)viewDidLoad
{
[super viewDidLoad];
[self initWithStyle: UITableViewStyleGrouped];
self.navigationController.navigationBarHidden=NO;
//self.navigationItem.hidesBackButton = YES;
// Uncomment the following line to preserve selection between presentations.
//self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithTitle: #"Done" style:UIBarButtonItemStylePlain target: self action: #selector(add)] autorelease];
course = [[NSMutableArray alloc] init];
date = [[NSMutableArray alloc] init];
scores = [[NSMutableArray alloc] init];
rating = [[NSMutableArray alloc] init];
slope = [[NSMutableArray alloc] init];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return 5;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryNone;
if ([indexPath section] == 0) {
if ([indexPath row] == 0) {
UITextField *playerTextField = [[UITextField alloc] initWithFrame:CGRectMake(110, 10, 185, 30)];
playerTextField.adjustsFontSizeToFitWidth = YES;
playerTextField.textColor = [UIColor blackColor];
playerTextField.placeholder = #"Required";
playerTextField.keyboardType = UIKeyboardTypeDefault;
playerTextField.returnKeyType = UIReturnKeyNext;
playerTextField.text = [course objectAtIndex:indexPath.row];
playerTextField.backgroundColor = [UIColor whiteColor];
playerTextField.textAlignment = UITextAlignmentRight;
[playerTextField setEnabled: YES];
[cell addSubview:playerTextField];
[playerTextField release];
}
else if([indexPath row] == 1){
UITextField *playerTextField = [[UITextField alloc] initWithFrame:CGRectMake(110, 10, 185, 30)];
playerTextField.adjustsFontSizeToFitWidth = YES;
playerTextField.textColor = [UIColor blackColor];
playerTextField.placeholder = #"Required";
playerTextField.keyboardType = UIKeyboardTypeNumbersAndPunctuation;
playerTextField.returnKeyType = UIReturnKeyDone;
playerTextField.text = [date objectAtIndex:indexPath.row];
playerTextField.backgroundColor = [UIColor whiteColor];
playerTextField.textAlignment = UITextAlignmentRight;
[playerTextField setEnabled: YES];
[cell addSubview:playerTextField];
[playerTextField release];
}
else if([indexPath row] == 2){
UITextField *playerTextField = [[UITextField alloc] initWithFrame:CGRectMake(110, 10, 185, 30)];
playerTextField.adjustsFontSizeToFitWidth = YES;
playerTextField.textColor = [UIColor blackColor];
playerTextField.placeholder = #"Required";
playerTextField.keyboardType = UIKeyboardTypeNumberPad;
playerTextField.returnKeyType = UIReturnKeyDone;
playerTextField.text = [scores objectAtIndex:indexPath.row];
playerTextField.backgroundColor = [UIColor whiteColor];
playerTextField.textAlignment = UITextAlignmentRight;
[playerTextField setEnabled: YES];
[cell addSubview:playerTextField];
[playerTextField release];
}
else if([indexPath row] == 3){
UITextField *playerTextField = [[UITextField alloc] initWithFrame:CGRectMake(110, 10, 185, 30)];
playerTextField.adjustsFontSizeToFitWidth = YES;
playerTextField.textColor = [UIColor blackColor];
playerTextField.placeholder = #"Required";
playerTextField.keyboardType = UIKeyboardTypeNumbersAndPunctuation;
playerTextField.returnKeyType = UIReturnKeyDone;
playerTextField.text = [rating objectAtIndex:indexPath.row];
playerTextField.backgroundColor = [UIColor whiteColor];
playerTextField.textAlignment = UITextAlignmentRight;
[playerTextField setEnabled: YES];
[cell addSubview:playerTextField];
[playerTextField release];
}
else if([indexPath row] == 4){
UITextField *playerTextField = [[UITextField alloc] initWithFrame:CGRectMake(110, 10, 185, 30)];
playerTextField.adjustsFontSizeToFitWidth = YES;
playerTextField.textColor = [UIColor blackColor];
playerTextField.placeholder = #"Required";
playerTextField.keyboardType = UIKeyboardTypeNumbersAndPunctuation;
playerTextField.returnKeyType = UIReturnKeyDone;
playerTextField.text = [slope objectAtIndex:indexPath.row];
playerTextField.backgroundColor = [UIColor whiteColor];
playerTextField.textAlignment = UITextAlignmentRight;
[playerTextField setEnabled: YES];
[cell addSubview:playerTextField];
[playerTextField release];
}
}
}
if ([indexPath section] == 0) {
if ([indexPath row] == 0) {
cell.textLabel.text = #"Course";
}
else if([indexPath row] == 1){
cell.textLabel.text = #"Date";
}
else if([indexPath row] == 2){
cell.textLabel.text = #"Score";
}
else if([indexPath row] == 3){
cell.textLabel.text = #"Rating";
}
else if([indexPath row] == 4){
cell.textLabel.text = #"Slope";
}
}
return cell;
}
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField {
[course replaceObjectAtIndex:textField.tag withObject:textField.text];
[date replaceObjectAtIndex:textField.tag withObject:textField.text];
[scores replaceObjectAtIndex:textField.tag withObject:textField.text];
[rating replaceObjectAtIndex:textField.tag withObject:textField.text];
[slope replaceObjectAtIndex:textField.tag withObject:textField.text];
return YES;
}
Wouldn't it just be easier to put 5 text fields in a view? I don't understand why you put them in a table view... If you want them to be scrollable, you can always just wrap your entire view in a scrollview, but I wouldn't do this with a table. As far as I know, it's generally bad to use a table view for input. It's more like a way to provide a user a display of some data, e.g. an array of objects. Also, usually, if you're using an NSMutableArray as a data source, you would also want your table data source methods like tableView:numberOfRowsInSection: to return a value based on the size of the array, rather than a magic, hard coded number.
I also see you're doing a lot of work in the code. You can have Interface Builder do all this stuff for you: just make a new UIViewController subclass with a xib that goes by the same name, design it in Interface Builder, and write the logic in the .m file.
For example, let's say I have a subclass of UIViewController called MyViewController, which has a view with 1 button 'next' and 2 UITextFields, conveniently called dateTF and scoreTF. My .h file would look something like this:
#import <UIKit/UIKit.h>
#interface MyViewController : UIViewController {
IBOutlet UITextField *dateTF;
IBOutlet UITextField *scoreTF;
}
#property (nonatomic, retain) UITextField *dateTF;
#property (nonatomic, retain) UITextField *scoreTF;
- (IBAction)clickedNext:(id)sender;
#end
Here we have a placeholder for the action that will be called when the "next" button is pressed, and 2 outlets to the text fields to retrieve the data from them. I don't need an IBOutlet to the button because I won't edit it.
The .m file could look like this:
#import "MyViewController.h"
#implementation MyViewController
#synthesize dateTF
#synthesize scoreTF;
// called when the button is clicked
- (IBAction)clickedNext:(id)sender{
NSString * date = self.dateTF.text;
NSString * score = self.scoreTF.text;
// do something with this data, like put up a model and go to the next view
}
#end
This assumes I have a xib file that contains my UI. In the xib you'll also need to make a few connections (easily done with ctrl+click_and_drag from source to target, e.g. from button to File's Owner): you'll need to connect the 2 IBOutlets and the button to call the IBAction, and you should be good to go.
Hope this helps!
I use data dictionary in passing data to a new viewController and uncomment the codes in the .m:
/*
// The designated initializer. Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
// Custom initialization
}
return self;
}
*/
and add the new parameter in my case a dictionary:
Supposed the name is passDataHereController and selectedNews was declared as NSDictionary in the .h
// Note that I added the withDataDictionary:(NSDictionary*)passedDataDictionary
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil withDataDictionary:(NSDictionary*)passedDataDictionary{
if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
// Custom initialization
self.selectedNews = passedDataDictionary;
}
return self;
}
Then in the controller where you are going to pass the data
//supposed dataTobePassed is already populated
passDataHereController *newView = [[passDataHereController alloc] initWithNibName:#"passDataHereController" bundle:nil withDataDictionary:dataTobePassed];
[self.navigationController pushViewController:newView animated:YES];
[newView release];
That's one way in passing data to another view, others may have simpler solutions.
Hope it helps.

Custom uitableview cell issue

I have a custom UITableViewCell as such:
#implementation CellWithThreeSubtitles
#synthesize title, subTitle1, subTitle2, subTitle3;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
self.textLabel.backgroundColor = self.backgroundColor;
self.textLabel.opaque = NO;
self.textLabel.textColor = [UIColor blackColor];
self.textLabel.highlightedTextColor = [UIColor whiteColor];
self.textLabel.font = [UIFont boldSystemFontOfSize:22.0];
}
return self;
}
- (void)layoutSubviews
{
[super layoutSubviews];
CGRect contentRect = self.contentView.bounds;
CGRect frame = CGRectMake(35.0, 0, contentRect.size.width, 50.0);
self.textLabel.frame = frame;
UILabel *subLabel1 = [[UILabel alloc] init];
frame = CGRectMake(35.0, 34.0, contentRect.size.width, 25.0);
subLabel1.font = [UIFont systemFontOfSize:18.0];
subLabel1.backgroundColor = [UIColor clearColor];
subLabel1.text = subTitle1;
subLabel1.opaque = NO;
subLabel1.frame = frame;
[self.contentView addSubview:subLabel1];
UILabel *subLabel2 = [[UILabel alloc] init];
frame = CGRectMake(35.0, 54.0, contentRect.size.width, 25.0);
subLabel2.font = [UIFont boldSystemFontOfSize:18.0];
subLabel2.backgroundColor = [UIColor clearColor];
subLabel2.text = subTitle2;
subLabel2.opaque = NO;
subLabel2.frame = frame;
[self.contentView addSubview:subLabel2];
UILabel *subLabel3 = [[UILabel alloc] init];
frame = CGRectMake(contentRect.size.width-100.0, 54.0, contentRect.size.width, 25.0);
subLabel3.font = [UIFont systemFontOfSize:18.0];
subLabel3.backgroundColor = [UIColor clearColor];
subLabel3.text = subTitle3;
subLabel3.opaque = NO;
subLabel3.frame = frame;
[self.contentView addSubview:subLabel3];
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
- (void)dealloc {
[super dealloc];
[subTitle4 release];
[subTitle3 release];
[subTitle2 release];
[subTitle1 release];
[title release];
}
When I implement it in my UITableView like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
int section = [indexPath indexAtPosition:0];
static NSString *kCustomCellID = #"AppointmentCellID";
CellWithThreeSubtitles *cell = (CellWithThreeSubtitles *)[tableView dequeueReusableCellWithIdentifier:kCustomCellID];
if (cell == nil) {
cell = (CellWithThreeSubtitles *)[[[CellWithThreeSubtitles alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCustomCellID] autorelease];
}
switch (section) {
case 0:
if ([wineArray count]==0) {
cell.textLabel.text = #"No wine favorites selected yet";
}else{
cell.subTitle1 = [[wineArray objectAtIndex:indexPath.row] objectForKey:#"Varietal"];
cell.subTitle2 = [NSString stringWithFormat:#"Bin No. %#", [[wineArray objectAtIndex:indexPath.row] objectForKey:#"Bin"]];
cell.subTitle3 = [NSString stringWithFormat:#"$%#", [[wineArray objectAtIndex:indexPath.row] objectForKey:#"Price"]];
cell.textLabel.text = [NSString stringWithFormat:#"%# (%#)", [[wineArray objectAtIndex:indexPath.row] objectForKey:#"Name"], [[wineArray objectAtIndex:indexPath.row] objectForKey:#"Availability"]];
}
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.userInteractionEnabled = NO;
break;
case 1:
if ([dinnerArray count]==0)
cell.textLabel.text = #"No dinner favorites selected yet";
else
cell.textLabel.text = [NSString stringWithFormat:#"%#", [[dinnerArray objectAtIndex:indexPath.row] objectForKey:#"Name"]];
break;
}
return cell;
}
the contents of the cell duplicates on top of itself every time the orientation of the device changes. Is it redrawing the cell every time the device rotates? And if so, How can I keep it from doing so?
You should be creating the subviews and adding them to your cell's subviews array in your -initWithStyle:reuseIdentifier: method. You only need to create the subviews once. The -layoutSubviews method is invoked repeatedly by the framework whenever the device orientation changes, to allow you to resize and/or move the subviews (plus make any other minor adjustments) to compensate for differences between the orientations.
I suspect layoutSubViews is being called on rotation, and re-drawing new labels on top of your old ones. If you remove any labels from the table cell at the beginning of layoutSubViews that would probably fix that issue, or you could create them in the init and then just position them in layoutSubViews.