Custom cell contents overlapping in UITableView - ios

I know this question is already asked many times, but my problem is some different.
I am creating a UIView and a UIImageView programmatically in cell's content view. When TableView appear first time it looking perfect, but when i scroll down and up , this seems overlapped.
Screenshot of without scroll:
Screenshot after scroll:
Code that i follow:
viewForHead = [[UIView alloc]initWithFrame:CGRectMake(cell.viewForContents.frame.origin.x, cell.viewForContents.frame.origin.y-10, cell.viewForContents.frame.size.width, 45)];
viewForHead.backgroundColor = [UIColor colorWithRed:232.0/255.0 green:255.0/255.0 blue:16.0/255.0 alpha:1];
[cell.contentView addSubview:viewForHead];
UIImageView *imageViewForDP = [[UIImageView alloc]initWithFrame:CGRectMake(viewForHead.frame.origin.x-50, viewForHead.frame.origin.y-8, 60,60 )];
imageViewForDP.image = [UIImage imageNamed:#"dog_1.png"];
//[cell.viewForContents addSubview:imageViewForDP];
imageViewForDP.layer.cornerRadius = 30;
imageViewForDP.clipsToBounds = YES;
[viewForHead addSubview:imageViewForDP];
Please get me out from this problem . Thanks

Use this into your - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
if ([cell.contentView subviews]){
for (UIView *subview in [cell.contentView subviews]) {
[subview removeFromSuperview];
}
}

You are adding your viewForHead as a subview each time the cell gets dequeued. So you're adding them on top of each other.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"CELL"];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"CELL"] autorelease];
// This is where you CREATE your cell contents.
viewForHead = [[UIView alloc]initWithFrame:CGRectMake(cell.viewForContents.frame.origin.x, cell.viewForContents.frame.origin.y-10, cell.viewForContents.frame.size.width, 45)];
viewForHead.backgroundColor = [UIColor colorWithRed:232.0/255.0 green:255.0/255.0 blue:16.0/255.0 alpha:1];
[cell.contentView addSubview:viewForHead];
UIImageView *imageViewForDP = [[UIImageView alloc]initWithFrame:CGRectMake(viewForHead.frame.origin.x-50, viewForHead.frame.origin.y-8, 60,60 )];
imageViewForDP.image = [UIImage imageNamed:#"dog_1.png"];
// [cell.viewForContents addSubview:imageViewForDP];
imageViewForDP.layer.cornerRadius = 30;
imageViewForDP.clipsToBounds = YES;
imageView.tag = 1
[viewForHead addSubview:imageViewForDP];
}
// this is where you UPDATE your viewForHead image and any other elements inside your cell
UIImageView *imageView = [cell.contentView viewWithTag:1];
imageView.image = // your new image
return cell;
}
Subclassing your UITableViewCell and building your layout with a xib would be even better, then you could just access the cells properties directly. A much cleaner solution.
MyCustomCell *cell = [tableView dequeueReusableCellWithIdentifier#"CELL"];
if (cell == nil) {
cell = [[MyCustomCell alloc] init]; // you ID is set in interface builder
}
cell.imageView.image = // your new image here.
cell.someLabel.text = #"some new text here"

This problem is because of table view cell gets reuse and you are adding a view again on cell.
Try below code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MyIdentifier"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"MyIdentifier"] ;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
UIView *viewForHead = (UIView *)[cell.contentView viewWithTag:1];
if (viewForHead==nil) {
viewForHead = [[UIView alloc]initWithFrame:CGRectMake(cell.frame.origin.x, cell.frame.origin.y, cell.frame.size.width, 20)];
viewForHead.backgroundColor = [UIColor colorWithRed:232.0/255.0 green:255.0/255.0 blue:16.0/255.0 alpha:0.5];
viewForHead.tag = 1;
[cell.contentView addSubview:viewForHead];
}
return cell;}

Related

UITableViewCell background color when highlighted/selected

I want my cell text color to change when tapped, but not the background color.
I want the cell background to always be white, and only the text color to change when selected.
I've seen a bunch of answers about how to do this...
UIView *bgColorView = [[UIView alloc] init];
bgColorView.backgroundColor = [UIColor whiteColor];
[cell setSelectedBackgroundView:bgColorView];
... but the view that gets created runs on top of the cell separator.
And to use cell.textLabel.highlightedTextColor = [UIColor brownColor]; to change the textColor, I can't have cell.selectionStyle = UITableViewCellSelectionStyleNone;, so I need to figure out something.
if you want to show the separator of cell , you may need this:
add this code :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
...
cell.selectionStyle = UITableViewCellSelectionStyleDefault;
cell.textLabel.highlightedTextColor = [UIColor brownColor];
UIView *backgroudView = [[UIView alloc]initWithFrame:CGRectMake(0, 1, tableView.bounds.size.width, [self tableView:tableView heightForRowAtIndexPath:indexPath] - 2)];
backgroudView.backgroundColor = [UIColor whiteColor];
UIView *placeholderView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1, 1)];
placeholderView.backgroundColor = [UIColor clearColor];
[placeholderView addSubview:backgroudView];
cell.selectedBackgroundView = placeholderView;
...
}
// These codes are used to show the separatorView when the cell didSelected
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
void (^showSeparatorView)(UITableViewCell *cell) = ^(UITableViewCell *cell){
for (id obj in cell.subviews) {
if([obj isKindOfClass:NSClassFromString(#"_UITableViewCellSeparatorView")]){
UIView *view = (UIView *)obj;
view.hidden = NO;
}
}
};
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
showSeparatorView(cell);
if (indexPath.row > 0)
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:indexPath.row - 1 inSection:indexPath.section]];
showSeparatorView(cell);
}
...
}
// These codes are used to show the separatorView when the cell didHightlight
- (void)tableView:(UITableView *)tableView didHighlightRowAtIndexPath:(NSIndexPath *)indexPath
{
void (^showSeparatorView)(UITableViewCell *cell) = ^(UITableViewCell *cell){
for (id obj in cell.subviews) {
if([obj isKindOfClass:NSClassFromString(#"_UITableViewCellSeparatorView")]){
UIView *view = (UIView *)obj;
view.hidden = NO;
}
}
};
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
showSeparatorView(cell);
if (indexPath.row > 0)
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:indexPath.row - 1 inSection:indexPath.section]];
showSeparatorView(cell);
}
}
Hope these can help to you!
Add this in cellForRowAtIndexPath method so when you tap in cell than change label text color
cell.textLabel.highlightedTextColor = [UIColor brownColor];
You can use this -
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *c = [tableView cellForRowAtIndexPath:indexPath];
[c.textLabel setTextColor:[UIColor brownColor]];
}
You can add the code cell.selectedBackgroundView = [UIView new]; to figure out this. With this method, you don't need cell.selectionStyle = UITableViewCellSelectionStyleNone;.

How to change cell text color with out hiding the separator?

In my my application I want to change the cell text color with out disappearing the cell separator.And I am using the following code
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = nil;
static NSString *identifier = #"cell";
cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
UIView * selectedBackgroundView = [[UIView alloc] initWithFrame:cell.frame];
[selectedBackgroundView setBackgroundColor:[UIColor clearColor]]; // set color here
[cell setSelectedBackgroundView:selectedBackgroundView];
cell.backgroundColor=[UIColor clearColor];
cell.textLabel.highlightedTextColor = [UIColor redColor];
[cell setOpaque:NO];
}
cell.textLabel.text=[contentArray objectAtIndex:indexPath.row];
return cell;
}
But when I clicked the cell the cell separator also is disappearing ? How to change the text color without hiding the separator ?
It seems the cell separators are a problem for a lot of people. So, I would say rather than doing what I suggested to disable the selection, it would be easier to set the cell separator to 'none' and manage the separator yourself in the background and selected background views:
- (void)viewDidLoad
{
[super viewDidLoad];
// ...
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = nil;
static NSString *identifier = #"cell";
cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
UIView *selectedBackgroundView = [[UIView alloc] initWithFrame:cell.frame];
[selectedBackgroundView setBackgroundColor:[UIColor clearColor]];
[cell setSelectedBackgroundView:selectedBackgroundView];
UIView *backgroundView = [[UIView alloc] initWithFrame:cell.frame];
[backgroundView setBackgroundColor:[UIColor clearColor]];
[cell setBackgroundView:backgroundView];
UIView *selectedBackgroundSeparator = [[UIView alloc] initWithFrame:CGRectMake(tableView.separatorInset.left, cell.frame.size.height - 1, cell.frame.size.width - tableView.separatorInset.left, 1)];
UIView *backgroundSeparator = [[UIView alloc] initWithFrame:selectedBackgroundSeparator.frame];
selectedBackgroundSeparator.backgroundColor = backgroundSeparator.backgroundColor = tableView.separatorColor;
[selectedBackgroundView addSubview:selectedBackgroundSeparator];
[backgroundView addSubview:backgroundSeparator];
cell.textLabel.highlightedTextColor = [UIColor redColor];
[cell setOpaque:NO];
}
cell.textLabel.text=[contentArray objectAtIndex:indexPath.row];
return cell;
}
Alternatively, you can use the default cell separator, and instead just add your own top and bottom separators to the selectedBackgroundView:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = nil;
static NSString *identifier = #"cell";
cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
UIView *selectedBackgroundView = [[UIView alloc] initWithFrame:cell.frame];
[selectedBackgroundView setBackgroundColor:[UIColor clearColor]];
[cell setSelectedBackgroundView:selectedBackgroundView];
UIView *topSelectedBackgroundSeparator = [[UIView alloc] initWithFrame:CGRectMake(tableView.separatorInset.left, 0, cell.frame.size.width - tableView.separatorInset.left, 1)];
UIView *selectedBackgroundSeparator = [[UIView alloc] initWithFrame:CGRectOffset(topSelectedBackgroundSeparator.frame, 0, cell.frame.size.height)];
topSelectedBackgroundSeparator.backgroundColor = selectedBackgroundSeparator.backgroundColor = tableView.separatorColor;
[selectedBackgroundView addSubview:selectedBackgroundSeparator];
[selectedBackgroundView addSubview:topSelectedBackgroundSeparator];
cell.textLabel.highlightedTextColor = [UIColor redColor];
[cell setOpaque:NO];
}
cell.textLabel.text=[contentArray objectAtIndex:indexPath.row];
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
for(id view in cell.containtView.subview) {
if([view isKindaOfClass:[UILabel class]])
UILabel* titleLabel = (UILabel*)view;
[titleLabel setTextColor:[UIColor whiteColor]]; // any you want
}
}
Rather than setting the cell's selectedBackgroundView to a clear view, would simply not allowing the cell to be highlighted when selected accomplish what you want? It will prevent the cell and separators from changing automatically based on the selection, but you will have to manage recognizing the tap gesture and highlighting the label text yourself.
Remove the selectedBackgroundView from your code.
You then need to implement tableView:shouldHighlightRowAtIndexPath: in your UITableViewDelegate:
- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath
{
return NO; // do what's appropriate based on the indexPath
}

How to Implement DataSheet

I want to implement data sheet to display history of user. I want to implement that design like this:
But I dont know how to do that...Can anyone please help me
Edit:
Add the horizontal line at the specific position and the label at the position and it will look like this.
Create a tableview and than in cellForRowAtIndexPath method add this code..
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *SimpleTableIdentifier;
UITableViewCell * cell;
SimpleTableIdentifier = #"SimpleTableIdentifier";
cell = [tableView dequeueReusableCellWithIdentifier: nil];
if(cell == nil) {
cell = [[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:SimpleTableIdentifier];
UILabel * numLbl = [[UILabel alloc] initWithFrame:CGRectMake(0,5,33,30)];
numLbl.text = #"1";
[numLbl setFont:[UIFont fontWithName:#"Helvetica" size:10.0]];
numLbl.backgroundColor = [UIColor clearColor];
[cell addSubview:numLbl];
UILabel * nameLbl = [[UILabel alloc] initWithFrame:CGRectMake(30,5,50,30)];
nameLbl.text = #"john%Lakeview";
[nameLbl setFont:[UIFont fontWithName:#"Helvetica" size:10.0]];
nameLbl.backgroundColor = [UIColor clearColor];
[cell addSubview:nameLbl];
//create a hoizontal separator in cell to display it like column
UIView* hSeparatorview1 = [[UIView alloc] initWithFrame:CGRectMake(25, 0, 1, 30)];
hSeparatorview1.backgroundColor = [UIColor blackColor];
hSeparatorview1.tag = 1;
[cell addSubview:hSeparatorview1];
UIView* hSeparatorview2 = [[UIView alloc] initWithFrame:CGRectMake(85, 0, 1, 30)];
hSeparatorview2.backgroundColor = [UIColor blackColor];
hSeparatorview2.tag = 2;
[cell addSubview:hSeparatorview2];
}
return cell;
}
//this method is used to set the hight of the tableview cell
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
{
return 30;
}
I have created it for only two label and two horizontal view but you can create as many as you like.
And yes dot forget to place this code in didSelectRowAtIndexPath otherwise horizontal view will disappear when user click the cell.
- (void)tableView:(UITableView *)atableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//get the cell which is selected
UITableViewCell *selectedCell = [atableView cellForRowAtIndexPath:indexPath];
//set cell horizontal saparator view color of selected cell bcoz when cell selected all view color is gone
UIView *hSeparatorview1=[selectedCell viewWithTag:1];
hSeparatorview1.backgroundColor = [UIColor blackColor];
UIView *hSeparatorview2=[selectedCell viewWithTag:2];
hSeparatorview2.backgroundColor = [UIColor blackColor];
}
Better to try with Custom tableview Cell for text,and UIViews for lines.I'm also done the same in my app.

UITableView dequeue not working as expected

As I scroll down the list, all the rows are there, but they keep adding more subviews the more they appear on the visible frame
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *reuse = #"RuleCell";
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:reuse];
if (cell == nil){
cell = [[UITableViewCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier:reuse];
}
NSUInteger row = indexPath.row;
[self createCell: cell onRow: row];
return cell;
}
- (void) createCell: (UITableViewCell*)cell onRow: (NSUInteger)row
{
UIImageView* bgImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"cell_background_spade_active.png"]];
cell.backgroundView = bgImage;
cell.textLabel.hidden = YES;
UILabel* titleLabel = [[UILabel alloc] initWithFrame: CGRectMake(100, CGRectGetHeight(cell.frame) / 2, 200, 50)];
titleLabel.text = [[self.ruleList objectAtIndex: row] objectForKey: TitleKey];
titleLabel.backgroundColor = [UIColor clearColor];
[cell.contentView addSubview: titleLabel];
}
I think you need to execute almost all of the logic that's in createCell: only within the if (cell == nil){ segment of your code. The part that should execute where you're currently calling createCell: is just getting a reference to the titleLabel and setting its text value.
To clarify, here's the kind of modification I'm suggesting (not tested, but should give the right idea):
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *reuse = #"RuleCell";
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:reuse];
if (cell == nil){
cell = [[UITableViewCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier:reuse];
[self setUpCell: cell];
}
NSUInteger row = indexPath.row;
UILabel *titleLabel = (UILabel *)[cell.contentView viewWithTag:42];
titleLabel.text = [[self.ruleList objectAtIndex: row] objectForKey: TitleKey];
return cell;
}
- (void) setUpCell: (UITableViewCell*)cell
{
UIImageView* bgImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"cell_background_spade_active.png"]];
cell.backgroundView = bgImage;
cell.textLabel.hidden = YES;
UILabel* titleLabel = [[UILabel alloc] initWithFrame: CGRectMake(100, CGRectGetHeight(cell.frame) / 2, 200, 50)];
titleLabel.tag = 42;
titleLabel.backgroundColor = [UIColor clearColor];
[cell.contentView addSubview: titleLabel];
}

iOS TableView Reuse would load a lot of subviews to cell

I used the following code to implement cell for every row at index path:
But the problem is when I scroll the tableView, the cell will load a lot of UIImageView *itemimageview in one cell in one line, I tried use
for (UIImageView *sView in cell.subviews) {
[sView removeFromSuperview];
}
but it would remove all subviews of one cell. How to solve this problem?...
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSUInteger row = [indexPath row];
NSUInteger oldRow = [lastIndexPath row];
static NSString *CheckMarkCellIdentifier = #"CheckMarkCellIdentifier";
//dequeueReusableCellWithIdentifier --
// Returns a reusable table-view cell object located by its identifier.
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CheckMarkCellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CheckMarkCellIdentifier] autorelease];
}
/*
for (UIImageView *sView in cell.subviews) {
[sView removeFromSuperview];
}
*/
UIImageView *itemimageview=[[UIImageView alloc]initWithFrame:CGRectMake(5, 5, 232, 54)];
itemimageview.image=[UIImage imageNamed:[tabsImageArray objectAtIndex:row]];
itemimageview.userInteractionEnabled = YES;
[cell.contentView addSubview:itemimageview];
[itemimageview release];
UIImageView *dictIcon=[[UIImageView alloc]initWithFrame:CGRectMake(30, 18, 30, 30)];
dictIcon.image=[UIImage imageNamed:#"dictionary_icon.png"];
dictIcon.userInteractionEnabled = YES;
[cell.contentView addSubview:dictIcon];
[dictIcon release];
UILabel *dictNameLabel = [[UILabel alloc] initWithFrame:CGRectMake(80, 23, 100, 21)];
dictNameLabel.text = dictName;
dictNameLabel.textColor = [UIColor whiteColor];
dictNameLabel.shadowColor = [UIColor blackColor];
dictNameLabel.backgroundColor = [UIColor clearColor];
dictNameLabel.userInteractionEnabled = YES;
[cell.contentView addSubview:dictNameLabel];
[dictNameLabel release];
//cell.textLabel.text = [tabsImageArray objectAtIndex:row];
cell.accessoryType = (row == oldRow && lastIndexPath != nil) ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;
return cell;
}
Consider running through and checking [view isKindOfClass:[UIImageView class]] to check whether the view is the right type of view to remove.
Also consider tagging the views with the UIView tag property, so you can add the subviews once, and then won't have to recreate them with reuse.
Here is how you would do this:
#define ImageViewOneTag 1001
#define ImageViewTwoTag 1002
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)path {
static NSString *CellID = #"CellID";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellID];
UIImageView *imageViewOne = nil;
UIImageView *imageViewTwo = nil;
if (cell) {
// You've caught a reusable cell. Fetch the image views by their tag.
imageViewOne = (UIImageView *)[cell viewWithTag:ImageViewOneTag];
imageViewTwo = (UIImageView *)[cell viewWithTag:ImageViewTwoTag];
} else {
// You haven't got a reusable cell. Make one, and make and add the image views to the contentView.
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellID];
imageViewOne = [[UIImageView alloc] initWithFrame:CGRectMake(0.0, 0.0, 20.0, 20.0)];
[imageViewOne setTag:ImageViewOneTag];
imageViewTwo = [[UIImageView alloc] initWithFrame:CGRectMake(0.0, 20.0, 20.0, 20.0)];
[imageViewTwo setTag:ImageViewTwoTag];
UIView *contentView = cell.contentView;
[contentView addSubview:imageViewOne];
[contentView addSubview:imageViewTwo];
}
// By this stage, you've either retrieved a reusable cell, or you've made a new one. Either way, imageViewOne and imageViewTwo now have a reference to the views you mean.
imageViewOne.image = *imageOneForRow*;
imageViewTwo.image = *imageTwoForRow*;
return cell;
}
I suggest you using custom table view cell, just create a cocoa touch class which inherits uitableviewcell.

Resources