UITableViewCell subviews added to wrong cells when scrolled - uiview

I have a subclass of UITableViewCell, and I am having problems with scrolling. All of the subviews are added to the cell in the storyboard, except for one UIView. I want to add this UIView as a subview of the cell based on a condition. The problem is that when the cells are scrolled off and onto the screen, the UIView is added to the cell a second time, or to the wrong cell. Here is my code, can you tell me what I am doing wrong?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
WavesFeedCell *cell = (WavesFeedCell *)[tableView dequeueReusableCellWithIdentifier:WavesFeedCellIdentifier forIndexPath:indexPath];
cell.cellWaveObject = [self.wavesArray objectAtIndex:indexPath.row];
//set the frames and text for the labels
cell.timeStampLabel.text = #"14m";
cell.waveTextLabel.text = cell.cellWaveObject.waveString;
cell.wavedByLabel.text = [NSString stringWithFormat:#"Waved by %#", cell.cellWaveObject.wavedByString];
//round the corners of the image view
[self setCornerRadiusForImageView:cell.profilePictureImageView];
//does the wave object have any agrees?
if (cell.cellWaveObject.numberOfAgrees > 0)
{
UIView *agreedView = [[UIView alloc] init];
UILabel *numberOfAgreesLabel = [[UILabel alloc] init];
numberOfAgreesLabel.font = [UIFont boldSystemFontOfSize:13.0f];
numberOfAgreesLabel.textColor = [UIColor whiteColor];
if (cell.cellWaveObject.numberOfAgrees > 1)
{
numberOfAgreesLabel.text = [NSString stringWithFormat:#"+%i Agree", cell.cellWaveObject.numberOfAgrees];
}
else
{
numberOfAgreesLabel.text = [NSString stringWithFormat:#"+%i Agrees", cell.cellWaveObject.numberOfAgrees];
}
UIImageView *backgroundImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:AgreedViewImage]];
//get the width of the string
CGSize constraintSize = CGSizeMake(242.0f, 16.0f);
CGSize stringSize = [numberOfAgreesLabel.text sizeWithFont:numberOfAgreesLabel.font constrainedToSize:constraintSize];
CGFloat agreedViewWidth = stringSize.width + 10.0f;
//adjust the frame and add it to the cell
agreedView.frame = CGRectMake(310.0f - agreedViewWidth, cell.wavedByLabel.frame.origin.y, agreedViewWidth, 14.0f);
backgroundImageView.frame = CGRectMake(5.0f, 0.0f, agreedView.frame.size.width, agreedView.frame.size.height);
numberOfAgreesLabel.frame = CGRectMake(5.0f, 0.0f, agreedView.frame.size.width, agreedView.frame.size.height);
[agreedView addSubview:backgroundImageView];
[agreedView addSubview:numberOfAgreesLabel];
[cell.contentView addSubview:agreedView];
return cell;
}
else
{
return cell;
}
}

May be added subview is not removing from cell.Content View .
Try using following code within cellForRow method
UIView *agreedView=(UIView*)[cell.contentView viewWithTag:21];
//does the wave object have any agrees?
if (cell.cellWaveObject.numberOfAgrees > 0)
{
if (!agreedView) {
agreedView=[[UIView alloc] init];
agreedView.tag=21;
UILabel *numberOfAgreesLabel = [[UILabel alloc] init];
numberOfAgreesLabel.font = [UIFont boldSystemFontOfSize:13.0f];
numberOfAgreesLabel.textColor = [UIColor whiteColor];
numberOfAgreesLabel.tag=22;
UIImageView *backgroundImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:AgreedViewImage]];
backgroundImageView.tag=23;
[agreedView addSubview:backgroundImageView];
[agreedView addSubview:numberOfAgreesLabel];
[cell.contentView addSubview:agreedView];
}
numberOfAgreesLabel=(UILabel*)[agreedView viewWithTag:22];
backgroundImageView=(UIImageView*)[agreedView viewWithTag:23];
if (cell.cellWaveObject.numberOfAgrees > 1)
{
numberOfAgreesLabel.text = [NSString stringWithFormat:#"+%i Agree", cell.cellWaveObject.numberOfAgrees];
}
else
{
numberOfAgreesLabel.text = [NSString stringWithFormat:#"+%i Agrees", cell.cellWaveObject.numberOfAgrees];
}
//get the width of the string
CGSize constraintSize = CGSizeMake(242.0f, 16.0f);
CGSize stringSize = [numberOfAgreesLabel.text sizeWithFont:numberOfAgreesLabel.font constrainedToSize:constraintSize];
CGFloat agreedViewWidth = stringSize.width + 10.0f;
//adjust the frame and add it to the cell
agreedView.frame = CGRectMake(310.0f - agreedViewWidth, cell.wavedByLabel.frame.origin.y, agreedViewWidth, 14.0f);
backgroundImageView.frame = CGRectMake(5.0f, 0.0f, agreedView.frame.size.width, agreedView.frame.size.height);
numberOfAgreesLabel.frame = CGRectMake(5.0f, 0.0f, agreedView.frame.size.width, agreedView.frame.size.height);
return cell;
}
else
{
if (agreedView) {
[agreedView removeFromSuperview];
}
return cell;
}

Better you set frames for your custom views in subclassed UITableView cell's class
hear is the sample code
//.h file of subclassed UITableView cell
#import <UIKit/UIKit.h>
#interface WavesFeedCell : UITableViewCell
#property(nonatomic, retain)UILabel *timeStampLabel;
#property(nonatomic, retain)UILabel *waveTextLabel;
#property(nonatomic, retain)UILabel *wavedByLabel;
#property(nonatomic, retain) id cellWaveObject; //your object from array
#end
//.m file subclassed UITableView cell
#import "WavesFeedCell.h"
#implementation WavesFeedCell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
UILabel *label1 = [[UILabel alloc]initWithFrame:CGRectZero];
UILabel *label2 = [[UILabel alloc]initWithFrame:CGRectZero];
UILabel *label3 = [[UILabel alloc]initWithFrame:CGRectZero];
self.timeStampLabel = label1;
self.waveTextLabel = label2;
self.wavedByLabel = label3;
//these are added with zero rect
[self addSubview:label1];
[self addSubview:label2];
[self addSubview:label3];
//for agreed imageview
UIImageView *agreedImgView = [[UIImageView alloc]initWithFrame:CGRectZero];
agreedImgView.tag = 200; //to access in layoutsubviews.
[self addSubview:agreedImgView];
//without ARC
[agreedImgView release];
[label1 release];
[label2 release];
[label3 release];
}
return self;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
- (void)layoutSubviews
{
[super layoutSubviews];
//hear set frames for all labels
self.timeStampLabel.frame = CGRectMake(5, 5, self.bounds.size.width-30.0f, 40.0f);
self.waveTextLabel.frame = CGRectMake(5, 45, self.bounds.size.width-30.0f, 40.0f);
self.wavedByLabel.frame = CGRectMake(5, 95, self.bounds.size.width-30.0f, 40.0f);
//hear you check weather it is agreed or not
if(self.cellWaveObject.numberOfAgrees > 1)
{
UIImageView *agreedView = (UIImageView *)[self viewWithTag:200];
//set frme for imageview as you did
// remember dont add any views hear and set your required frames only because this method called many times
}
//in other class
//.m file
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
WavesFeedCell *cell = [self.aTableView dequeueReusableCellWithIdentifier:#"WavesFeedCell"];
if(cell == nil)
{
cell = [[WavesFeedCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"WavesFeedCell"];
}
//set cell properties
return cell;
}

Related

UITableViewCell element no longer accessible via [cell.contentView viewWithTag] when scrolled down

I am trying to create expand/collapse cell. On every cell, it has subview of UIView for border bottom. If expanded, the border should also go to bottom of the cell. It is working fine on initial load of the cells, however, when I scroll down, the border is no longer going to the bottom.
I am adjusting the border originY via taskOptionsExpand method. That method is getting the border view via [cell.contentView viewWithTag:2].
Code below:
#import "HomeViewController.h"
#interface HomeViewController ()<UITableViewDelegate, UITableViewDataSource>
#property (strong, nonatomic) UITableView *tableView;
#property (strong, nonatomic) NSIndexPath *selectedIndexPath;
#end
#implementation HomeViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.selectedIndexPath = nil;
[self.view addSubview:self.tableView];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (UITableView *)tableView
{
if (!_tableView) {
_tableView = [[UITableView alloc] init];
_tableView.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
_tableView.delegate = self;
_tableView.dataSource = self;
_tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
[_tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"Cell"];
[_tableView addSubview:self.tableRefreshControl];
}
return _tableView;
}
# pragma mark - table view delegates
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 100;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([self.selectedIndexPath isEqual:indexPath]) {
return 80;
}else{
return 50;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell"];
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
// text view
UIView *view1 = [[UIView alloc] initWithFrame:CGRectMake(20, 0, self.view.frame.size.width-20, 50)];
view1.backgroundColor = [UIColor clearColor];
view1.tag = 0;
UILabel *title = [[UILabel alloc] initWithFrame:view1.frame];
title.text = #"Lorem ipsum";
title.textColor = [UIColor grayColor];
[view1 addSubview:title];
// options view
UIView *view2 = [[UIView alloc] initWithFrame:CGRectMake(0, 50, self.view.frame.size.width, 30)];
view2.backgroundColor = [UIColor orangeColor];
view2.tag = 1;
// border bottom
CGRect frame = CGRectMake(20, 49, self.view.frame.size.width-40, 1);
if ([self.selectedIndexPath isEqual:indexPath]) {
frame.origin.y = 79; //expand
} else {
}
UIView *border = [[UIView alloc] initWithFrame:frame];
border.backgroundColor = [UIColor blueColor];
border.tag = 2;
cell.clipsToBounds = YES;
[cell.contentView addSubview:view1];
[cell.contentView addSubview:view2];
[cell.contentView addSubview:border];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([self.selectedIndexPath isEqual:indexPath]) {
[self taskOptionsExpand:NO indexPath:indexPath];
self.selectedIndexPath = nil;
} else {
[self taskOptionsExpand:YES indexPath:indexPath];
[self taskOptionsExpand:NO indexPath:self.selectedIndexPath];
self.selectedIndexPath = indexPath;
}
[tableView beginUpdates];
[tableView endUpdates];
}
- (void) taskOptionsExpand:(BOOL) expand indexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
UIView *border = [cell.contentView viewWithTag:2];
NSLog(#"border: %#", border);
if (expand) {
border.frame = CGRectMake(20, 79, self.view.frame.size.width-40, 1);
}else{
border.frame = CGRectMake(20, 49, self.view.frame.size.width-40, 1);
}
}
#end
When scrolling the table view, the cell is dequeued to get reusable cell and as reusable cell will already have viewWithTag 2 (since it was added when the cell being reused was created) so adding another view with tag 2 will create the issues like above. To overcome the above issue you should remove the earlier added viewWithTag 2 and than re-add the view with the same tag, like-
// remove (previously added) border if it exists
UIView *border = nil;
border = [cell.contentView viewWithTag:2];
if(border)
[border removeFromSuperview];
// again create border view
Update your cellForRowAtIndexPath: method as
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell"];
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
// text view
UIView *view1 = [[UIView alloc] initWithFrame:CGRectMake(20, 0, self.view.frame.size.width-20, 50)];
view1.backgroundColor = [UIColor clearColor];
view1.tag = 0;
UILabel *title = [[UILabel alloc] initWithFrame:view1.frame];
title.text = #"Lorem ipsum";
title.textColor = [UIColor grayColor];
[view1 addSubview:title];
// options view
UIView *view2 = [[UIView alloc] initWithFrame:CGRectMake(0, 50, self.view.frame.size.width, 30)];
view2.backgroundColor = [UIColor orangeColor];
view2.tag = 1;
// border bottom
CGRect frame = CGRectMake(20, 49, self.view.frame.size.width-40, 1);
if ([self.selectedIndexPath isEqual:indexPath]) {
frame.origin.y = 79; //expand
} else {
}
UIView *border = nil;
border = [cell.contentView viewWithTag:2];
if(border)
[border removeFromSuperview];
border = [[UIView alloc] initWithFrame:frame];
border.backgroundColor = [UIColor blueColor];
border.tag = 2;
cell.clipsToBounds = YES;
[cell.contentView addSubview:view1];
[cell.contentView addSubview:view2];
[cell.contentView addSubview:border];
// release your allocated instances after adding them
[view1 release];
[view2 release];
[border release];
return cell;
}
Also you should release your subviews which you have allocated like view1, view2, border after adding them to the cell's content view as
[view1 release];
[view2 release];
[border release];
This will make there retain count from 2 to 1 and when the cell is deallocated than they will be removed from there parent which is cell.
Table views re-use cells. When a cell is scrolled offscreen it is added to a queue, and will be re-used for the next cell to be scrolled onscreen. That means your configuration code in tableView:cellForRowAtIndexPath: method will be run again on the same cell multiple times at different indexPaths. Since you're just adding your border view every time your configuration code runs, they will stack one on top of the other. When you call viewWithTag: you will only get one of the multiple views you've added.
The correct approach is to create a custom cell (subclass of UITableViewCell) with properties for each subview that needs to be configured (IBOutlets if using xibs/storyboard), so that they can be accessed.

Last cell of UITableView disappears automatically after some time?

I have a table view in one view controller with five cells on clicking of which I redirect to some other view controller. The issue is that whenever I come back the view controller that contains the table view, the contents of the last cell in the table view automatically disappears.
Here is the code for my tableview:
-(void)viewWillAppear:(BOOL)animated
{
logoimg=[[NSMutableArray alloc]initWithObjects:#"account_settings.png", #"account_settings_onclick.png",#"invite_friends.png", #"invite_friends_onclick.png", #"leaderboard.png", #"leaderboard_onclick.png", #"setting.png",#"setting_onclick.png", #"logout.png", #"logout_onclick.png", nil];
logoname=[[NSMutableArray alloc]initWithObjects:#"Account Settings", #"Invite Friends",#"Leaderboard",#"Settings",#"Logout",nil];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 45;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return logoname.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *CellIdentifier = [NSString stringWithFormat:#"%d_%d",indexPath.section,indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.backgroundColor = [UIColor clearColor];
//[[[cell contentView] subviews] makeObjectsPerformSelector: #selector(removeFromSuperview)];
UIImage *logoOff = [UIImage imageNamed:[logoimg objectAtIndex:indexPath.row*2]];
UIImage *logoOn = [UIImage imageNamed:[logoimg objectAtIndex:indexPath.row*2+1]];
UIButton *logo = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[logo setBackgroundImage:logoOff forState:UIControlStateNormal];
[logo setBackgroundImage:logoOn forState:UIControlStateSelected];
[logo setBackgroundImage:logoOn forState:UIControlStateHighlighted];
logo.frame = CGRectMake(20, 5, logoOff.size.width/2, logoOff.size.height/2);
logo.userInteractionEnabled = NO;
logo.tag = indexPath.row;
logo.selected = FALSE;
//[bottomView addSubview:logo];
UILabel *name = [[UILabel alloc]initWithFrame:CGRectMake(70,13, cell.contentView.frame.size.width-70, 20)];
[name setFont:[UIFont fontWithName:#"CenturyGothic" size:14]];
name.numberOfLines = 2;
name.text=[logoname objectAtIndex:indexPath.row];
name.backgroundColor = [UIColor clearColor];
[name sizeToFit];
name.textColor = [UIColor whiteColor];
UIImageView *divider = [[UIImageView alloc]init];
divider.image = [UIImage imageNamed:#"divider_line.png"];
divider.frame = CGRectMake(0, 43, self.view.frame.size.width ,2);
[cell.contentView addSubview:logo];
[cell.contentView addSubview:name];
[cell.contentView addSubview:divider];
return cell;
}
The logoname and logoimage are two NSMutableArrays.
If any more code is needed let me know I will provide the necessary code.
Better u need to subclass the tableview because, each time you are reusing the cell, but its subview are not, so just do like this
create a new file and name it as MyCustomCell subclass of UITableViewCell
in MyCustomCell.h file
MyCustomCell.h
#import <UIKit/UIKit.h>
#interface MyCustomCell : UITableViewCell
#property (nonatomic, retain) UIImage *logoOff;
#property (nonatomic, retain) UIImage *logoOn;
#property (nonatomic, retain) UIButton *logo;
#property (nonatomic, retain) UILabel *name;
#property (nonatomic, retain) UIImageView *divider;
#end
in MyCustomCell.m file
MyCustomCell.m
#import "MyCustomCell.h"
#implementation MyCustomCell
#synthesize logoOn;
#synthesize logoOff;
#synthesize logo;
#synthesize name;
#synthesize divider;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
self.logo = [UIButton buttonWithType:UIButtonTypeRoundedRect];
self.logo.userInteractionEnabled = NO;
self.logo.selected = FALSE;
self.name = [[UILabel alloc]initWithFrame:CGRectZero];
[self.name setFont:[UIFont fontWithName:#"CenturyGothic" size:14]];
self.name.numberOfLines = 2;
self.name.backgroundColor = [UIColor clearColor];
[self.name sizeToFit];
self.name.textColor = [UIColor whiteColor];
self.divider = [[UIImageView alloc]init];
[self.contentView addSubview:logo];
[self.contentView addSubview:name];
[self.contentView addSubview:divider];
}
return self;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
- (void)layoutSubviews
{
[super layoutSubviews];
// set the frames for all subviews
[self.logo setBackgroundImage:self.logoOff forState:UIControlStateNormal];
[self.logo setBackgroundImage:self.logoOn forState:UIControlStateSelected];
[self.logo setBackgroundImage:self.logoOn forState:UIControlStateHighlighted];
self.logo.frame = CGRectMake(20, 5, self.logoOff.size.width/2, self.logoOff.size.height/2);
self.name.frame = CGRectMake(70,13, self.bounds.size.width-70, 20);
self.divider.frame = CGRectMake(0, 43, self.bounds.size.width ,2);
}
#end
and in the controller
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
MyCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:#"CELL"];
if(cell == nil)
{
cell = [[MyCustomCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"CELL"];
}
cell.logoOff = [UIImage imageNamed:[logoimg objectAtIndex:indexPath.row*2]];
cell.logoOn = [UIImage imageNamed:[logoimg objectAtIndex:indexPath.row*2]];
cell.name.text = [logoname objectAtIndex:indexPath.row];
// cell.divider.image = [UIImage imageNamed:#"divider_line.png"]; //for test i commented
cell.divider.backgroundColor = [UIColor blackColor];
return cell;
}
Hope this helps u :)

subclass uitableviewcell and override layoutsubviews

I need to make cell selectionBackgroundView not on full width in plain UItableView. For this I made UItableViewCell subclass and override layoutsubviews method
- (void)layoutSubviews
{
[super layoutSubviews];
self.selectedBackgroundView.frame = CGRectMake(self.frame.origin.x + 10.0f, self.frame.origin.y, self.frame.size.width - 20.0f, self.frame.size.height);
}
My cellForRowAtIndexPath method looks like
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *identifier = [NSString stringWithFormat: #"CELL %i %i", indexPath.section, indexPath.row];
GroupedTableCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if(cell == nil)
{
cell = [[GroupedTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
UIView *cellBgView = [[UIView alloc] init];
cellBgView.frame = CGRectMake(10, 0, 300, 80);
[cellBgView setBackgroundColor:[UIColor colorWithRed:242 / 255.0 green:242 / 255.0 blue:242 / 255.0 alpha:1.0]];
[cell.contentView addSubview:cellBgView];
}
[cell setBackgroundColor:[UIColor clearColor]];
UIView *selectionView = [[UIView alloc] init];
[selectionView setBackgroundColor:[UIColor colorWithRed:181 / 255.0 green:211 / 255.0 blue:53 / 255.0 alpha:1.0]];
selectionView.frame = CGRectMake(10, 0, 300, 80);
cell.selectedBackgroundView = selectionView;
return cell;
}
But only for first row selectedView works correct. For other rows I have selectedView with clear color. Please, help me.
All I need was to set frame with numbers.
- (void)layoutSubviews
{
[super layoutSubviews];
self.selectedBackgroundView.frame = CGRectMake(10.0f, 0, 300, 80);
}
Instead add the background in the subclassed cell itself,
do like this it is an example how you can manage the selection and deselection state in the cell change it to your requirements
//in your subclassed cell
#import "GroupedTableCell.h"
#implementation GroupedTableCell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
//add the background view hear only, changes the frame in the layoutsubviews
UIView *cellBgView = [[UIView alloc] init];
[cellBgView setTag:12345];//using tag to access in the layoutsubviews
[self addSubview:cellBgView];//hear u added the background view
}
return self;
}
//manage the cell selection and deselection state hear
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
// Configure the view for the selected state
[super setSelected:selected animated:animated];
UIView *cellBgView = [self viewWithTag:12345];
if(selected)
{
[cellBgView setBackgroundColor:[UIColor colorWithRed:242 / 255.0 green:242 / 255.0 blue:242 / 255.0
alpha:1.0]]; //your selected background color
}
else
{
[cellBgView setBackgroundColor:[UIColor clearColor]]; //your deselected background color
}
}
//setting the frames of views within the cell
- (void)layoutSubviews
{
[super layoutSubviews];
UIView *cellBgView = [self viewWithTag:12345];
cellBgView.frame = CGRectMake(10, 0, 300, 80);//always set the frame in layoutSubviews
}
in your controller just do like this
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
GroupedTableCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if(cell == nil)
{
cell = [[GroupedTableCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"];
}
return cell;
}
Hope this helps u :)

how to add UITableviewcell subview as uiscrollview

I have UITableViewCell subview as UIScrollview and UIscrollview as dynamic uilabels and i need to scroll horizontally with pagination. but i need to scroll synchronously all the table view cell. problem is not able to scroll all the cell togeather.
here is my source code.
Customcell source:
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
//ScrollView
self.kpiScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 300, 70)];
[self.kpiScrollView setPagingEnabled:YES];
[self.contentView addSubview:self.kpiScrollView];
[self.kpiScrollView release];
NSArray *colors = [NSArray arrayWithObjects:[UIColor grayColor], [UIColor greenColor], [UIColor blueColor], nil];
for (int i =0; i<colors.count; i++) {
CGRect frame;
frame.origin.x = self.kpiScrollView.frame.size.width *i;
frame.origin.y = 0;
frame.size = self.kpiScrollView.frame.size;
subView = [[UIView alloc] initWithFrame:frame];
subView.backgroundColor = [colors objectAtIndex:i];
[self.kpiScrollView addSubview:subView];
[subView release];
}
self.kpiScrollView.contentSize =
CGSizeMake(self.kpiScrollView.frame.size.width*colors.count,
self.kpiScrollView.frame.size.height);
}
}
and TableView source:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = #"CellIdentifier";
PageCell *cell = (PageCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[[PageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]autorelease];
}
// cell.pageDelegate = self;
cell.self.kpiScrollView.delegate= self;
cell.tag = indexPath.row+1;
NSLog(#"cell tag:%d", cell.tag);
return cell;
}
UIScrollView delegate methods:
- (void)scrollViewDidScroll:(UIScrollView *)sender {
if (kpiScrollView == self.kpiTableView) {
return;
}
CGPoint contentOffset = kpiScrollView.contentOffset;
for (PageCell *cell in [self.kpiTableView visibleCells]) {
cell.kpiScrollView.contentOffset = contentOffset;
}
}
Skimming the code, not sure if there are other problems, but the first thing to fix is where you get the content offset....
- (void)scrollViewDidScroll:(UIScrollView *)sender {
// note the change here...
if (sender == self.kpiTableView) return;
// get the content offset from the cell's scrollview that posted this delegate message
CGPoint contentOffset = sender.contentOffset;
for (PageCell *cell in [self.kpiTableView visibleCells]) {
cell.kpiScrollView.contentOffset = contentOffset;
}
}

UIImageView does not appear in custom UITableViewCell

I have a need to display three images per row in a tableview. I have created a custom tableviewcell that has three imageviews in it. The tableView in its cellForRowAtIndexPath: method gives the names of the images to the cell and the cell is expected to load them side by side in a row. But the images are not appearing in the tableView. I am not sure why it isnt working. Please help!
Here is the code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"Cell";
customCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[customCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
NSString *imageForCell = [arrayImages objectAtIndex:(indexPath.row*3)];
cell.firstImageName = imageForCell;
imageForCell = [arrayImages objectAtIndex:(indexPath.row*3)+1];
cell.secondImageName = imageForCell;
cell.thirdImageName = [arrayImages objectAtIndex:(indexPath.row*3)+2];
return cell;
}
The customCell.m:
#import "customCell.h"
#implementation customCell
#synthesize firstImageView, secondImageView,thirdImageView, firstImageName, secondImageName, thirdImageName;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
//Make the Rects for the images
CGRect rectForFirstImage = CGRectMake(10, 0, 90, 140);
CGRect rectForSecondImage = CGRectMake(110, 0, 90, 140);
CGRect rectForThirdImage = CGRectMake(210, 0, 90, 140);
//create the Image views with the Rects
firstImageView.frame = rectForFirstImage;
secondImageView.frame = rectForSecondImage;
thirdImageView.frame = rectForThirdImage;
//set the images
[firstImageView setImage:[UIImage imageNamed:firstImageName]];//tried setting the image this way also
// firstImageView.image = [UIImage imageNamed:firstImageName];
secondImageView.image = [UIImage imageNamed:secondImageName];
thirdImageView.image = [UIImage imageNamed:thirdImageName];
// set the content mode for the image views to fit in the images
firstImageView.contentMode = UIViewContentModeScaleAspectFit;
secondImageView.contentMode = UIViewContentModeScaleAspectFit;
thirdImageView.contentMode = UIViewContentModeScaleAspectFit;
}
return self;
}
-(void) layoutSubviews{
[super layoutSubviews];
self.opaque = NO;
[self.contentView addSubview:firstImageView];
[self.contentView addSubview:self.secondImageView];
[self.contentView addSubview:self.thirdImageView];
}
#end
I have used the following code for your task.I used SDWebimage for assigning image.You can use without SDWebimage also.Its working try this
if(indexPath.section==0)
{
if ([self.array count]>0)
{
if ([self.array count]>indexPath.row*3)
{
LooksObject *looksObjectRef1 = [self.array objectAtIndex:indexPath.row*3];
[cell.firstImage setImageWithURL:[NSURL URLWithString:looksObjectRef1.looksThumbImage] placeholderImage:[UIImage imageNamed:#"no_image.png"]];
}
if ([self.array count]>(indexPath.row*3)+1)
{
LooksObject *looksObjectRef2 = [self.array objectAtIndex:(indexPath.row*3)+1];
[cell.secondImage setImageWithURL:[NSURL URLWithString:looksObjectRef2.looksThumbImage] placeholderImage:[UIImage imageNamed:#"image.png"]];
}
if ([self.array count]>(indexPath.row*3)+2)
{
LooksObject *looksObjectRef3 = [self.array objectAtIndex:(indexPath.row*3)+2];
[cell.thirdImage setImageWithURL:[NSURL URLWithString:looksObjectRef3.looksThumbImage] placeholderImage:[UIImage imageNamed:#"image.png"]];
}
}
}

Resources