I have a UITableView with paging enabled. At first I can scroll very smoothly between cells. However, after scrolling back and forth a few times, it becomes rather choppy. Am I not creating/reusing my cells properly?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cash-Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
UIImageView *image = [[UIImageView alloc] initWithFrame:CGRectMake(20, 40, cell.frame.size.width-40, cell.frame.size.width-40)];
Purchase *purch = (Purchase *)self.purchases[indexPath.row];
[image setImage:[UIImage imageWithData:purch.image]];
image.contentMode = UIViewContentModeCenter;
image.contentMode = UIViewContentModeScaleAspectFill;
image.clipsToBounds = YES;
[self setMaskTo:image byRoundingCorners:UIRectCornerTopLeft|UIRectCornerTopRight];
[cell addSubview:image];
UIView *price = [[UIView alloc] initWithFrame:CGRectMake(20, 40+cell.frame.size.width-40, cell.frame.size.width-40, 60)];
UILabel *priceLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, price.frame.size.width, price.frame.size.height)];
[priceLabel setText:#"$10.0"];
[priceLabel setTextAlignment:NSTextAlignmentCenter];
[priceLabel setFont:[UIFont boldSystemFontOfSize:25.0f]];
[self setMaskTo:price byRoundingCorners:UIRectCornerBottomLeft|UIRectCornerBottomRight];
[price addSubview:priceLabel];
[price setBackgroundColor:[UIColor whiteColor]];
[cell addSubview:price];
return cell;
}
If you want to reuse them then make sure you add the content to your UITableViewCell only once and on reusing it just update it (e.g. update the image and the price accordingly).
Otherwise, what you get with your implementation is adding subviews price and image everytime (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath gets called. Just try debugging the number of subviews your cell has to see if I am right.
You could go this way:
if ( ! [cell viewWithTag: 1])
{
UIImageView *image = [[UIImageView alloc] initWithFrame:CGRectMake(20, 40, cell.frame.size.width-40, cell.frame.size.width-40)];
image.tag = 1;
image.contentMode = UIViewContentModeCenter;
image.contentMode = UIViewContentModeScaleAspectFill;
image.clipsToBounds = YES;
[self setMaskTo:image byRoundingCorners:UIRectCornerTopLeft|UIRectCornerTopRight];
[cell addSubview:image];
}
if ( ! [cell viewWithTag: 2])
{
UIView *price = [[UIView alloc] initWithFrame:CGRectMake(20, 40+cell.frame.size.width-40, cell.frame.size.width-40, 60)];
UILabel *priceLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, price.frame.size.width, price.frame.size.height)];
priceLabel.tag = 2;
[priceLabel setTextAlignment:NSTextAlignmentCenter];
[priceLabel setFont:[UIFont boldSystemFontOfSize:25.0f]];
[self setMaskTo:price byRoundingCorners:UIRectCornerBottomLeft|UIRectCornerBottomRight];
[price addSubview:priceLabel];
[price setBackgroundColor:[UIColor whiteColor]];
[cell addSubview:price];
}
Purchase *purch = (Purchase *)self.purchases[indexPath.row];
UIImage *image = [cell viewWithTag: 1];
[image setImage:[UIImage imageWithData:purch.image]];
UILabel *priceLabel = [cell viewWithTag: 2];
[priceLabel setText:#"$10.0"];
This is because - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath is being called each time the cell comes into the view. Add the images to an array (in viewDidLoad or somewhere), and you'll get a smoother result.
You are not reusing the cells, which causes the lag/choppy scrolling.
suggestion:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"Cash-Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if(cell == nil){
UIImageView *image = [[UIImageView alloc] initWithFrame:CGRectMake(20, 40, cell.frame.size.width-40, cell.frame.size.width-40)];
Purchase *purch = (Purchase *)self.purchases[indexPath.row];
[image setImage:[UIImage imageWithData:purch.image]];
image.contentMode = UIViewContentModeCenter;
image.contentMode = UIViewContentModeScaleAspectFill;
image.clipsToBounds = YES;
image.tag = 10;
[self setMaskTo:image byRoundingCorners:UIRectCornerTopLeft|UIRectCornerTopRight];
[cell.contentView addSubview:image];
UIView *price = [[UIView alloc] initWithFrame:CGRectMake(20, 40+cell.frame.size.width-40, cell.frame.size.width-40, 60)];
UILabel *priceLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, price.frame.size.width, price.frame.size.height)];
[priceLabel setText:#"$10.0"];
[priceLabel setTextAlignment:NSTextAlignmentCenter];
[priceLabel setFont:[UIFont boldSystemFontOfSize:25.0f]];
[self setMaskTo:price byRoundingCorners:UIRectCornerBottomLeft|UIRectCornerBottomRight];
[price addSubview:priceLabel];
[price setBackgroundColor:[UIColor whiteColor]];
price.tag = 11;
[cell.contentView addSubview:price];
}
//update the value here
UIImageView *imgV = (UIImageView *)[self.contentView viewWithTag:10];
// update the imageView here
//imgV.image = image
UIView *vv = (UIView *)[self.contentView viewWithTag:11];
// Update the UIView here
//vv.text = #"text here";
//Put setselection style here to allow the cell to be loaded before setting the property value
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
Related
hi im creating chat example and if user add send button adding new object in my arrray and reload data but its overwrite old table.
its my array :
arr1 = [[NSMutableArray alloc] initWithObjects:#"Whats up today ? ", #"Hello.", nil];
Here my source :
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *simleTableIdentifier = #"TeamCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"TeamCell"];
}
cell.backgroundColor = [UIColor clearColor];
tableView.scrollEnabled = YES;
UIImageView *myRect = [[UIImageView alloc] initWithFrame:CGRectMake(20, 30, 10, 12)];
myRect.image = [UIImage imageNamed:#"tri.png"];
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"jj.jpg"]];
UILabel *label = [[UILabel alloc] init];
label.text = [arr1 objectAtIndex:indexPath.row];
label.numberOfLines = 0;
label.lineBreakMode = NSLineBreakByWordWrapping;
label.font =[UIFont systemFontOfSize:14.0];
label.text = [arr1 objectAtIndex: indexPath.row];
label.textColor = [UIColor blackColor];
label.backgroundColor = [UIColor clearColor];
label.frame = CGRectMake(40, 40, 210, 80);
[label sizeToFit];
UIImageView *imgim = [[UIImageView alloc] initWithFrame:CGRectMake(30, 10, label.frame.size.width+20, label.frame.size.height+20)];
imgim.image = [UIImage imageNamed:#"bg.png"];
CGRect myRectANGLE = CGRectMake(imgim.frame.origin.x+10,imgim.frame.origin.y+10, label.frame.size.width, label.frame.size.height);
[label setFrame:myRectANGLE];
CALayer *addRadius = [imgim layer];
[addRadius setMasksToBounds:YES];
[addRadius setCornerRadius:5.0];
[self.MyTableView setSeparatorColor:[UIColor clearColor]];
[self.MyTableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];
self.MyTableView.transform = CGAffineTransformMakeScale(1, -1); //in viewDidLoad
cell.transform = CGAffineTransformMakeScale(1, -1);//in tableView:cellForRowAtIndexPath:
[[cell contentView] addSubview:myRect];
[[cell contentView] addSubview:imgim];
[[cell contentView] addSubview:label];
return cell;
}
İf click send button i reload data but its overwite on old-data look like my photo :
-(IBAction)btnTap:(UIButton *)sender {
[arr1 insertObject:Textify.text atIndex:0];
NSLog(#"%i", arr1.count);
[MyTableView reloadData];
}
Try clearing the cell's contentView subview, and then add the new subviews.
Here's a block of code for removing the subviews, taken from this post.
if ([cell.contentView subviews]){
for (UIView *subview in [cell.contentView subviews]) {
[subview removeFromSuperview];
}
}
UITableViewCell will be reused while reload, you should not create subviews again to add on cell.contentView.Try to use code below
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"TeamCell"];
UILabel *label = [[UILabel alloc] initWithFrame:someFrame];
label.tag = 1000;
[cell.contentView addSubview:label];
}
UILabel *label = [cell.contentView viewWithTag:1000];
label.text = #"something";
I need to use two tableview in a view. Also i need to create these tables with custom cells.
I tried something but i could not see even simple string in my table's cell.
What's wrong here?
Here is my updated code;
I have still problems, i am taking invalid argument exception [LastVisitOrder superview]: unrecognized selector sent to instance .Since i have changed uiview to uiview controller.
- (id)initWithFrame:(CGRect)frame
{
self.view = [super initWithFrame:frame];
if (self) {
self.view.frame = CGRectMake(0, 0, 1024, 768);
[self.view setBackgroundColor:[[UIColor blackColor] colorWithAlphaComponent:0.8]];
UIView *popup = [[UIView alloc]initWithFrame:CGRectMake((self.view.frame.size.width-860)/2,(self.view.frame.size.height-570)/2, 860, 570)];
[popup setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:#"popup_bckgrnd"]]];
[self.view addSubview:popup];
UILabel *customerName = [[UILabel alloc]initWithFrame:CGRectMake(50, 50, 300, 30)];
[customerName setBackgroundColor:[UIColor clearColor]];
[customerName setText:#"Beşiktaş Eczanesi"];
[customerName setFont:[UIFont fontWithName:#"Arial-BoldMT" size:18]];
[popup addSubview:customerName];
UILabel *customerDetail = [[UILabel alloc]initWithFrame:CGRectMake(50, 70, 300, 30)];
[customerDetail setBackgroundColor:[UIColor clearColor]];
[customerDetail setText:#"Tel: 231 213 23 23 Bla bla cad. Bla bla Sok. Bla bla Apt. No:Bla Blastan/Bistanbul"];
[customerDetail setFont:[UIFont fontWithName:#"Arial" size:14]];
[popup addSubview:customerDetail];
UIButton *close = [[UIButton alloc]initWithFrame:CGRectMake(780, 65, 19, 19)];
[close setBackgroundImage:[UIImage imageNamed:#"kapat"] forState:UIControlStateNormal];
[close addTarget:self action:#selector(closePopUp:) forControlEvents:UIControlEventTouchUpInside];
[popup addSubview:close];
UIView *titleLine = [[UIView alloc]initWithFrame:CGRectMake(35, 100, 790, 2)];
[titleLine setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:#"baslik_cizgi"]]];
[popup addSubview:titleLine];
dateTable = [[UITableView alloc]initWithFrame:CGRectMake(48.5, 165, 200, 345)];
dateTable.layer.cornerRadius = 10;
[dateTable setBackgroundColor:[UIColor clearColor]];
[popup addSubview:dateTable];
dateTable.delegate=self;
dateTable.dataSource=self;
UIImageView *visitDatesLabel = [[UIImageView alloc]initWithFrame:CGRectMake(70, 122, 148, 30)];
[visitDatesLabel setImage:[UIImage imageNamed:#"en_son_ziyaret"]];
[popup addSubview:visitDatesLabel];
UIImageView *line = [[UIImageView alloc]initWithFrame:CGRectMake(49.5, 160, 200, 2)];
[line setImage:[UIImage imageNamed:#"ust_cizgi"]];
[popup addSubview:line];
UIImageView *line2 = [[UIImageView alloc]initWithFrame:CGRectMake(270.5, 160, 540, 2)];
[line2 setImage:[UIImage imageNamed:#"ust_cizgi"]];
[popup addSubview:line2];
UIImageView *productsDatesLabel = [[UIImageView alloc]initWithFrame:CGRectMake(300, 122, 102, 29)];
[productsDatesLabel setImage:[UIImage imageNamed:#"urunler"]];
[popup addSubview:productsDatesLabel];
UIImageView *verticalLine = [[UIImageView alloc]initWithFrame:CGRectMake(430, 115, 2, 45)];
[verticalLine setImage:[UIImage imageNamed:#"dikey_cizgi"]];
[popup addSubview:verticalLine];
UILabel *firstMonth = [[UILabel alloc]initWithFrame:CGRectMake(455, 126, 148, 30)];
[firstMonth setBackgroundColor:[UIColor clearColor]];
[firstMonth setText:#"OCAK"];
[firstMonth setFont:[UIFont fontWithName:#"Arial-BoldMT" size:12]];
[firstMonth setTextColor:[UIColor grayColor]];
[popup addSubview:firstMonth];
UILabel *secondMonth = [[UILabel alloc]initWithFrame:CGRectMake(455+75, 126, 148, 30)];
[secondMonth setBackgroundColor:[UIColor clearColor]];
[secondMonth setText:#"ŞUBAT"];
[secondMonth setFont:[UIFont fontWithName:#"Arial-BoldMT" size:12]];
[secondMonth setTextColor:[UIColor grayColor]];
[popup addSubview:secondMonth];
UILabel *thirdMonth = [[UILabel alloc]initWithFrame:CGRectMake(455+75+75, 126, 148, 30)];
[thirdMonth setBackgroundColor:[UIColor clearColor]];
[thirdMonth setText:#"MART"];
[thirdMonth setFont:[UIFont fontWithName:#"Arial-BoldMT" size:12]];
[thirdMonth setTextColor:[UIColor grayColor]];
[popup addSubview:thirdMonth];
UILabel *rangeMonth = [[UILabel alloc]initWithFrame:CGRectMake(455+75+75+100, 126, 148, 30)];
[rangeMonth setBackgroundColor:[UIColor clearColor]];
[rangeMonth setText:#"OCAK-MART"];
[rangeMonth setFont:[UIFont fontWithName:#"Arial-BoldMT" size:12]];
[rangeMonth setTextColor:[UIColor grayColor]];
[popup addSubview:rangeMonth];
UIImageView *verticalLine2 = [[UIImageView alloc]initWithFrame:CGRectMake(510, 115, 2, 45)];
[verticalLine2 setImage:[UIImage imageNamed:#"dikey_cizgi"]];
[popup addSubview:verticalLine2];
UIImageView *verticalLine3 = [[UIImageView alloc]initWithFrame:CGRectMake(590, 115, 2, 45)];
[verticalLine3 setImage:[UIImage imageNamed:#"dikey_cizgi"]];
[popup addSubview:verticalLine3];
UIImageView *verticalLine4 = [[UIImageView alloc]initWithFrame:CGRectMake(670, 115, 2, 45)];
[verticalLine4 setImage:[UIImage imageNamed:#"dikey_cizgi"]];
[popup addSubview:verticalLine4];
medSalesTable = [[UITableView alloc]initWithFrame:CGRectMake(270.5, 165, 540, 345)];
medSalesTable.layer.cornerRadius = 10;
[medSalesTable setBackgroundColor:[UIColor clearColor]];
[popup addSubview:medSalesTable];
medSalesTable.delegate=self;
medSalesTable.dataSource=self;
}
return self;
}
-(void) closePopUp:(id)sender{
[self.view removeFromSuperview];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 5;
}
-(CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 50;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"cellForRowAtIndexPath");
if (tableView == dateTable)
{
static NSString *CellIdentifier = #"VisitDateCell";
VisitDateCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[VisitDateCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
[cell.lastVisit setText:#"fucker"];
return cell;
}
else if(tableView == medSalesTable){
static NSString *CellIdentifier2 = #"OrdersCell";
OrdersCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier2];
if (cell == nil) {
cell = [[OrdersCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier2];
}
[cell.textLabel setText:#"fucker"];
return cell;
}
}
#end
In your datasource methods you need to distinguish between the two tables.
//cellForRowAtIndexPath
if (tableView == medSalesTable) {
// configure the first table
}
else {
// configure the second table
// use a different cell identifier
}
Make sure you do this also in numberOfRowsInSection, and numberOfSectionsInTableView if necessary. This assumes that you set both table views datasource property to the controller.
Use cell = [[[NSBundle mainBundle] loadNibNamed:#"VisitDateCell" owner:self options:nil] objectAtIndex:0];
Instead of cell = [[[VisitDateCell alloc] initWithFrame:CGRectZero] autorelease];
Then use cell.textLabel.text = #"YOUR_TEXT";
UPDATE!
For having access to your variable date you need to create it global in VisitDateCell.h.Like:
#property (nonatomic, strong) UILabel *date;
Then it your TableView to achieve the access use:
(VisitDateCell*)cell.date = #"YOUR TEXT";
You don't need in your custom method setText. Just use this code in cellForRows.
Hope it will help!
This is an elegant way to do that I use all the time..
Here's only working on create multiples custom cells, there aren't any code for calculate the height of the cells.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
/*
Call a function to create all custom cells.
Send the tableview and the indexPath to this function.
So, your code will be clean and easy to read an maintenance =D
DON'T forget to change the height of each cell
*/
if (indexPath.row < 3)
return [self createACustomCell1:tableView indexPath:indexPath];
else
return [self createACustomCell2:tableView indexPath:indexPath];
}
//*************
// Create CUSTOM CELL 2
//*************
-(UITableViewCell *)createACustomCell1:(UITableView *)anTableView indexPath:(NSIndexPath *)indexPath{
static NSString *CUSTOMCELL_1 = #"CUSTOMCELL_1";
CustomCell_1 *cell = [anTableView dequeueReusableCellWithIdentifier:CUSTOMCELL_1];
if (!cell){
[anTableView registerNib:[UINib nibWithNibName:CUSTOMCELL_1
bundle:nil] forCellReuseIdentifier:CUSTOMCELL_1];
cell = [anTableView dequeueReusableCellWithIdentifier:CUSTOMCELL_1];
}
// Cell customization above
return cell;
}
//*************
// Create CUSTOM CELL 2
//*************
-(UITableViewCell *)createACustomCell2:(UITableView *)anTableView indexPath:(NSIndexPath *)indexPath{
static NSString *CUSTOMCELL_2 = #"CUSTOMCELL_2";
CustomCell_2 *cell = [anTableView dequeueReusableCellWithIdentifier:CUSTOMCELL_2];
if (!cell){
[anTableView registerNib:[UINib nibWithNibName:CUSTOMCELL_2
bundle:nil] forCellReuseIdentifier:CUSTOMCELL_2];
cell = [anTableView dequeueReusableCellWithIdentifier:CUSTOMCELL_2];
}
// Cell customization above
return cell;
}
After adding a font and a shadow to some UILabels I noticed that the table view animation lags when the view is popped off the stack (a side swipe like FB/Path uses). The side swipe was smooth until I added the UILabel shadows.
I think I might be adding it it the wrong place so that the label properties are being added incorrectly maybe. Please take a look at the following cellForRowAtIndexPath: method below:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString * cellReuseIdentifier = #"cellReuseIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellReuseIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellReuseIdentifier];
}
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 2, self.view.bounds.size.width, 200)];
imageView.image = [UIImage imageNamed:#"rest.jpg"];
[cell.contentView addSubview:imageView];
UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 2, 320, 30)];
titleLabel.text = (NSString *)[[publicDataArray objectAtIndex:indexPath.row] objectForKey:#"title"];
titleLabel.backgroundColor = [UIColor clearColor];
titleLabel.textColor = [UIColor whiteColor];
[titleLabel setFont:[UIFont fontWithName:#"HelveticaNeue" size:24]];
titleLabel.layer.shadowColor = [[UIColor whiteColor] CGColor];
titleLabel.layer.shadowOpacity = 0.7;
[cell.contentView addSubview:titleLabel];
UILabel *detailLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 160, cell.bounds.size.width, 30)];
detailLabel.text = (NSString *)[[publicDataArray objectAtIndex:indexPath.row] objectForKey:#"description"];
detailLabel.backgroundColor = [UIColor clearColor];
detailLabel.textColor = [UIColor whiteColor];
[detailLabel setFont:[UIFont fontWithName:#"HelveticaNeue" size:18]];
detailLabel.layer.shadowColor = [[UIColor whiteColor] CGColor];
detailLabel.layer.shadowOpacity = 0.7;
[cell.contentView addSubview:detailLabel];
cell.contentView.backgroundColor = [UIColor clearColor];
return cell;
}
thanks for any help.
You're always adding new subviews. So whenever you scroll the table view your cells are getting more and more content added into them.
Create all your subviews when the cell is created and then just update the subviews settings. Something like:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString * cellReuseIdentifier = #"cellReuseIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellReuseIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellReuseIdentifier];
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 2, self.view.bounds.size.width, 200)];
imageView.tag = 123123;
[cell.contentView addSubview:imageView];
UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 2, 320, 30)];
titleLabel.tag = 234234];
titleLabel.backgroundColor = [UIColor clearColor];
titleLabel.textColor = [UIColor whiteColor];
[titleLabel setFont:[UIFont fontWithName:#"HelveticaNeue" size:24]];
titleLabel.layer.shadowColor = [[UIColor whiteColor] CGColor];
titleLabel.layer.shadowOpacity = 0.7;
[cell.contentView addSubview:titleLabel];
UILabel *detailLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 160, cell.bounds.size.width, 30)];
detailLabel.tag = 345345];
detailLabel.backgroundColor = [UIColor clearColor];
detailLabel.textColor = [UIColor whiteColor];
[detailLabel setFont:[UIFont fontWithName:#"HelveticaNeue" size:18]];
detailLabel.layer.shadowColor = [[UIColor whiteColor] CGColor];
detailLabel.layer.shadowOpacity = 0.7;
[cell.contentView addSubview:detailLabel];
cell.contentView.backgroundColor = [UIColor clearColor];
}
UIImageView *imageView = (UIImageView *)[cell viewWithTag:123123];
imageView.image = [UIImage imageNamed:#"rest.jpg"];
UILabel *titleLabel = (UILabel *)[cell viewWithTag:234234];
titleLabel.text = (NSString *)[[publicDataArray objectAtIndex:indexPath.row] objectForKey:#"title"];
UILabel *detailLabel = (UILabel *)[cell viewWithTag:345345];
detailLabel.text = (NSString *)[[publicDataArray objectAtIndex:indexPath.row] objectForKey:#"description"];
return cell;
}
Since text attributes never change, move the code that sets them inside the if statement. Keep only the code that sets the image and the text of your labels outside the if statement. Cells are reused, so the attributes such as font etc. will remain with the cell even after it gets "recycled". In the else branch add code that finds existing labels in the cell. Otherwise, you keep adding the same label to the cell multiple times.
You add subviews, even after dequeueing instead of initializing a new cell. Make sure all the code that creates and adds subviews are only done on initializing a cell. If you need to refer to views in the cell for configuring, subclass UITableViewCell.
Also, shadow rendering could be slowing it down too, add a shadowpath to make the rendering more efficient:
add to your tableView:cellForRowAtIndexPath: method:
...
CGPathRef shadowPath = [UIBezierPath bezierPathWithRect:detailLabel.layer.bounds].CGPath;
detailLabel.layer.shadowPath = shadowPath;
...
This article from Twitter Engineering gives you a great overview: http://engineering.twitter.com/2012/02/simple-strategies-for-smooth-animation.html
Basically, you want to avoid using subviews but instead draw your content directly with Quartz. It's the single best thing you can do to improve performance. Also: Avoid transparency! In Instruments, you can also use the Core Animation instrument and activate "Color Blended Layers" to see where transparent views are being composed:
Replace your code with this :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString * cellReuseIdentifier = #"cellReuseIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellReuseIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellReuseIdentifier];
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 2, self.view.bounds.size.width, 200)];
imageView.image = [UIImage imageNamed:#"rest.jpg"];
imageView.tag =1;
[cell.contentView addSubview:imageView];
UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 2, 320, 30)];
titleLabel.text = (NSString *)[[publicDataArray objectAtIndex:indexPath.row] objectForKey:#"title"];
titleLabel.backgroundColor = [UIColor clearColor];
titleLabel.tag = 2;
titleLabel.textColor = [UIColor whiteColor];
[titleLabel setFont:[UIFont fontWithName:#"HelveticaNeue" size:24]];
titleLabel.layer.shadowColor = [[UIColor whiteColor] CGColor];
titleLabel.layer.shadowOpacity = 0.7;
[cell.contentView addSubview:titleLabel];
UILabel *detailLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 160, cell.bounds.size.width, 30)];
detailLabel.tag = 3;
detailLabel.text = (NSString *)[[publicDataArray objectAtIndex:indexPath.row] objectForKey:#"description"];
detailLabel.backgroundColor = [UIColor clearColor];
detailLabel.textColor = [UIColor whiteColor];
[detailLabel setFont:[UIFont fontWithName:#"HelveticaNeue" size:18]];
detailLabel.layer.shadowColor = [[UIColor whiteColor] CGColor];
detailLabel.layer.shadowOpacity = 0.7;
}
UIImageView *tempImgView = (UIImageView *)[cell viewWithTag:1];
tempImgView.image = [UIImage imageNamed:#""];// Here you can set any image by reusing imageview without allocating again and again
UILabel *tempLabel;
tempLabel = (UILabel *)[cell viewWithTag:2];
tempLabel.text = #"";// Here you can access your title label and can set its properties without allocating again
tempLabel = (UILabel *)[cell viewWithTag:3];
tempLabel.text = #"";// Here you can access your detailLabel label and can set its properties without allocating again
[cell.contentView addSubview:detailLabel];
cell.contentView.backgroundColor = [UIColor clearColor];
return cell;
}
You need create custom table view cell with a class. This code you added many label then shadow show no correctly.
code like this.
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString * cellReuseIdentifier = #"cellReuseIdentifier";
UITableCustomViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellReuseIdentifier];
if (cell == nil)
{
cell = [[UITableCustomViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellReuseIdentifier];
}
cell.imageView.image = [UIImage imageNamed:#"rest.jpg"];
cell.titleLabel.text = (NSString *)[[publicDataArray objectAtIndex:indexPath.row] objectForKey:#"title"];
cell.detailLabel.text = (NSString *)[[publicDataArray objectAtIndex:indexPath.row] objectForKey:#"description"];
return cell;
}
Hi am using 2 UIImageView in a cellrow with tag, each row is displayed sequentially by populating images from an array like (0th image,1st image) for row 0, and (2nd image,3rd image) for row 1 and so on...
i am successful in displaying the image with appropriate tag for each image, but am unsuccessful in getting the tag for image or cell in didrowselect method...i need the tag number to directly pass the tagnumber as array index to detailsegue...Am new to IOS programming, i would like to know if am doing anything wrong here, please suggest a way to get the appropriate tag number...your help in this regard is greatly appreciated, as am struck with only this task to be completed!!!
Pasted my code for your reference: self.tagnumber=0; this code is for displaying even number of images.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
//Check Even Rows or odd rows
if(_objects.count%2==0)
{
return (_objects.count/2);
}
else
{
return ((_objects.count/2)+1);
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *MyCellIdentifier = #"MyCellIdentifier";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:MyCellIdentifier];
if(cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyCellIdentifier];
}
NSInteger itemcount = _objects.count;
NSLog(#"RowCount:%d",_objects.count/2);
if(itemcount%2==0)
{
NSLog(#"Image Count is Even!");
if(itemcount!=self.tagnumber)
{
RSSItem *object = _objects[self.tagnumber];
UIImageView *imageView1 = [[UIImageView alloc]initWithFrame:CGRectMake(10, 4, 145, 95)];
imageView1.tag = self.tagnumber;//1;
NSLog(#"Tag number for Image1:%d", self.tagnumber);
imageView1.image = [UIImage imageWithData:object.artimageData];
[imageView1 setContentMode:UIViewContentModeScaleAspectFill];
[imageView1 setClipsToBounds:YES];
[cell.contentView addSubview:imageView1];
UILabel *label1 = [[UILabel alloc] initWithFrame:CGRectMake(10, 100, 145, 30)];
label1.tag = self.tagnumber;
[label1 setFont:[UIFont fontWithName:#"AppleGothic" size:14.0]];
[label1 setTextColor:[UIColor blackColor]];
[label1 setContentMode:UIViewContentModeScaleToFill];
[label1 setTextAlignment:NSTextAlignmentCenter];
label1.text = #"Added 2days ago";;
[label1 setNumberOfLines:1];
[cell.contentView addSubview:label1];
//Display next Image
self.tagnumber++;
object = _objects[self.tagnumber];
UIImageView *imageView2= [[UIImageView alloc]initWithFrame:CGRectMake(165, 4, 145, 95)];
imageView2.tag =self.tagnumber;
NSLog(#"Tag number for Image2:%d", self.tagnumber);
imageView2.image = [UIImage imageWithData:object.artimageData];
[imageView2 setContentMode:UIViewContentModeScaleAspectFill];
[imageView2 setClipsToBounds:YES];
[cell.contentView addSubview:imageView2];
UILabel *label2 = [[UILabel alloc] initWithFrame:CGRectMake(165, 100, 145, 30)];
label2.tag = self.tagnumber;
[label2 setFont:[UIFont fontWithName:#"AppleGothic" size:14.0]];
[label2 setTextColor:[UIColor blackColor]];
[label1 setContentMode:UIViewContentModeScaleToFill];
[label2 setTextAlignment:NSTextAlignmentCenter];
label2.text = #"Added 3days ago";;
[label2 setNumberOfLines:1];
[cell.contentView addSubview:label2];
self.tagnumber++;
[self dismissMegaAnnoyingPopup];
return cell;
}
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//Hide Category view if not
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
//[self performSegueWithIdentifier:#"ShowGalleryDetail" sender:cell];
int rownumber = cell.tag;
//Here i get 0 for rownnumber and even if i use indexpath.row**
NSLog (#"Current Page for article is:%i", rownumber);
}
In your cellForRowAtIndexPath method, you set the tag of a UIImageView or the tag of a UILabel.
In your didSelectRowAtIndexPath method, you get the tag of the cell.
Either get the tag of the image view or label that is in the cell, or set the cell`s tag.
I have a UITableView that has an image and text on each cell, however they are put side by side. What I'm trying to do is put the text label over the top of the image. Is it possible?
Take custom UITableViewCell,where take UIView at every cell and make your image as the background color of the UIView then take a UILabel at the top of the UIView.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *MyIdentifier = #"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:nil];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier] autorelease];
cell.textLabel.font = [UIFont fontWithName:#"Arial" size:15.0];
cell.selectionStyle = UITableViewCellSelectionStyleBlue;
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"pl_arows.png"]];
cell.accessoryView = imageView;
cellView = [[[UIView alloc] initWithFrame:CGRectMake(0,0,290, 70)] autorelease]; //important do not changer the position
cellView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"order_description_bg.png"]];
cellView.tag =10;
[cell.contentView addSubview:cellView];
imgView = [[UIImageView alloc] initWithFrame:CGRectMake(10, 15, 39, 36)];
imgView.image = [UIImage imageNamed:#"image_category.png"];
imgView.layer.borderColor = [UIColor blackColor].CGColor;
imgView.tag = 5;
[cellView addSubview:imgView];
//Status label
CGRect statusRectText = CGRectMake(52, 0, 50, 18);
UILabel *statusLabelText = [[[UILabel alloc] initWithFrame:statusRectText] autorelease];
statusLabelText.textAlignment = UITextAlignmentRight;
statusLabelText.backgroundColor = [UIColor clearColor];
statusLabelText.tag = 101;
[imgView addSubview:statusLabelText];
}
You will have to define a custom UITableViewCell in which you can place any standard UI objects, including a UILabel on top of your UIImage.