UITableViewCell with dynamic number of UILables - ios

I was trying to implement a tableview like this one
please read the comment to see the link <1>
My implementation is:
1. i create my cell from a nib!
please read the comment to see the link <2>
For testing purpose i hardcode the heading part of the cell, and i create the rest in the code like this ...
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
{
UITableViewCell *myCell = (UITableViewCell*)
[self.tableView dequeueReusableCellWithIdentifier:#"CheckedOutOrderTableCell"];
[[NSBundle mainBundle] loadNibNamed:#"CheckedOutOrderTableCell" owner:self options:NULL];
myCell = nibLoadedTableCell;
UILabel *orderConditionLabel = [[UILabel alloc] initWithFrame:CGRectMake(250, (85+([[bigDictionary objectAtIndex:indexPath.row]count]*35)), 64, 21)];
[orderConditionLabel setText:#"Delivered"];
[orderConditionLabel setFont:[UIFont systemFontOfSize:14]];
orderConditionLabel.textColor = [UIColor darkGrayColor];
orderConditionLabel.backgroundColor = [UIColor clearColor];
for(NSInteger i=0; i<[[bigDictionary objectAtIndex:indexPath.row]count]; i++)
{
UILabel *quantityLabel = [[UILabel alloc] initWithFrame:CGRectMake(15, 85+(i*35), 42, 21)];
UILabel *foodLabel = [[UILabel alloc] initWithFrame:CGRectMake(85, 85+(i*35), 175, 21)];
UILabel *priceLabel = [[UILabel alloc] initWithFrame:CGRectMake(220, 85+(i*35), 60, 21)];
[quantityLabel setFont:[UIFont systemFontOfSize:15]];
[foodLabel setFont:[UIFont systemFontOfSize:15]];
[priceLabel setFont:[UIFont systemFontOfSize:15]];
[quantityLabel setText:[NSString stringWithFormat:#"%#",[[[bigDictionary objectAtIndex:indexPath.row]objectAtIndex:i]valueForKey:#"quantity"]]];
[foodLabel setText:[NSString stringWithFormat:#"%#",[[[bigDictionary objectAtIndex:indexPath.row]objectAtIndex:i]valueForKey:#"item_name"]]];
[priceLabel setText:[NSString stringWithFormat:#"$ %#.00", [[[bigDictionary objectAtIndex:indexPath.row]objectAtIndex:i]valueForKey:#"price"]]];
[self.view addSubview:quantityLabel];
[self.view addSubview:foodLabel];
[self.view addSubview:priceLabel];
quantityLabel = nil;
foodLabel = nil;
priceLabel = nil;
}
[self.view addSubview:orderConditionLabel];
orderConditionLabel = nil;
return myCell;
}
and of course i also rewrite heightForRowAtIndexPath: and i finally got this one...
http://i.stack.imgur.com/cF7Y4.png
everything seems going right :D all the label are dynamic created and the position goes perfect... then i tried to save any other record.... and got crashed :'(
http://i.stack.imgur.com/RAXMF.png
I check the data I fed into those cells using NSLOG and below is the structure of my "bigDictionary"
2012-05-17 12:17:50.330 LazBuy[53187:11903] show structure (
(
{
"item_name" = "\U8292\U679c\U9752\U8336";
price = 30;
quantity = 1;
},
{
"item_name" = "\U6587\U5c71\U6e05\U8336";
price = 20;
quantity = 3;
},
{
"item_name" = "\U8292\U679c\U9752\U8336";
price = 30;
quantity = 3;
}
),
(
{
"item_name" = "\U51cd\U9802\U70cf\U9f8d\U8336";
price = 15;
quantity = 3;
}
)
)
The data are fed properly, I do not know what is going wrong!
Why the label didnt update properly, do I need to release them? But I cant release as ARC do not let me do the release line.

You are adding the labels to self.view? Theses should be on the tableviewcell.
[self.view addSubview:quantityLabel];
[self.view addSubview:foodLabel];
[self.view addSubview:priceLabel];
and
[self.view addSubview:orderConditionLabel];
Also your tableviewcell reuse should look more like this
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *MyIdentifier = #"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
[[NSBundle mainBundle] loadNibNamed:#"TVCell" owner:self options:nil];
cell = tvCell;
self.tvCell = nil;
}
// Set your labels text
return cell;
}

Related

How to set the text and detail text of cell in tableview?

I am getting this type of data inside cell. How to set the text and detail text of cell so that both text may appear in readable format.
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableItem";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:simpleTableIdentifier];
}
cell.textLabel.font=[UIFont fontWithName: #"Arial" size: 14.0 ];
cell.textLabel.lineBreakMode = NSLineBreakByWordWrapping;
[cell setBackgroundColor:[UIColor whiteColor]];
UILabel *idLabel = (UILabel*)[cell.contentView viewWithTag:201];
if(!idLabel)
{
idLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 200, 50)];
cell.textLabel.textColor = [UIColor blackColor];
idLabel.tag = 201;
[cell.contentView addSubview:idLabel];
}
idLabel.text = [arrayFiltered objectAtIndex:indexPath.row];
cell.textLabel.text = [idArray objectAtIndex:indexPath.row];
cell.textLabel.textColor = [UIColor grayColor];
cell.detailTextLabel.text = [descArray objectAtIndex:indexPath.row];
cell.detailTextLabel.textColor = [UIColor blueColor];
cell.detailTextLabel.numberOfLines = 2;
cell.detailTextLabel.adjustsFontSizeToFitWidth = YES;
return cell;
}
The code which i have written is above.
Please help me.
We have 3 or more options to achieve this.I explain you step by step process
I create the tableView and hook up.
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController<UITableViewDataSource,UITableViewDelegate>
#property (strong, nonatomic) IBOutlet UITableView *tblView;
#end
ViewController.m
#import "ViewController.h"
#import "CustomCell.h" // For CustomCell using,we have to import.
#interface ViewController ()
{
NSMutableArray *idArray;
NSMutableArray *descArray;
}
#end
#implementation ViewController
In viewDidLoad method I added the objects to id desc array.
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
idArray = [[NSMutableArray alloc]initWithObjects:#"INOX",#"Sathyam",#"PVR",#"IMAX",nil];
descArray = [[NSMutableArray alloc]initWithObjects:#"INOX currently operates 107 multiplexes and 420 screens in 57 cities across India",#"SPI Cinemas is an Indian multiplex chain and film production company owned by the SPI Group, headquartered in Chennai.",#"The IMAX cinema process increases the image resolution by using larger film frame;",#"PVR Cinemas is the largest and the most premium film entertainment company in India.",nil];
}
Below tableView datasource methods
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return idArray.count;
}
Now I have 3 options for achieving your requirement.But all these are implemented in cellForRowAtIndexPath method.
FIRST OPTION:UITableViewCellStyleDefault-If you use this, you can implement the code in cellForRowAtIndexPath like below
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *strCell = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:strCell];
if(cell==nil)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:strCell];
}
UILabel *idLabel = [[UILabel alloc]init];
idLabel.frame = CGRectMake(15, 13, 168, 24);
idLabel.tag = indexPath.row;
idLabel.numberOfLines = 1;
idLabel.font = [UIFont fontWithName:#"HelveticaNeue" size:18];
idLabel.textAlignment = NSTextAlignmentLeft;
idLabel.textColor = [UIColor blackColor];
idLabel.text = [NSString stringWithFormat:#"%#",[idArray objectAtIndex:indexPath.row]];
[cell.contentView addSubview:idLabel];
UILabel *descLabel = [[UILabel alloc]init];
descLabel.frame = CGRectMake(15, 47, 348, 34);
descLabel.tag = indexPath.row;
descLabel.numberOfLines = 2;
descLabel.font = [UIFont fontWithName:#"HelveticaNeue" size:12];
descLabel.textAlignment = NSTextAlignmentLeft;
descLabel.textColor = [UIColor blueColor];
descLabel.text = [NSString stringWithFormat:#"%#",[descArray objectAtIndex:indexPath.row]];
[cell.contentView addSubview:descLabel];
return cell;
}
SECOND OPTION:UITableViewCellStyleSubtitle - If you use this, you can implement the code in cellForRowAtIndexPath like below
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *strCell = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:strCell];
if(cell==nil)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:strCell];
}
cell.textLabel.text = [NSString stringWithFormat:#"%#",[idArray objectAtIndex:indexPath.row]];
cell.textLabel.tag = indexPath.row;
cell.textLabel.numberOfLines = 1;
cell.textLabel.font = [UIFont fontWithName:#"HelveticaNeue" size:18];
cell.textLabel.textAlignment = NSTextAlignmentLeft;
cell.textLabel.textColor = [UIColor blackColor];
cell.detailTextLabel.text = [NSString stringWithFormat:#"%#",[descArray objectAtIndex:indexPath.row]];
cell.detailTextLabel.tag = indexPath.row;
cell.detailTextLabel.numberOfLines = 2;
cell.detailTextLabel.font = [UIFont fontWithName:#"HelveticaNeue" size:12];
cell.detailTextLabel.textAlignment = NSTextAlignmentLeft;
cell.detailTextLabel.textColor = [UIColor blueColor];
return cell;
}
THIRD OPTION : CUSTOM CELL - If you use Custom Cell you have to import the CustomCell.h first.After that you have to do the following things in cellForRowAtIndexPath method
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:#"cell"];
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:self options:nil];
if(cell == nil){
cell = nib[0];
}
cell.idLabel.text = [NSString stringWithFormat:#"%#",[idArray objectAtIndex:indexPath.row]];
cell.idLabel.tag = indexPath.row;
cell.idLabel.numberOfLines = 1;
cell.idLabel.font = [UIFont fontWithName:#"HelveticaNeue" size:18];
cell.idLabel.textAlignment = NSTextAlignmentLeft;
cell.idLabel.textColor = [UIColor blackColor];
cell.descLabel.text = [NSString stringWithFormat:#"%#",[descArray objectAtIndex:indexPath.row]];
cell.descLabel.tag = indexPath.row;
cell.descLabel.numberOfLines = 2;
cell.descLabel.font = [UIFont fontWithName:#"HelveticaNeue" size:12];
cell.descLabel.textAlignment = NSTextAlignmentLeft;
cell.descLabel.textColor = [UIColor blueColor];
return cell;
}
I attached the screen shot of custom cell.It shows you what I have done there.
SNAPCHAT 1:idLabel
SNAPCHAT 2:descLabel
You can use heightForRowAtIndexPath method for setting row height.It is UITableViewDelegate method
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 90;
}
NOTE:Generally I set the tag for label is idLabel.tag = indexPath.row.According
to your requirement set the tag here.
I created and worked out the sample application for you.All I have done successfully.
Use cell textLable and detailTextLable to show your data like below code-
cell.textLabel.text=#"your text";
cell.detailTextLabel.text=#"your text";
idLabel overrides the position of the textlabel .
If
you want to put the id before the text , You can combine both the string and put into the textlabel.
else
use dont use textlabel and detail textlabel, create all the three labels of your own and align properly using Frame values.
Check the Height of the Cell and calculate it according to the Cell Text and number of lines of Label. And move your Font, Background Color, Line Break settings of label inside cell == nil.
Edit: to adjust three Labels you would need custom Cell or if you can concatenate it with Text Label. It all depends on your requirement.

TableViewCell is piled up and appear again and again

I implemented TableView with ADLively TableView.
But if I scroll tableView, the cell's texts become to be piled up again and again....
Using "cell.textLabel" is good, adding UILabel is not good than that but if I use "cell.textLabel", I can't resize width of textLabel.
(I want to add UIImageView on the left and right side of text)
So now, I use the way to add UILabel.
What should I do?
Here is the code.
- (void)viewDidLoad {
CGRect rect = CGRectMake(0, 50, 320, self.view.frame.size.height-150);
self.tableView = [[ADLivelyTableView alloc]initWithFrame:rect style:UITableViewStylePlain];
self.tableView = (ADLivelyTableView *)self.tableView;
self.tableView.initialCellTransformBlock = ADLivelyTransformFan;
self.tableView.delegate = self;
self.tableView.dataSource = self;
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
[self.view addSubview: self.tableView];
//self.tableView.backgroundColor = [UIColor blueColor];
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"Cell"];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.section count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
[self updateCell:cell atIndexPath:indexPath];
if (cell == nil){
myCellView = [[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:#"Cell"];
NSMutableArray *set = [self.section objectAtIndex:indexPath.row];
tableTitleLabel = [[UILabel alloc] initWithFrame:CGRectMake(50, 7, 220, 30)];
tableTitleLabel.text = [set objectAtIndex:0];
[tableTitleLabel setNumberOfLines:0];
tableTitleLabel.backgroundColor = [UIColor clearColor];
tableTitleLabel.textColor = [UIColor blackColor];
tableTitleLabel.font = [UIFont fontWithName:#"HiraKakuProN-W3" size:15];
tableTitleLabel.adjustsFontSizeToFitWidth = YES;
tableTitleLabel.minimumScaleFactor = 10.0f;
[myCellView.contentView addSubview:tableTitleLabel];
}
NSMutableArray *set = [self.section objectAtIndex:indexPath.row];
[(UILabel *)[cell.contentView viewWithTag:1] setText:[set objectAtIndex:0]];
return cell;
}
- (void)updateCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
NSMutableArray *set = [self.section objectAtIndex:indexPath.row];
tableTitleLabel = [[UILabel alloc] initWithFrame:CGRectMake(50, 7, 220, 30)];
tableTitleLabel.text = [set objectAtIndex:0];
[tableTitleLabel setNumberOfLines:0];
tableTitleLabel.backgroundColor = [UIColor clearColor];
tableTitleLabel.textColor = [UIColor blackColor];
tableTitleLabel.font = [UIFont fontWithName:#"HiraKakuProN-W3" size:15];
tableTitleLabel.adjustsFontSizeToFitWidth = YES;
tableTitleLabel.minimumScaleFactor = 10.0f;
[cell.contentView addSubview:tableTitleLabel];
}
It is not a good idea to keep adding subviews in cell on scroll but if you do not want to change the code that you have already written, use the following to remove all subviews of that cell before you call you updateCell method.
for (UIView *view in [cell subviews])
{
[view removeFromSuperview];
}

UITextViews not cleared when selected in a UITableView

I'm implementing a UITableView with text-views as the content view of my cells.
The data that the user enters is saved in a settings dictionary when the user hits the return key:
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
if (textField == _textFieldOne){
[settingsDictionary setObject: _textFieldOne.text forKey:#"EntryOneText"];
[settingsDictionary stringValueForKey:#"textFieldOneValue"];
[self postNotificationSettingsUpdate:settingsDictionary];
didTestPostNotificationSettings = YES;
}
These saved values should be displayed in the text-field when the user returns back to the screen, which I've done using the code below:
//Set the value in the text fields from the settings dictionary
NSString *textFieldOneText = [self.settingsDictionary stringValueForKey:#"RedZoneCarsPerManHrMin"];
_textFieldOne.text = textFieldOneValue;
So far, everything seems to work as expected: text input is saved, and shown in the text-field when the user returns to screen. However, if the row of the TableView that holds the text-field is select (not the text-field itself), the text-field displays the behavior shown below:
It appears as if the text-field is showing both the newly inputted entry, as well as the entry that was last saved.
EDIT I'ved added more of my cellForRowAtIndexPath method below:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForSubscribedRedZoneAlertRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"RedZoneAlertCell";
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
}
cell.backgroundColor = [UIColor colorWithRed:0.922 green:0.937 blue:0.949 alpha:1];
UISwitch *cellSwitch = nil;
NSNumber *position = enabledRedZoneAlertRows[indexPath.row];
switch (position.integerValue) {
case CarPerManHourRow: {
cell.textLabel.text = NSLocalizedString(#"Label", #"Label Row");
cellSwitch = [[UISwitch alloc] init];
cellSwitch.on = [[NSUserDefaults standardUserDefaults] boolForKey:SwitchKey];
cellSwitch.tag = SwitchTag;
[cellSwitch addTarget:self action:#selector(switchChanged:) forControlEvents:UIControlEventValueChanged];
cell.accessoryView = cellSwitch;
if ([[self.settingsDictionary valueForKey:#"RedZoneCarsPerManHrOnOff"]isEqual: #"1"]){
[cellSwitch setOn:YES];
}
break;
}
case TextFieldRow: {
static NSString *CellIdentifier = #"ConfigCell";
cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
[cell.contentView addSubview:_textFieldOne];
[cell.contentView addSubview:_textFieldTwo];
[cell.contentView addSubview:_spacingLabel];
}
cell.backgroundColor = [UIColor colorWithRed:0.922 green:0.937 blue:0.949 alpha:1];
_textFieldOne = [[UITextField alloc]initWithFrame:CGRectMake(25, 0, 50, 30)];
_textFieldTwo = [[UITextField alloc]initWithFrame:CGRectMake(100, 0, 50, 30)];
_textFieldOne.delegate = self;
_textFieldTwo.delegate = self;
_textFieldOne.placeholder = #"Auto";
_textFieldTwo.placeholder = #"Auto";
[_textFieldOne setTextAlignment:NSTextAlignmentCenter];
[_textFieldTwo setTextAlignment:NSTextAlignmentCenter];
//Set the value in the text fields from the settings dictionary
NSString *textFieldOneText = [self.settingsDictionary stringValueForKey:#"RedZoneCarsPerManHrMin"];
NSString *textFieldTwoText = [self.settingsDictionary stringValueForKey:#"RedZoneCarsPerManHrMax"];
NSString *carsPerManHrMax = [self.settingsDictionary stringValueForKey:#"RedZoneCarsPerManHrMax"];
NSString *carsPerManHrMax = [self.settingsDictionary stringValueForKey:#"RedZoneCarsPerManHrMax"];
_textFieldOne.text = textFieldOneValue;
_textFieldTwo.text = textFieldTwoValue
_textFieldOne.backgroundColor = [UIColor whiteColor];
_textFieldTwo.backgroundColor = [UIColor whiteColor];
_textFieldOne.tintColor = [UIColor blackColor];
_textFieldTwo.tintColor = [UIColor blackColor];
[_textFieldOne.layer setCornerRadius:7.0f];
[_textFieldTwo.layer setCornerRadius:7.0f];
[_textFieldOne setKeyboardType:UIKeyboardTypeNumbersAndPunctuation];
[_textFieldTwo setKeyboardType:UIKeyboardTypeNumbersAndPunctuation];
_textFieldOne.returnKeyType = UIReturnKeyNext;
_textFieldTwo.returnKeyType = UIReturnKeyDone;
_spacingLabel = [[UILabel alloc] initWithFrame:CGRectMake(70, 0, 35, 30)];
_spacingLabel.text = #"–";
_spacingLabel.textColor = [UIColor colorWithRed:0.658 green:0.658 blue:0.658 alpha:1];
[_spacingLabel setTextAlignment:NSTextAlignmentCenter];
_spacingLabel.backgroundColor = [UIColor clearColor];
//[cell.contentView addSubview:_textFieldOne];
//[cell.contentView addSubview:_textFieldTwo];
//[cell.contentView addSubview:_spacingLabel];
break;
}
return cell;
}
EDIT TWO
Below is my attempt at fixing my issue based on jherran's answer. However, I am still experiencing the same problem.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForSubscribedRedZoneAlertRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"RedZoneAlertCell";
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
}
cell.backgroundColor = [UIColor colorWithRed:0.922 green:0.937 blue:0.949 alpha:1];
UISwitch *cellSwitch = nil;
NSNumber *position = enabledRedZoneAlertRows[indexPath.row];
switch (position.integerValue) {
case CarPerManHourRow: {
cell.textLabel.text = NSLocalizedString(#"Label", #"Label Row");
cellSwitch = [[UISwitch alloc] init];
cellSwitch.on = [[NSUserDefaults standardUserDefaults] boolForKey:SWSettingCarsPerManHour];
cellSwitch.tag = SaveCarsPerManHourTag;
[cellSwitch addTarget:self action:#selector(switchChanged:) forControlEvents:UIControlEventValueChanged];
cell.accessoryView = cellSwitch;
if ([[self.settingsDictionary valueForKey:#"RedZoneCarsPerManHrOnOff"]isEqual: #"1"]){
[cellSwitch setOn:YES];
}
break;
}
case CarsPerManHourConfigRow: {
static NSString *CellIdentifier = #"ConfigCell";
cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
cell.backgroundColor = [UIColor colorWithRed:0.922 green:0.937 blue:0.949 alpha:1];
_carsPerManHourMinTextField = [[UITextField alloc]initWithFrame:CGRectMake(25, 0, 50, 30)];
_carsPerManHourMaxTextField = [[UITextField alloc]initWithFrame:CGRectMake(100, 0, 50, 30)];
_textFieldOne.delegate = self;
_textFieldTwo.delegate = self;
_textFieldOne.placeholder = #"Auto";
_textFieldTwo.placeholder = #"Auto";
[_textFieldOne setTextAlignment:NSTextAlignmentCenter];
[_textFieldTwo setTextAlignment:NSTextAlignmentCenter];
_textFieldOne.backgroundColor = [UIColor whiteColor];
_textFieldTwo.backgroundColor = [UIColor whiteColor];
_textFieldOne.tintColor = [UIColor blackColor];
_textFieldTwo.tintColor = [UIColor blackColor];
[_textFieldOne.layer setCornerRadius:7.0f];
[_textFieldTwo.layer setCornerRadius:7.0f];
[_textFieldOne setKeyboardType:UIKeyboardTypeNumbersAndPunctuation];
[_carsPerManHourMaxTextField setKeyboardType:UIKeyboardTypeNumbersAndPunctuation];
_textFieldOne.returnKeyType = UIReturnKeyNext;
_textFieldTwo.returnKeyType = UIReturnKeyDone;
_spacingLabel = [[UILabel alloc] initWithFrame:CGRectMake(70, 0, 35, 30)];
_spacingLabel.text = #"–";
_spacingLabel.textColor = [UIColor colorWithRed:0.658 green:0.658 blue:0.658 alpha:1];
[_spacingLabel setTextAlignment:NSTextAlignmentCenter];
_spacingLabel.backgroundColor = [UIColor clearColor];
NSLog(#"%#", _textFieldOne.text);
NSLog(#"%#",_carsPerManHourMaxTextField.text);
[cell.contentView addSubview: _textFieldOne];
[cell.contentView addSubview: _textFieldTwo];
[cell.contentView addSubview:_spacingLabel];
cell.tag = 1;
}
else {
_textFieldOne = (UITextField *)[cell.contentView viewWithTag:1];
_textFieldTwo = (UITextField *)[cell.contentView viewWithTag:1];
_spacingLabel = (UILabel *)[cell.contentView viewWithTag:1];
}
NSString * _textFieldOne = [self.settingsDictionary stringValueForKey:#"RedZoneCarsPerManHrMin"];
NSString *carsPerManHrMax = [self.settingsDictionary stringValueForKey:#"RedZoneCarsPerManHrMax"];
_textFieldOne.text = carsPerManHrMin;
_textFieldTwo.text = carsPerManHrMax;
How do I modify my code so that this behavior does not occur?
Check your cellForRowAtIndexPath, as cells are reused, you are probably not loading the cell property.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
/*
* This is an important bit, it asks the table view if it has any available cells
* already created which it is not using (if they are offscreen), so that it can
* reuse them (saving the time of alloc/init/load from xib a new cell ).
* The identifier is there to differentiate between different types of cells
* (you can display different types of cells in the same table view)
*/
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MyIdentifier"];
/*
* If the cell is nil it means no cell was available for reuse and that we should
* create a new one.
*/
UILabel *label;
if (cell == nil) {
/*
* Actually create a new cell (with an identifier so that it can be dequeued).
*/
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"MyIdentifier"] autorelease];
label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 30)];
cell.tag = 1;
[cell.contentView addSubview:label];
} else {
label = (UILabel *)[cell.contentView viewWithTag:1];
}
/*
* Now that we have a cell we can configure it to display the data corresponding to
* this row/section
*/
label.text = #"whatever";
}
EDIT: When your cell exits and it's reused, you are adding a view ([cell.contentView addSubview:_textFieldOne]) each time the cell is reused.
Ok, it is as I suspected. Every time the cell is taken out out the reuse queue, you create a new instance of textfield and add it to the content view. So basically the content view is piling up with new textfields.
What you should do is
1) to have a custom cell and make the cell the sole class responsible for its internals
2) expose only a configuration method to pass a raw text to cell
3) call that configuration method when thr cell is reused.
4) keep a reference to the textfield inside the custom cell to be able to update the text value any time incl. when it is recycled in cellforrowatindexpath

Add tableview cell with the value of UITextfield

I have a UITextField in a UITableView header. When the user enters anything in the UITextFields, the entry gets added to a NSMutableArray.
I want to create a new UITableCell with the value of the UITextField entry whenever textFieldShouldReturn is called.
I tried using reloadData but that seems to empty my array completely.
Any suggestions? Thanks
- (BOOL)textFieldShouldReturn:(UITextField *)task
{
[task resignFirstResponder];
[self.tasksArray addObject:task.text];
NSLog(#"Test %#", self.tasksArray);
}
My cellForRowAtIndexPath
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
SwipeTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[SwipeTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
}
[cell setDelegate:self];
[cell.contentView setBackgroundColor:[UIColor whiteColor]];
// Setting the default inactive state color to the tableView background color
[cell setDefaultColor:self.tableView.backgroundView.backgroundColor];
[cell setSelectionStyle:UITableViewCellSelectionStyleGray];
[cell.textLabel setText:self.task.text];
self.view = tableView;
cell.mode = SwipeTableViewCellModeExit;
return cell;
}
My UITableView header :
- (UIView *)tableView:(UITableView *)tableView
viewForHeaderInSection:(NSInteger)section{
float width = tableView.bounds.size.width;
int fontSize = 18;
int padding = 1;
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0,width, fontSize+11)];
view.backgroundColor = [UIColor colorWithWhite:0 alpha:0];
view.userInteractionEnabled = YES;
view.tag = section;
UITextField *task = [[UITextField alloc] initWithFrame:CGRectMake(padding, 2,
width - padding , fontSize + 11)];
task.text = #"Type here";
task.borderStyle = UITextBorderStyleRoundedRect;
task.textAlignment = NSTextAlignmentCenter;
task.backgroundColor = [UIColor whiteColor];
task.textColor = [UIColor blackColor];
task.delegate = self;
task.font = [UIFont boldSystemFontOfSize:fontSize];
[view addSubview:task];
self.tasksArray = [[NSMutableArray alloc] init];
return view;
}
viewDidLoad
- (void)viewDidLoad {
[super viewDidLoad];
self.tasksArray = [NSMutableArray arrayWithCapacity:0];
self.title = #"Test";
self.navigationController.navigationBar.tintColor = [UIColor darkGrayColor];
UIView *backgroundView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
[backgroundView setBackgroundColor:[UIColor colorWithRed:227.0 / 255.0
green:227.0 / 255.0
blue:227.0 / 255.0
alpha:1.0]];
[self.tableView setBackgroundView:backgroundView];
}
Remove [cell.textLabel setText:self.task.text];
And then,
Insert [self.yourTableOutletName reloadData]; after [self.tasksArray addObject:task.text];
Now your code will reload the tableView after adding a object into self.taskArray.
And then,
To reflect your array in tablView use this line.
Insert [cell.textLabel setText:[self.tasksArray objectAtIndex:indexPath.row]]; after [cell setSelectionStyle:UITableViewCellSelectionStyleGray];
This line pulls the data incorrectly: [cell.textLabel setText:self.task.text];
self.view = tableView;
It should be from your array.
Also you never reload data, that should be the last line in textFieldShouldReturn

UIButtons & UILabels inside a tableviewcell

I have two UIButtons and some labels inside a table view cell. I have 2 sections, the first section contains one table view cell and inside of that cell there are two UIButtons that call on an api to fetch new data for the cells in section 2. In a certain if case, a label is created because the string is very long so I have to create a new frame for the cell.
The problem that I am currently having is that the button text also gets update with new information and sometimes the string is short or sometimes the string is long, so I have to remove the button and a add a new button with a new frame to fit the new string. But if the past button string was shorter than the new one, the button still appears in the background. I tried removing it from the superview and also checking that it has removed from the superview (check that it is null once I remove it) and it is, but it still appears on the screen. The same thing happens with the UILabels as well. I also tried to removing them from super view with a tag (viewWithTag:123). Anyone have any pointers, ideas, suggestions, anything really, that could help me figure/fix this out?
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
UIView *selectedBackgroundView = [[UIView alloc] initWithFrame:CGRectZero];
selectedBackgroundView.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.1];
cell.selectedBackgroundView = selectedBackgroundView;
if(cell==nil) { NSLog(#"Cell is still nil");}
}
cell.textLabel.text = nil;
cell.accessoryView = nil;
cell.detailTextLabel.text = nil;
cell.userInteractionEnabled = YES;
if(indexPath.section == 0)
{
dosageButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
amountButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[dosageButton setContentHorizontalAlignment:UIControlContentHorizontalAlignmentLeft];
[dosageButton setContentEdgeInsets:UIEdgeInsetsMake(0, 15, 0, 0)];
[amountButton setContentHorizontalAlignment:UIControlContentHorizontalAlignmentLeft];
[amountButton setContentEdgeInsets:UIEdgeInsetsMake(0, 15.5, 0, 0)];
if(strengths.count == 0) { [dosageButton setTitle:#"Dosage" forState:UIControlStateNormal];}
else
{
[dosageButton setTitle:selectedStrength forState:UIControlStateNormal];
CGSize stringsize = [selectedStrength sizeWithFont:[UIFont systemFontOfSize:14]];
[dosageButton setFrame:CGRectMake(5, 27.5, stringsize.width + 30, 30)];
}
if(quantity.count == 0) { [amountButton setTitle:#"Amount" forState:UIControlStateNormal];}
else
{
int value = [selectedQuantity intValue];
if (value == 1)
{
NSString *amountAndFormat = [NSString stringWithFormat:#"%# %#", selectedQuantity, selectedFormat];
[amountButton setTitle:amountAndFormat forState:UIControlStateNormal];
CGSize stringsize = [selectedStrength sizeWithFont:[UIFont systemFontOfSize:14]];
CGSize amountSize = [amountAndFormat sizeWithFont:[UIFont systemFontOfSize:14]];
if(amountSize.width+stringsize.width > 250)
{
dosageButton.frame = CGRectMake(5, 27.5, 130, 30);
amountButton.frame = CGRectMake(140, 27.5, 160, 30);
}
else
{
[amountButton setFrame:CGRectMake(stringsize.width + 40, 27.5, amountSize.width + (amountSize.height * 2.1), 30)];
}
}
else
{
NSString *amountAndFormat = [NSString stringWithFormat:#"%# %#", selectedQuantity, selectedFormatPlural];
[amountButton setTitle:amountAndFormat forState:UIControlStateNormal];
CGSize stringsize = [selectedStrength sizeWithFont:[UIFont systemFontOfSize:14]];
CGSize amountSize = [amountAndFormat sizeWithFont:[UIFont systemFontOfSize:14]];
if(amountSize.width + stringsize.width> 250)
{
dosageButton.frame = CGRectMake(5, 27.5, 130, 30);
amountButton.frame = CGRectMake(140, 27.5, 160, 30);
}
else
{
[amountButton setFrame:CGRectMake(stringsize.width + 40, 27.5, amountSize.width + (amountSize.height * 2.1), 30)];
}
}
}
[dosageButton addTarget:self action:#selector(showDosages:) forControlEvents:UIControlEventTouchUpInside];
[amountButton addTarget:self action:#selector(showAmount:) forControlEvents:UIControlEventTouchUpInside];
//[cell.contentView addSubview:dosageButton];
//[cell.contentView addSubview:amountButton];
//adding it to view instead of cell because of userInteraction.
//if I add it to cell.contentView and userInteractionEnabled = NO
//then the user can't press the button
//but if the it is enabled then they can click the cell and looks tacky!
[self.view addSubview:dosageButton];
[self.view addSubview:amountButton];
cell.userInteractionEnabled = NO;
}
if(indexPath.section == 1)
{
if(localName.count == 0)
{
//Nothing
}
else
{
CGRect longStringFrame = CGRectMake(12, 4, 250, 120);
//UILabel *longStringLabel = [[UILabel alloc] initWithFrame:longStringFrame];
UILabel *longStringLabel = [[UILabel alloc] initWithFrame:longStringFrame];
longStringLabel.backgroundColor = [UIColor clearColor];
longStringLabel.font = [UIFont systemFontOfSize:12];
longStringLabel.text = [NSString stringWithFormat:#"Something super duper long. Some really really long string that has a lot of information and cannot fit in one line so I have to use numberOfLines = 0 and NSLineBreakByWordWrapping. This string is really really really long.]];
longStringLabel.textColor = [UIColor blackColor];
longStringLabel.numberOfLines = 0;
longStringLabel.lineBreakMode = NSLineBreakByWordWrapping;
cell.textLabel.text = #"";
longStringLabel.tag = 123;
[cell.contentView addSubview:longStringLabel];
}
}
}
- (void) showDosages:(UIButton *)sender
{
[dosageButton removeFromSuperview];
[amountButton removeFromSuperview];
[[cell.contentView viewWithTag:123] removeFromSuperview];
NSLog(#"%#",[dosageButton superview]);
NSLog(#"%#",[amountButton superview]);
//Also tried it this way as well. Didn't work
//[dosageButton performSelectorOnMainThread:#selector(removeFromSuperview) withObject:nil waitUntilDone:NO];
//[amountButton performSelectorOnMainThread:#selector(removeFromSuperview) withObject:nil waitUntilDone:NO];
dispatch_async(someDispatch, ^{ NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString: [NSString stringWithFormat: #"http://somewebsite.com"]]]; [self performSelectorOnMainThread:#selector(fetchData:) withObject:data waitUntilDone:YES]; });
}
showAmount is similar to showDosages
I would suggest you to create a custom cell put all the labels & buttons you want, give an iboutles so that you can easily manage things.
Custom cell tutorial
http://mobile.tutsplus.com/tutorials/iphone/customizing-uitableview-cell/
Once you made your cell you can set the height of cell according to your string. Your buttons will automatically adjusted when your cell size is increased or decreased
Here is the simple example of multiple cell identifier hope it might help
- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier1 = #"Cell1";
static NSString *CellIdentifier2 = #"Cell2";
if(flag == 0) {
MainArticleTableViewCell *cell = (MainArticleTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier1];
if (cell == nil) {
cell = [[[MainArticleTableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier1] autorelease];
}
cell.textLabel.text= #"Cell1";
return cell;
}
else {
NewsTableViewCell *cell = (NewsTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier2];
if (cell == nil) {
cell = [[[NewsTableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier2 orientation:currentOrientation] autorelease];
}
cell.textLabel.text= #"Cell1";
return cell;
}
return nil;
}

Resources