How to clear whole tableview data and reload with new one?
Clear your data before calling reloadData, and now the user will see the table get cleared and re-populated with fresh data.
myArray = nil;
[myTableView reloadData];
use [tableView reloadData] method on ui table view
This was my wrok around which worked.
set cell = nil;
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell = nil;
By the way, clearsContextBeforeDrawing is a property, and
[cell.contentView clearsContextBeforeDrawing];
does nothing except of returning its value.
ok.. but.. we need the solution for this.. if we add the cells in runtime, i have received the output with the same cells in first and last cells of the uitableview..
you can clear the cell before add any subviews
Example:
[mytableview.contentView clearsContextBeforeDrawing];
You can look at the value of the reused cell and if its not the same - then recreate it.
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MyLog(#"Start Table: cellForRowAtIndexPath: %d", indexPath.row);
NSString *MyIdentifier = [NSString stringWithFormat:#"MyIdentifier %i", indexPath.row];
UILabel *lblNew;
lblNew = [UILabel new];
UILabel *lblCell;
lblCell = [UILabel new];
MyTableCell *cell = (MyTableCell *)[tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil)
{
cell = [[[MyTableCell alloc] initWithFrame:CGRectZero reuseIdentifier:MyIdentifier] autorelease];
[cell.contentView addSubview:[lblNameArray objectAtIndex:indexPath.row]];
}
else
{
lblNew = [lblNameArray objectAtIndex:indexPath.row];
for (id label in [cell.contentView subviews])
{
if ([label isKindOfClass:[UILabel class]])
{
lblCell = label;
}
}
if (![lblNew.text isEqualToString:lblCell.text])
{
cell = [[[MyTableCell alloc] initWithFrame:CGRectZero reuseIdentifier:MyIdentifier] autorelease];
[cell.contentView addSubview:[lblNameArray objectAtIndex:indexPath.row]];
}
}
return cell;
Swift: Not sure it's the best way or not, But I'm using this code to clear and roload Data:
fileprivate func clearTable() {
self.tableviewData.removeAll(keepingCapacity: false)
self.tableView.reloadData()
}
I had double entries on selection after scrolling. Now the Display is as clean as expected!
Used the workaround
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell = nil;
and also (btw: clearsContextBeforeDrawing as standalone it did not work
[cell.contentView clearsContextBeforeDrawing];
in Simulator i have the impression of more accurate reaction on cell selection.
Thank you!
Related
I am attempting to update a label inside a cell(note, this is NOT the cell's label text. Its another custom label inside of the cell) after the user selects a value from a previous screen and the nav controller popping them back.
However, when I call reloadData, instead of the label in the cell being cleaned and the new value being placed, its actually stacking on top of what was there already. Like if you took the number 200 and placed a 50 on top of it. You get a weird mesh of the 0 and 5 on top of each other.
Any ideas on how to adjust this? Do I have to reset the label's text to "" every view did appear? and if so, what's the best way to do this, I've tried in the cellForRowAtIndexPath method, but no change.
cellforRowAtIndexPath code
// Set up the cell...
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
// get the dictionary object
NSDictionary *dictionary = [_groups objectAtIndex:indexPath.section];
NSArray *array = [dictionary objectForKey:#"key"];
NSString *cellValue = [array objectAtIndex:indexPath.row];
cell.textLabel.text = cellValue;
//label for currently selected/saved object
_currentSetting = [[UILabel alloc] initWithFrame:CGRectMake(160, 8, 115, 25)];
[_currentSetting setFont:[UIFont systemFontOfSize:14]];
_currentSetting.backgroundColor = [UIColor clearColor];
_currentSetting.textColor = [UIColor blueColor];
_currentSetting.textAlignment = NSTextAlignmentRight;
_currentSetting.text = [NSString stringWithFormat:#""];
_currentSetting.text = [NSString stringWithFormat:#"%# mi",[setting.val stringValue]];
[cell.contentView addSubview:_currentSetting];
return cell
You are recreating the label and re-adding it every time the cell gets refreshed. All of your cell subviews should only be added when you create the cell the first time.
So in your code you create a cell and all subviews the first time. Then if you need a new cell for scrolling or any other reason you get a reusable cell that has already had all the subviews added to it (re-usable...). Then you go through the process of adding the subviews (again) so now that cell contains the subviews from the previous owner (data) of that cell and the new owner (data) of that cell. That is why they appear stacked on top of eachother when you reload the data.
seudo code:
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: CellIdentifier];
if (cell == nil) {
//Add all subviews here
}
//Modify (only modify!!) all cell subviews here
return cell;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UILabel *customLabel;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
customLabel = [[UILabel alloc] initWithFrame:CGRectMake(0,0,320,44)];
customLabel.tag = 123;
[cell addSubview:customLabel];
} else {
customLabel = (UILabel *)[cell viewWithTag:123];
}
customLabel.text = #"Some nice text";
return cell;
}
I want tableView not to load a cell that contains some string, how to do that?
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
NSString *itemTitle = item.title;
if ([item.title isEqualToString: #"Some string"])
{
// Help needed
}
else
{
cell.textLabel.font = [UIFont boldSystemFontOfSize:15];
cell.textLabel.text =itemTitle;
}
return cell;
One possible option can be you save indexPath of cell that you don't want to show on screen when table is being loaded and once loading is completed delete them form table using following method.
- (void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation
Better option is to update your data before providing loading the table.
If both of above fails then you can try following method
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
Return 0 if you don't want cell to appear on screen. Probably cell with height 0 will not appear.
If above don't work then post here so that i can assist further....
Hey guys i have a table view that can add and delete cells. but when i delete the only cell that comes with the app, and i try to add a new cell with the text of "Meghan Way" and the text just automatically changes it self to the original cells text which is "House 1" here is my code!
- (IBAction)saveButton:(id)sender {
FacePlatesViewController * viewController = (FacePlatesViewController
*)self.parentViewController;
[viewController addObject:[NSMutableDictionary dictionaryWithObject:text.text
forKey:#"name"]];
[self dismissModalViewControllerAnimated:YES];
}
- (IBAction)cancel:(id)sender {
[self dismissModalViewControllerAnimated:YES];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:
(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero
reuseIdentifier:CellIdentifier] autorelease];
cell.textLabel.text = [[cells objectAtIndex:indexPath.row] valueForKey:#"name"];
UIImage * myimage = [UIImage imageNamed: #"check.png"];
image = [[UIImageView alloc]initWithImage:myimage];
tableView.backgroundColor = [UIColor clearColor];
self.myTableView = tableView;
}
return cell;
}
this is for the save button! any help would be very appreciated:D Thanks
You code is quite messed up. I have improved it below and added comments:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:
(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero
reuseIdentifier:CellIdentifier] autorelease];
} //The if block should end here. You should set the cell's label irrespective whether the cell was nil. This is the cause of the issue you are facing.
cell.textLabel.text = [[cells objectAtIndex:indexPath.row] valueForKey:#"name"];
//You are doing nothing with the UIImage
//UIImage * myimage = [UIImage imageNamed: #"check.png"];
//image = [[UIImageView alloc]initWithImage:myimage];
//You should be setting the background color just once, in ViewDidLoad, not here.
//tableView.backgroundColor = [UIColor clearColor];
//I don't see why this is required
//self.myTableView = tableView;
return cell;
}
Are you storing the text labels for these cells in any kind of array or dictionary and loading them in there using the standard "cellForRowAtIndexPath?" If so, then you need to delete the dictionary / array entry in that data source to prevent it from being used again.
I can't tell for sure without seeing some more code...but it sounds like a cell recycling issue. I could be wrong...but I'd need to see more info.
I have a segmented tableView that loads all the data in all the cells of all the sections.
There is a textField in each cell.
The tableview doesn't fit the iPad screen completely, and I can't access all the invisible cells in order to read/save data. And when I make changes in "textField", then scroll up, the scroll down, all the changes are gone.
I need to load all the cells, even invisible once, to be able to access them.
I am sorry, I just started working with tables a few days ago...
I think that this problem has something to do with reusable cells, but not sure how to resolve it.
Looking for your help, please.
initialization:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 400, 30)] ;
textField.enabled = NO;
cell.accessoryView = textField;
[textField release];
}
UITextField *textField = (UITextField*)cell.accessoryView;
if(indexPath.section == 0)
cell.textLabel.text = [idenInfo objectAtIndex:indexPath.row];
else if (indexPath.section == 1)
cell.textLabel.text = [prodInfo objectAtIndex:indexPath.row];
else if (indexPath.section == 2)
cell.textLabel.text = [visInfo objectAtIndex:indexPath.row];
if(indexPath.section == 0)
textField.text = [idenInfoRez objectAtIndex:indexPath.row];
else if (indexPath.section == 1)
textField.text = [prodInfoRez objectAtIndex:indexPath.row];
else if (indexPath.section == 2)
textField.text = [visInfoRez objectAtIndex:indexPath.row];
textField = nil;
return cell;
}
First of all : you don't have to load all the cells including the invisible ones. That's the whole point of the UITableView and MVC Pattern : separate your views from your data.
What you'll want to do is update your Data source (that is idenInfoRez, prodInfoRez and vizInfoRez in your case) when the user has changed a value inside a textField. So you'll have to set your UIViewController as the delegate of each textfield and update the values as the user types in.
[UIView beginAnimations:#"ShiftUp" context:nil];
[UIView setAnimationDuration:0.0001];
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSInteger section = [indexPath section];
static NSString *CellIdentifier = #"Cell";
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
[[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:self options:nil];
cell = objCustCell;
cell.selectionStyle = UITableViewCellSelectionStyleNone ;
}
if (section == 0) {
switch (indexPath.row) {
case 0:{
cell.lable.text = #"Date of Birth";
cell.field.placeholder = #"Birth Name";
break;
}
case 1:{
cell.lable.text = #"Enter Your Name";
cell.field.placeholder = #"Full Name";
break;
}
default:
break;
}
}
[UIView beginAnimations:#"ShiftUp" context:nil];
[UIView setAnimationDuration:0.0001];
// [UIView beginAnimations: #"ShiftUp" context:nil];
NSLog(#"Load cellfor raw at index ");
// Configure the cell.
return cell;
}
Note : UIView animation will not allow text field to move away data or any UIcontroller will remain same in its old state !!
Don't Commit animation otherwise it will not working !!
What you can do is this: in the Editing Changed event of each of the TextField store the value contain in the text field in an NSMutableArray whose number equal the number of cells. i.e.
-(IBAction) EditingChanged: (id) sender
{
UITextField *txt =(UITextField*)sender;
NSString* str =[[NSString alloc] initWithString: txt.text];
//get current text string
NSInteger path =[tableView indexPathForSelectedRow].row;
// get currently selected row, this could be a bit different depending on the number of sections
[yourMutableArray insertObject: str atIndex: path];
[str release]
}
You can then populate the TextField with the values from the NSMutableArray anytime the cells are recreated i.e.
(UITableViewCell *) tableView: (UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*) indexPath
{
...... // create the cells here and use viewTag to get the textFields
textField.text= [yourMutableArray objectAtIndex:indexPath.row];
//This may be a bit different depending on the number of sections.
}
Also, note that it might be advisable to initialize yourMutable array to the capacity of the number of cells.
I am sorry if the codes are not well formatted as this is my first post on stackoverflow - also there might be some typos in the code. Hope this helps someone.
every time we allocate the cell to different data,the data will not reloading the cell,every time the data override previous data, before allocate the cell to clear cell,
like as cell=nil
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell=nil;
//it clear data in the cell
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 400, 30)] ;
textField.enabled = NO;
cell.accessoryView = textField;
[textField release];
}
You're right, the problem is the cells will be reused. There are two solutions to the problem, the quick and dirty one would be to not use reusable cells:
Remove this:
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
And just leave this:
UITableViewCell * cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 400, 30)] ;
textField.enabled = NO;
cell.accessoryView = textField;
[textField release];
That should be ok, if you have only a small number of cells in your tableview (about fewer than 50).
The better solution would be to leave cell reuse on, and fill their textfields as they are requested. The approach differs from app to app, but you basically never should access the cells directly, and store the data of the cell somewhere else, e.g. an NSArray of NSStrings. You could then manipulate the NSArray. Your cellForRowAtIndexPath method would look something like this:
textField.text = [arrData objectAtIndex:indexPath.row];
I'm not seeing the text for my UITableView show up.. in fact the TableView doesn't appear to be on the screen at all because I cannot select the empty rows.
Strangely, my log in cellForRowAtIndexPath shows up ok with the expected data - I just don't see any on the screen.
-(void)bindFriendsToTable:(NSArray *)friends{
NSLog(#"friends : %#",friends);
[sections removeAllObjects];
[sectionRows removeAllObjects];
[sections addObject:#"Friends"];
[sectionRows setObject:friends forKey:#"Friends"];
[self.tableView reloadData];
HideActivityIndicator();
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *cellsection = [sections objectAtIndex:indexPath.section];
NSArray *rowsInSection = [sectionRows valueForKey:cellsection];
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
cell.textLabel.font = [UIFont fontWithName:#"Helvetica" size:14];
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
cell.textLabel.text = [rowsInSection objectAtIndex:indexPath.row];
NSLog(#"%#",cell.textLabel.text);
return cell;
}
I'm inheriting from a base class which is a UITableViewController, as I have for a dozen other screens in the project. Any idea why I'm not seeing the tableView?
Is your font colour the same as your background colour? If you set the accessoryType to a checkmark does it display?
cell.accessoryType = UITableViewCellAccessoryCheckmark;
Do you have any header sections? If so make sure you return a value for heightForHeaderInSection:
-(float)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
return 66;
}
i think u should remove
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
and then try it.
and display the other static string in the cell to check the problem.