I created a custom UITableViewCell with a UITextField, UILabels and UIButtons. When I enter a value to a UITextField and scroll down, it disappears and shows in another random cell. The same problem happens with my UIButton, when I press it, the state is changing but after I scroll down, it disappears.
Here is my cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"produktCell";
//NSString *CellIdentifier = [NSString stringWithFormat:#"produktCell %d",indexPath.row];
ProduktTableViewCell *cell =(ProduktTableViewCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSLog(#"wird neu erstellt");
cell = [[ProduktTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NSManagedObject *managedObject = [self.fetchedResultsController objectAtIndexPath:indexPath];
cell.produktnameLabel.text = [managedObject valueForKey:#"produktname"];
if ([[managedObject valueForKey:#"vondatum"] length] > 1){
cell.vonDatumLabel.text = [managedObject valueForKey:#"vondatum"];
cell.bisDatumLabel.text = [managedObject valueForKey:#"bisdatum"];
}else {
cell.vonDatumLabel.text = dateString;
cell.bisDatumLabel.text = dateString1;
}
cell.datumButton.tag = indexPath.row;
cell.warenkorbButton.tag = indexPath.row;
cell.menge.tag = indexPath.row + 437812;
cell.mengeLabel.text = [managedObject valueForKey:#"mengelabel"];
cell.produktnameLabel.tag = indexPath.row +22333;
cell.mengeLabel.tag =indexPath.row;
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
NSLocale *german = [[NSLocale alloc] initWithLocaleIdentifier:#"de_DE"];
[formatter setLocale:german];
[formatter setNumberStyle:NSNumberFormatterCurrencyStyle];
[formatter setMinimumFractionDigits:2];
[formatter setMaximumFractionDigits:2];
NSNumber *firstNumber = [managedObject valueForKey:#"preis"];
cell.preisLabel.text = [formatter stringFromNumber:firstNumber];
return cell;
}
EDIT: i fixed my problem with the textfield. i just delete the method:
/*- (void) scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
[[self.tableView superview] endEditing:YES];
}*/
but there is still a problem with my button.
My best guess, is that your cells that are being re-used, are receiving the same behavior of the cell that you just interacted with. You can try something quick to see what I mean. Comment this:
Edit:
ProduktTableViewCell *cell =(ProduktTableViewCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSLog(#"wird neu erstellt");
cell = [[ProduktTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
Put this instead:
ProduktTableViewCell *cell = [[ProduktTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
This way your new cells won't get the same "state" as the previous cell. What you need to do next, is to know which cell are you working on. Besides that you still need to reset the state of new cells. To finish, uncomment what I told you to comment (since you want your cells to be re-usable)
Related
I have a problem using a UITableView inside a UIViewController:
When I start the app the UITableView is shown, but the data from _opponents isn't shown.
When I start scrolling the first cell outside the UITableView, now this cell gets updated.
Also, when I trigger [_topponents reloaddata] manually, the whole UITableView shows the correct data.
What do I have to add or change, so that the data is shown from the beginning?
dataSource and delegate are both connected with the class in the storyboard
Here is my code:
viewDidLoad:
- (void)viewDidLoad {
[super viewDidLoad];
myappdel = (AppDelegate *)[UIApplication sharedApplication].delegate;
self.title = #"New Match";
_lopponent.text = _opponent;
opponents = [[NSMutableArray alloc] init];
NSMutableDictionary *opponent = [[NSMutableDictionary alloc] init];
[opponent setObject:#"opponent A" forKey:#"name"];
[opponent setObject:#"xx matches | xx wins || xx losts" forKey:#"stats"];
[opponent setObject:#"Krems" forKey:#"location"];
NSMutableDictionary *opponent2 = [[NSMutableDictionary alloc] init];
[opponent2 setObject:#"opponent B" forKey:#"name"];
[opponent2 setObject:#"yy matches | yy wins || yy losts" forKey:#"stats"];
[opponent2 setObject:#"Location B" forKey:#"location"];
NSMutableDictionary *opponent3 = [[NSMutableDictionary alloc] init];
[opponent3 setObject:#"opponent C" forKey:#"name"];
[opponent3 setObject:#"zz matches | zz wins || zz losts" forKey:#"stats"];
[opponent3 setObject:#"Location C" forKey:#"location"];
[opponents addObject:opponent];
[opponents addObject:opponent2];
[opponents addObject:opponent3];
[_topponents reloadData];
}
and here my cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"opponentcell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
UILabel *lopponentname = (UILabel*)[cell viewWithTag:1];
UILabel *lopponentstats = (UILabel*)[cell viewWithTag:2];
UILabel *llocation = (UILabel*)[cell viewWithTag:3];
lopponentname.text = [[opponents objectAtIndex:indexPath.row] objectForKey:#"name"];
lopponentstats.text = [[opponents objectAtIndex:indexPath.row] objectForKey:#"stats"];
llocation.text = [[opponents objectAtIndex:indexPath.row] objectForKey:#"location"];
return cell;
}
I found my fault!
I used to write:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]
but I should use
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
with "forIndexPath"
I think, the trouble is in the cell. Create UITableViewCell subclass.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"opponentcell";
CustomTableViewCell *cell = (CustomTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell.lopponentname.text = [[opponents objectAtIndex:indexPath.row] objectForKey:#"name"];
cell.lopponentstats.text = [[opponents objectAtIndex:indexPath.row] objectForKey:#"stats"];
cell.llocation.text = [[opponents objectAtIndex:indexPath.row] objectForKey:#"location"];
return cell;
}
Hope it helps you.
Add this after initialisation of cell. For me works properly.
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
I think you are using custom cel and it looks you have trouble in "cellForRowAtIndexPath". If you using .xib, you may find it useful.
static NSString *cellIdentifier = #"opponentcell";
CustomTableViewCell *cell = (CustomTableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
NSArray *nibObjects =[[NSBundle mainBundle] loadNibNamed:#"CustomTableViewCell" owner:nil options:nil];
for (id currentObject in nibObjects)
{
if ([currentObject isKindOfClass:[CustomTableViewCell class]])
{
cell = (CustomTableViewCell *) currentObject;
}
}
[cell initViewStyles];
}
You need to check for condition when cell is nil..
Initially the cell is nil..
So the data is loading only after scrolling...
Add below lines of code in your cellForRowAtIndexPath delegate method after initializing cell.
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
Hope this fixes the issue...
I need some help with the below. I would like p.no to align to the left of the cell and p.name to align to the right. Any advice?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateStyle:NSDateFormatterShortStyle];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
// Configure the cell...
President *p = (President *)[self.importedRows objectAtIndex:indexPath.row];
cell.textLabel.text = [NSString stringWithFormat:#"%# - %#", p.no , p.name];
return cell;
}
Follow These Steps:
1. drag & drop 2 labels on your prototypeCell in storyboard at the positions you want them to be in.
2. Create a subclass of UITableViewCell class in your project.
3. Assign newly created subClass as class for your table cell from identity inspector.
4. connect both label outlets with customTableviewcell.h
5. Import customTableViewCell.h in tableViewController.
6. Now in (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath method, replace code like this
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateStyle:NSDateFormatterShortStyle];
customTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
// Configure the cell...
President *p = (President *)[self.importedRows objectAtIndex:indexPath.row];
cell.label1.text = [NSString stringWithFormat:#"%# , p.no ];
cell.label2.text = [NSString stringWithFormat:#"%# , p.name ];
return cell;
}
Let me know if any issues are there :)
i am new in iphone devlpmnt.i just want to add current date in the cell. i need "notiftext" appear left of the cell and current date on the right.thanks in advance
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
AppDelegate *AppD = (AppDelegate *)[[UIApplication sharedApplication]delegate];
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil) {
cell = [[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier]autorelease];
}
MLNotifMessage *list = [AppD.storage objectAtIndex:indexPath.row];
cell.textLabel.text = list.notifText;
NSString *dteStr = [[NSString alloc]init];
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setTimeZone:[NSTimeZone timeZoneWithName:#"Europe/London"]];
[dateFormat setDateFormat:#"dd/MM/yyyy HH:mm:ss"];
dteStr = [dateFormat stringFromDate:list.date];
[dateFormat release];
cell.detailTextLabel.text = dteStr;
return cell;
}
Use any other style of the cell or use custom cell to fully customize the cell. I think for your question tabel view stye UITableViewCellStyleValue1 is enough.
cell = [[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier]autorelease];
cell.textLabel.text = list.notifText;
cell.detailTextLabel.text = [NSDate date];
use Custom TableViewCell. You can make custom tableViewCell by subclassing it
I want to display in UITableView array like:
(
1,
{
date = 1351876762;
ncom = 0;
nid = 11739814;
"read_ncom" = 0;
text = "<div class=\"wikiText\"><!--4-->New note text </div>";
title = lol;
uid = 3795852;
}
)
Cells should have a label with "title" from this array.
How can I make that?
P.S.:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
NSString *textCell = [[array objectAtIndex:indexPath.row] objectForKey:#"title"];
cell.textLabel.text = textCell;
return cell;
}
returns signal SIGABRT.
Thanks.
[EDIT]
Your array seems to be weird. Try following and let me know the result.
NSString *textCell = [[array objectAtIndex:1] objectForKey:#"title"];
You should have cell with identifier "Cell" in your table (if you have storyboard) or create this cell manually
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = [[array objectAtIndex:1] objectforkey:#"title"];
try the above code
Replace this :
NSString *textCell = [[[array objectAtIndex:indexPath.row] objectForKey:#"1"]objectForKey:#"title"];
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
[cell setBackgroundColor:[UIColor lightGrayColor]];
cell.textLabel.textColor = [UIColor lightTextColor];
cell.textLabel.backgroundColor = nil;
cell.detailTextLabel.textColor = [UIColor darkGrayColor];
cell.detailTextLabel.backgroundColor = nil;
// Get list of local notifications
NSArray *notificationArray = [[UIApplication sharedApplication] scheduledLocalNotifications];
UILocalNotification *notif = [notificationArray objectAtIndex:indexPath.row];
// Display notification info
[cell.textLabel setText:notif.alertBody];
NSDateFormatter *format = [[NSDateFormatter alloc] init];
[format setDateFormat:#"MMM dd 'at' HH:mm"];
NSString *dateString = [format stringFromDate:notif.fireDate];
NSString *textData = [[NSString alloc]initWithFormat:#"%#",dateString];
[cell.detailTextLabel setText:textData];
//[notif.fireDate description]
[self.tableView reloadData];
return cell;
}
Everything goes absoloutely normal if i DONT write "[self.tableView reloadData];", but if I do, seems like the cell is there but its not being displayed (the cell separator disappear according to the number of cells the tableview has)
I need to reloadData so the user won't need to get out of the view and load the view again to display updated information.
Any suggestion?
You dont need to add [self.tableView reloadData]; inside cellForRowAtIndexPath, this is absolutely wrong, since calling reloadData will again call cellForRowAtIndexPath which as you experienced will create very weird issues
In general you normally call [self.tableView reloadData]; whenever you want to change all or some of the contents of the UITableView
Create a function to check if new data is available (maybe implement a refresh button/pull to refresh). If new data is available call [self.tableView reloadData];.