i have a little social network and i tried to implement the ratings code into the table view, it judges ratings with stars... the problem is that the second section displays ratings from the first table section
picture:
so you can see it displays ratings in some of the tableview cells, just the last couple, why would it be doing this?
drawing code:
-(void)drawRect:(CGRect)rect
{
if(_shouldDrawRating)
{
self.desc_image.layer.cornerRadius = 8;
self.desc_image.clipsToBounds = YES;
_rating = [[UIStarRateView alloc]initWithFrame:CGRectMake(220,35,70,15)];
[_rating setMaxStars:5];
[_rating setFullImage:[UIImage imageNamed:#"StarFull.png"]];
[_rating setHalfImage:[UIImage imageNamed:#"StarHalf.png"]];
[_rating setEmptyImage:[UIImage imageNamed:#"StarEmpty.png"]];
[_rating setRate:_postRating];
[self addSubview:_rating];
}
}
cell rendering code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
Regular_Cell *cell;
// Configure the cell...
if(indexPath.section == 0)
{
if(indexPath.row < NUMBER_OF_DYNAMIC_ROWS_RECENT)
{
cell = [tableView dequeueReusableCellWithIdentifier:#"default"];
if(cell == nil)
{
cell = [[Regular_Cell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"default"];
}
NSDictionary *dict = self.recentArray[indexPath.row];
[cell setShouldDrawRating:YES];
[cell.title_label setText:dict[#"title"]];;
[cell.author_label setText:[NSString stringWithFormat:#"Author: %#",dict[#"author"]]];
[cell.views_label setText:[NSString stringWithFormat:#"Views: %#",dict[#"views"]]];
[cell setPoll_idFromString:[NSString stringWithFormat:#"%#",dict[#"id"]]];
//options for image view
cell.desc_image.contentMode = UIViewContentModeScaleAspectFill;
NSURL *imageURL = [NSURL URLWithString:[NSString stringWithFormat:#"%#",dict[#"imageURL"]]];
[cell.desc_image setImageURL:imageURL];
[cell setPostRating:indexPath.row+0.5];
}
else if(indexPath.row == NUMBER_OF_DYNAMIC_ROWS_RECENT)
{
cell = [tableView dequeueReusableCellWithIdentifier:#"See More"];
if(cell == nil)
{
cell = [[Regular_Cell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"See More"];
}
}
else
{
cell = nil;
}
NSLog(#"%#",indexPath);
}
if(indexPath.section == 1)
{
if(indexPath.row < NUMBER_OF_DYNAMIC_ROWS_TOP)
{
cell = [tableView dequeueReusableCellWithIdentifier:#"default"];
if(cell == nil)
{
cell = [[Regular_Cell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"default"];
}
NSDictionary *dict = self.topViewedArray[indexPath.row];
[cell.title_label setText:dict[#"title"]];
[cell.author_label setText:[NSString stringWithFormat:#"Author: %#",dict[#"author"]]];
[cell.views_label setText:[NSString stringWithFormat:#"Views: %#",dict[#"views"]]];
[cell setPoll_idFromString:[NSString stringWithFormat:#"%#",dict[#"id"]]];
//options for image view
cell.desc_image.contentMode = UIViewContentModeScaleAspectFill;
NSURL *imageURL = [NSURL URLWithString:[NSString stringWithFormat:#"%#",dict[#"imageURL"]]];
[cell.desc_image setImageURL:imageURL];
}
else if(indexPath.row == NUMBER_OF_DYNAMIC_ROWS_TOP)
{
cell = [tableView dequeueReusableCellWithIdentifier:#"See More"];
if(cell == nil)
{
cell = [[Regular_Cell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"See More"];
}
}
else
{
cell = nil;
}
NSLog(#"%#",indexPath);
}
return cell;
}
In section 1 you have to set the boolean to NO,It doesnt have a proper value now in section 1.I think you miss this line.
[cell setShouldDrawRating:NO];
Not only in Section 1 where ever you create the cell it must be implemented,Otherwise can cause problem of inconsistency in drawing
Replace code for setting cell labels, images etc from tableView:cellForRowAtIndexPath: and paste it in tableView:willDisplayCell:forRowAtIndexPath:. And setShouldDrawRating: in each section, not only in section number 0.
Related
I add a "Load More" cell in the tableview through check if the current cell is the last one.
but i have got 2 kinds of data to display,so i used a UISegmentedControl to switch.
once at the first tab of UISegmentedControl,the "Load More" cell appears at the last cell.but when i switch to second tab of the UISegmentedControl.The "Load More" cell still stays there...and there is still a "Load More" cell at the last of tableview.so there are 2 "Load More" cell shows.
i want to remove the first "Load More" cell,but i dont know how.Much THX.
EDIT:
static NSString * ID = #"TopicCustomCellIdentifier";
[tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:ID];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
if(IS_LAST_TOPIC_ROW){
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
if(cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
}
cell.textLabel.text = #"Load More";
cell.textLabel.font = [UIFont systemFontOfSize:14];
cell.textLabel.textAlignment = NSTextAlignmentCenter;
cell.imageView.image = nil;
return cell;
}
MTopicItem *topic;
cell.textLabel.textAlignment = NSTextAlignmentLeft;
if(SEGMENTINDEX == 0){
topic = [_my_topics_data_array objectAtIndex:indexPath.row];
}else{
topic = [_rec_topics_data_array objectAtIndex:indexPath.row];
}
[cell.textLabel setText:topic.name];
[cell.textLabel setFont:[UIFont systemFontOfSize:18]];
if(IS_RETINA){
[cell.imageView setImageWithURL:[NSURL URLWithString: topic.image]
placeholderImage:[UIImage imageNamed:#"default50"]];
}else{
[cell.imageView setImageWithURL:[NSURL URLWithString: topic.sImage]
placeholderImage:[UIImage imageNamed:#"default"]];
}
topic = nil;
return cell;
#define IS_LAST_TOPIC_ROW ((indexPath.row == [_my_topics_data_array count] - 1) && [_my_topics_data_array count] != 0) || ((indexPath.row == [_rec_topics_data_array count] - 1) && [_rec_topics_data_array count] != 0)
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if(SEGMENTINDEX == 0){
return [_my_topics_data_array count];
}else{
return [_rec_topics_data_array count];
}
}
Use the reloadData to refresh the view on segment touch.
[myTableView reloadData];
If you add a row manually, you can delete that manually too:
deleteRowsAtIndexPaths:withRowAnimation:
See here:
Check the last cell text label is load more don't add in second control.
This is happening due to the reusing of cell. When you deque a cell from the tableview check if it is not nil and reset content.
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
if(cell) {
cell.textLabel.text=#"";
cell.imageView.image=nil;
}
Also cross check if IS_LAST_TOPIC_ROW is identifying the last row correctly.
Hope that helps.
keep a boolean to make sure when to show the cell or not.
Check it before you add the loadmore cell in cellForRowAtIndexpath
method .
Also the numberOfRowsInSection should be maintained with the same
bool.
When you click the loadmore cell set boolean to no and then reload table
How it looks
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(showLoadMore)
{
if(IS_LAST_TOPIC_ROW){
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
if(cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
}
cell.textLabel.text = #"Load More";
cell.textLabel.font = [UIFont systemFontOfSize:14];
cell.textLabel.textAlignment = NSTextAlignmentCenter;
cell.imageView.image = nil;
return cell;
}
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if(showLoadMore{
return [_my_topics_data_array count]+1;
}
else
{
return [_my_topics_data_array count];
}
}
just now,i suddenly got the answer.
I write 2 CONSTANT:
#define IS_LAST_MY_TOPIC_ROW (indexPath.row == [_my_topics_data_array count] - 1) && [_my_topics_data_array count] != 0
#define IS_LAST_REC_TOPIC_ROW (indexPath.row == [_rec_topics_data_array count] - 1) && [_rec_topics_data_array count] != 0
and in - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
if(SEGMENTINDEX == 0){
if(IS_LAST_MY_TOPIC_ROW){
cell.textLabel.text = #"Load More";
cell.textLabel.font = [UIFont systemFontOfSize:14];
cell.textLabel.textAlignment = NSTextAlignmentCenter;
cell.imageView.image = nil;
return cell;
}
topic = [_my_topics_data_array objectAtIndex:indexPath.row];
}else{
if(IS_LAST_REC_TOPIC_ROW){
cell.textLabel.text = #"加载更多";
cell.textLabel.font = [UIFont systemFontOfSize:14];
cell.textLabel.textAlignment = NSTextAlignmentCenter;
cell.imageView.image = nil;
return cell;
}
topic = [_rec_topics_data_array objectAtIndex:indexPath.row];
}
I have one tableview with 1 section and two rows,
and down I have one button action.
In the button action I have to check which cell is clicked because according to that cell I have to open email view for sending mail.
I created for two bool values, but It is not working properly, still my emailview get call without cell is selected
this code what i am doing
#implementation View
#synthesize Mytableview,selectedIndexPaths,value1,value2,cellselected;
BOOL values[1];
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [Mytableview dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];
}
if ([indexPath row] == 0 && [indexPath section] == 0)
{
cell.textLabel.text= #"test";
if (values[indexPath.row]) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
value1=TRUE;
}
else if ([indexPath row] == 1 && [indexPath section] == 0)
{
cell.textLabel.text= #"test";
value2=TRUE;
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//[Mytableview deselectRowAtIndexPath:indexPath animated:YES];
//self.cellselected = indexPath.row;
UITableViewCell *cell = [Mytableview cellForRowAtIndexPath:indexPath];
//here values is i give as array on top as BOOL values[1];i give size for it
values[indexPath.row] = !values[indexPath.row];
if (values[indexPath.row]) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
}
-(IBAction)ExportEmail
{
if (value1==FALSE) {
return;
}
else {
Class mailClass = (NSClassFromString(#"MFMailComposeViewController"));
if (mailClass != nil)
{
// We must always check whether the current device is configured for sending emails
if ([mailClass canSendMail])
{
[self displayComposerSheet];
}
}
}
}
Declare class veriable NSIndexPath;
NSIndexPath *myIndexPath;
Modify your didSelectRowAtIndexPath to below
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [Mytableview cellForRowAtIndexPath:indexPath];
//here values is i give as array on top as BOOL values[1];i give size for it
myIndexPath = indexPath;
if (values[indexPath.row]) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
}
You can use that NSIndexPath in you Button's IBAction and according to index you can open up email.
-(IBAction)ExportEmail
{
if(myIndexPath.row==0){
// send mail
}else if(myIndexPath.row==1){
// send mail
}
}
I am having real troubles adding a UIImageView to a single UITableView cell. In my Storyboard I have a UITableViewController and four prototype dynamic cells. Three of them are just fine as normal left detail cells and they work fine. However one of them I need to have a UIImageView in.
So I have added said view to the cell, given the cell a custom class with a property so I can access the image view.
I have the following cells:
Title cell.
Image Cell.
URL Cell.
Notes Cell.
The contents of the table view change depending on whether the user wants to add a URL, note or image. So the user always sees the title cell with one of the others.
Here is my code and for whatever reason I just can't get the UIImageView to display on that image cell.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
//0 = Image
if ([[NSUserDefaults standardUserDefaults] integerForKey:#"NewScrapbookEntry"] == 0)
{
if (indexPath.row == 0) CellIdentifier = #"titleCell";
if (indexPath.row == 1) CellIdentifier = #"imageCell";
if (indexPath.row == 2) CellIdentifier = #"notesCell";
}
//1 = URL
else if ([[NSUserDefaults standardUserDefaults] integerForKey:#"NewScrapbookEntry"] == 1)
{
if (indexPath.row == 0) CellIdentifier = #"titleCell";
if (indexPath.row == 1) CellIdentifier = #"urlCell";
if (indexPath.row == 2) CellIdentifier = #"notesCell";
}
//2 = Notes
else if ([[NSUserDefaults standardUserDefaults] integerForKey:#"NewScrapbookEntry"] == 2)
{
if (indexPath.row == 0) CellIdentifier = #"titleCell";
if (indexPath.row == 1) CellIdentifier = #"notesCell";
}
ScrapbookImageDetailCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[ScrapbookImageDetailCell alloc] initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:CellIdentifier];
cell.editingAccessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
[cell setBackgroundColor:[UIColor colorWithRed:250.0f/255.0f green:250.0f/255.0f blue:250.0f/255.0f alpha:1.0f]];
[cell setSelectionStyle:UITableViewCellSelectionStyleGray];
cell.textLabel.adjustsFontSizeToFitWidth = YES;
cell.textLabel.text = [firstSection objectAtIndex:indexPath.row];
cell.detailTextLabel.font = [UIFont fontWithName:#"HelveticaNeue" size:13.0f];
cell.detailTextLabel.numberOfLines = 0;
cell.accessoryView = nil;
switch (indexPath.section)
{
case 0:
switch (indexPath.row)
{
case 0:
{
cell.detailTextLabel.text = scrapbook.title;
}
break;
case 1:
{
//0 = Image
if ([[NSUserDefaults standardUserDefaults] integerForKey:#"NewScrapbookEntry"] == 0)
{
cell.detailTextLabel.text = nil;
cell.iv.image = [UIImage imageNamed:#"image.png"];
}
//1 = URL
else if ([[NSUserDefaults standardUserDefaults] integerForKey:#"NewScrapbookEntry"] == 1)
{
cell.detailTextLabel.text = scrapbook.url;
}
//2 = Notes
else if ([[NSUserDefaults standardUserDefaults] integerForKey:#"NewScrapbookEntry"] == 2)
{
cell.detailTextLabel.text = scrapbook.notes;
}
}
break;
case 2:
{
cell.detailTextLabel.text = scrapbook.notes;
}
break;
default:
break;
}
break;
default:
break;
}
return cell;
}
Why are you changing the identifier value? The thing you just have to do is make custom cell, and in height for row, check if it's your desired row, and return with height of image else default size, and in cell for row method, again check desired row and add the image you want to add else make the imageview nil.
I am creating my cells from an array. The last object in my area gets created differently, as I want to add a new UILabel to the contentView of the cell. (So that it shows a total number of records in a UILabel in the last cell).
For some reason, my last cell that adds the UILabel to the contentView keeps getting duplicated. It will show up on other cells, screw up their display, etc. I have a feeling this has to do with cell reuse, but I am not sure how to fix it.
Here is my method:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *kCellID = #"cellID";
// Bounds
CGRect bounds = [[UIScreen mainScreen] bounds];
Person *person = nil;
if (tableView == self.searchDisplayController.searchResultsTableView) {
person = [people objectAtIndex:indexPath.row];
}
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellID];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:kCellID] autorelease];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
// Check if it is the first cell
if (person == [people lastObject]) {
cell.accessoryType = UITableViewCellAccessoryNone;
cell.userInteractionEnabled = NO;
UILabel *count = [[UILabel alloc] initWithFrame:CGRectMake(-4, 11, bounds.size.width - 10, 20)];
count.autoresizingMask = UIViewAutoresizingFlexibleWidth;
count.textColor = [UIColor darkGrayColor];
count.font = [UIFont systemFontOfSize:16];
count.textAlignment = UITextAlignmentCenter;
count.text = person.nameFirst;
cell.textLabel.text = nil;
cell.detailTextLabel.text = nil;
[cell.contentView addSubview:count];
return cell;
}
}//end
cell.textLabel.text = [NSString stringWithFormat:#"%#, %#", person.nameLast, person.nameFirst];
// Check if they are faculty staff
if ([person.status isEqualToString:#"Staff/Faculty"]) {
cell.detailTextLabel.text = [NSString stringWithFormat:#"%#: %#", person.status, person.department];
} else {
cell.detailTextLabel.text = person.status;
}//end
return cell;
}
Can someone help me understand how I can get this working correctly so that my UILabel doesn't get created on different cells?
I have adjusted your method below. Basically, you need to dequeue cells and perform any cell wide settings (disclosure, etc.) when you create the cell. Any individual cell changes should be done after the cell has been dequeued.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *kCellID = #"cellID";
static NSString *lastCellID = #"lastcellID";
// Bounds
CGRect bounds = [[UIScreen mainScreen] bounds];
Person *person = nil;
if (tableView == self.searchDisplayController.searchResultsTableView) {
person = [people objectAtIndex:indexPath.row];
}
UITableViewCell *cell;
if (person != [people lastObject]) {
cell = [tableView dequeueReusableCellWithIdentifier:kCellID];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:kCellID] autorelease];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
cell.textLabel.text = [NSString stringWithFormat:#"%#, %#", person.nameLast, person.nameFirst];
// Check if they are faculty staff
if ([person.status isEqualToString:#"Staff/Faculty"]) {
cell.detailTextLabel.text = [NSString stringWithFormat:#"%#: %#", person.status, person.department];
} else {
cell.detailTextLabel.text = person.status;
}//end
} else {
cell = [tableView dequeueReusableCellWithIdentifier:lastCellID];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:lastCellID] autorelease];
cell.accessoryType = UITableViewCellAccessoryNone;
cell.userInteractionEnabled = NO;
UILabel *count = [[UILabel alloc] initWithFrame:CGRectMake(-4, 11, bounds.size.width - 10, 20)];
count.autoresizingMask = UIViewAutoresizingFlexibleWidth;
count.textColor = [UIColor darkGrayColor];
count.font = [UIFont systemFontOfSize:16];
count.textAlignment = UITextAlignmentCenter;
count.tag = 1;
[cell.contentView addSubview:count];
}
UILabel *count = (UILabel *)[cell viewWithTag:1];
count.text = person.nameFirst;
//cell.textLabel.text = nil;
//cell.detailTextLabel.text = nil;
}//end
return cell;
}
It's probably because the cell will be reused. Use a different reuse identifier for the last cell, say, kLastCellID.
UITableViewCell *cell = nil;
// Check if it is the first cell
if (person == [people lastObject]) {
cell = [tableView dequeueReusableCellWithIdentifier:kLastCellID];
if (!cell) {
//create a last cell, with an UILabel in your content view
}
//update the cell's content
} else {
cell = [tableView dequeueReusableCellWithIdentifier:kCellID];
if (!cell) {
//create a regular cell
}
//update the cell's content
}
I have a viewcontroller with a nib - which has a tableview, searchbar and searchdisplaycontroller inside.
The searchdisplaycontroller's contentscontroller, results delegate, delegate and results datasource is wired to the viewcontroller in IB. The searchbar's delegate is wired to the view controller in IB. The main tableview is also wired to the viewcontroller and its loading items during runtime properly.
Everything seems to work except the resultstableview - it never gets populated and the tableView:cellForRowAtIndexPath: never gets called AFTER the user types into the searchbar - it only gets called to populate the main tableview.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CellIdentifier";
// Dequeue or create a cell o f the appropriate type.
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
if (tableView.tag == 2)
{
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
// Configure the cell.
NSHotel *selectedHotel = [[self hotelList] objectAtIndex:[indexPath row]];
//Store the hotel id for use later
selectedHotel.id = [indexPath row];
//cell.textLabel.text = [NSString stringWithFormat:#"Catalonia Majorica", indexPath.row];
cell.textLabel.text = [selectedHotel name];
}
else if (tableView.tag == 1)
{
cell.accessoryType = UITableViewCellAccessoryNone;
// Configure the cell...
NSAirport *selectedAirport = nil;
if (tableView == self.searchDisplayController.searchResultsTableView)
{
selectedAirport = [self.filteredListContent objectAtIndex:indexPath.row];
}
else
{
selectedAirport = [self.listContent objectAtIndex:indexPath.row];
}
//Set the label of the cell formatting the distance from the device
cell.textLabel.text = [NSString stringWithFormat:#"%# - %# miles",
selectedAirport.name, [self formattedStringWithDecimal:selectedAirport.milesFromDevice]];
//Adjust the front of the label
cell.textLabel.font = [UIFont boldSystemFontOfSize:12];
}
return cell;
}
Fixed it - it was returning 0 here:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (tableView == self.searchDisplayController.searchResultsTableView)
{
return [self.filteredListContent count];
}
else if (tableView.tag == 1)
{
return [self.listContent count];
}
else if (tableView.tag == 2)
{
// Return the number of rows in the section.
return [[self hotelList] count];
}
NSLog(#"The rows in tableview!");
return 0;
}