I am setting a UIImage, via a UIImageView as my background view of a subclassed UITableViewCell like so:
-(void)awakeFromNib {
UIImage *backImg = [[UIImage imageNamed:#"CellBackground"]
resizableImageWithCapInsets:UIEdgeInsetsMake(16, 132, 16, 16)];
UIImageView *imv = [[UIImageView alloc] initWithImage:backImg];
self.backgroundView = imv;
}
This works excellently, each cell is different in height (exposed via heightForRowAtIndexPath which calculates the height of a UILabel with text in it), and the background image resizes as I want the cell to.
However, when I rotate the device, the view hangs mid rotate, and takes 5-10 seconds to redraw in landscape, or crashes with no error. If I remove this imageview from the backgroundView, the rotate works excellently. Both simulator and device.
[Edit] Alternatively, I added the imageview as a subview of the cell.contentView - performance was better, but still laggy.
UIImage *backImg = [[UIImage imageNamed:#"CellBackground"]
resizableImageWithCapInsets:UIEdgeInsetsMake(16, 132, 16, 16)];
UIImageView *imv = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
imv.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
imv.image = backImg;
[self.contentView addSubview:imv];
Additionally, as mentioned above, my UITableViewCell is a subclass. The above code is in awakeFromNib, and I'm loading in my UITableViewCell like so:
// within initWithNibName: of UIViewcontroller:
cellLoader = [UINib nibWithNibName:#"MasterTableViewCell" bundle:[NSBundle mainBundle]];
// and UITableView method:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
MasterTableViewCell *cell = (MasterTableViewCell *)[tableView dequeueReusableCellWithIdentifier:#"MasterTableViewCell"];
if (cell == nil) {
NSArray *topLevelItems = [cellLoader instantiateWithOwner:self options:nil];
cell = [topLevelItems objectAtIndex:0];
}
return cell;
}
Am I doing something wrong? Any hints?
Are you calling this every time you draw a cell? This can really hurt your performance. I would suggest only doing this when drawing a new cell. So it would look like
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
{
UIImage *backImg = [[UIImage imageNamed:#"CellBackground"]
resizableImageWithCapInsets:UIEdgeInsetsMake(16, 132, 16, 16)];
UIImageView *imv = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
imv.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
imv.image = backImg;
[self.contentView addSubview:imv];
}
Related
I am loading custom separator image in uitableview cell.
Here is my code :
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
{
static NSString *CellID=#"Cell"
MyTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:SwitchCellIdentifier];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
UIImageview *aSwitch = [[UIImageview alloc] initWithImage:[UIImage imageNamed:#"divider.png"]];
separator.frame = CGRectMake(0,50,320,1);
[cell.contentView addSubview:seperator];
}
if(cell.height == 22)
{
/// here i am setting frame for uiimageview
}
but i am getting seperator image disappears for only one row out of 20 while scrolling.
Can you please help why it is loading like this.
If you've put your separator UIImage out of the bounds of the cell, and set cell.clipsToBounds = NO; to have the separator image displayed, the separator image might get hidden by drawing the next cell.
You can't control the z-index of the cells as they're being drawn on screen, it depends from where you're scrolling (bottom to top, or top to bottom).
If that's indeed you're issue, you can either put the divider inside the cell's frame, or if your separator is thin enough use:
[TableView setSeparatorColor:[UIColor colorWithPatternImage:[UIImage imageNamed:...]]];
self.tblView=[[UITableView alloc] initWithFrame:CGRectMake(0,0,320,370) //set as u need
style:UITableViewStylePlain];
self.tblView.delegate=self;
self.tblView.dataSource=self;
[self.view addSubview:self.tblView];
UIView *v = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 10)];//set as u ne
v.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"divider.png"]];
[self.tblView setTableHeaderView:v];
[self.tblView setTableFooterView:v];
[v release];
I have a UITableView with a title and an image on each cell. Some cells will have a default image and others will not. When I scroll the table, the image of some rows is not the expected and the image of another row gets displayed instead of the expected one. If I don't use dequeuereuseidentifier everything works fine, but I want to use it because I have lots of cells.
Any suggestion?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MyCell"];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"MyCell"];
CGRect titleRect = CGRectMake(60, 6, 200, 24);
UILabel *title = [[UILabel alloc] initWithFrame: titleRect];
title.tag = 1;
title.backgroundColor = [UIColor clearColor];
title.font = [UIFont fontWithName:#"AdelleBasic-Bold" size:15.5];
[cell.contentView addSubview:title];
UIImageView *defaultCellImage = [[UIImageView alloc] initWithFrame:CGRectMake(8, 10, 42, 42)];
defaultCellImage.tag = 2;
[defaultCellImage setImage:[UIImage imageNamed: #"Default_Row_Image"]];
[cell.contentView addSubview:defaultCellImage];
}
NSUInteger row = [indexPath row];
Movie *movie = [_movies objectAtIndex: row];
UILabel *titleRowLabel = (UILabel *) [cell.contentView viewWithTag:1];
titleRowLabel.text = [movie title];
UIImageView *cellImage = (UIImageView *) [cell.contentView viewWithTag:2];
if (![movie.imageName isEqualToString:#""])
[cellImage setImage:[UIImage imageNamed: [movie imageName]]];
return cell;
}
The first cells to be used in your table view will be properly loaded. Since there is no cell to dequeue, the if (cell == nil) will return YES and your cell will have its image set to be the default. Then, if your condition for setting a different image is satisfied later in the method, a different image will be shown. So far, so good.
However, when a reusable cell is dequeued, it already has an image set, which might not be the default. Since cell == nil will now return NO, this cell will never have its image reset to the default one, even if it is the image that should be shown.
I am having trouble centering a 200x200 image horizontally inside a customized UITableViewCell. I have set the tableViewheightForRowAtIndexPath in the UITableViewDelegate to the appropriate value, but that doesn't center my image horizontally, it does so only vertically (better than nothing I guess). I also tried to change the value of the imageView.frame in layoutSubviews in my customized cell, but that doesn't seem to have any effect. I have even commented it out, placed it before [super layoutSubviews];, played around with the values of the frame, but I keep getting the same result.
Can anyone help me with this? What code should I write to achieve such an effect?
Thanks.
You will try this code its help you
You need to subclass UITableViewCell and override layoutSubviews, as follows:
- (void) layoutSubviews
{
[super layoutSubviews];
self.imageView.frame = CGRectMake( 10, 10, 50, 50 ); // your positioning here
}
In your cellForRowAtIndexPath: method, be sure to return an instance of your new cell type.
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
UIImageView *imgView;
if(cell == nil)
{
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
imgView = [[UIImageView alloc] initWithFrame:(100,0,100,62)];
[imgView setImage:[UIImage imageNamed:#"img.png"]];
imgView.tag = 55;
[cell.contentView addSubview:imgView];
[imgView release];
}
else
{
imgView = (id)[cell.contentView viewWithTag:55];
}
using sdk 4.1. I'm getting growing memory footprint followed by crash (observed in Instruments) when loading a thumbnail image into imageview in table view cell. In addition scrolling is very jerky even with just 7-8 cells
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *FavouritesCellIdentifier = #"cellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:cellIdentifier] autorelease];
UIImageView* imgView = [[UIImageView alloc] initWithFrame:CGRectMake(10,
16, 64, 64)];
imgView.tag = kImageLabelTag;
[cell.contentView addSubview:imgView];
[imgView release];
}
UIImageView* imgView = (UIImageView*)[cell viewWithTag:kImageLabelTag];
NSData *contactImageData = (NSData*)ABPersonCopyImageDataWithFormat(personRef,
kABPersonImageFormatThumbnail);
UIImage *img = [[UIImage alloc] initWithData:contactImageData];
[imgView setImage:img];
[contactImageData release];
[img release];
return cell;
}
In viewdidunload i am setting self.tableview=nil , is there anyway to release the images held by the cell as memory footprint keeps growing even when navigating to totally different viewcontroller. Memory shoots up only when selecting the viewcontroller that holds this tableview.
The reason for crash is that you're releasing NSData object which you shouldn't.
And the scrolling of the table should be slow always because with each scroll, it will call cellForRowAtIndexPath method & with it will create a new image.
So try the below code & let me know whether it works or not
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *FavouritesCellIdentifier = #"cellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:cellIdentifier] autorelease];
UIImageView* imgView = [[UIImageView alloc] initWithFrame:CGRectMake(10, 16, 64, 64)];
imgView.tag = kImageLabelTag;
[cell.contentView addSubview:imgView];
[imgView release];
NSData *contactImageData = (NSData*)ABPersonCopyImageDataWithFormat(personRef, kABPersonImageFormatThumbnail);
UIImage *img = [[UIImage alloc] initWithData:contactImageData];
[imgView setImage:img];
[img release];
}
return cell;
}
I thing that the fact that you cast your CFDataRef to a NSData is the problem. I guess the release method doesn't do anything since the pointer is actually a pointer to a CFDataRef object that is supposed to be released using CFRelease function.
Try :
UIImageView* imgView = (UIImageView*)[cell viewWithTag:kImageLabelTag];
CFDataRef contactImageData = ABPersonCopyImageDataWithFormat(personRef,
kABPersonImageFormatThumbnail);
UIImage *img = [[UIImage alloc] initWithData:(NSData*)contactImageData];
[imgView setImage:img];
CFRelease(contactImageData);
[img release];
I want to have transparency between UITableViewCells. Space between the cells.
I user custom created cells and for setting a background i use this code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CustomCell = #"CustomBookingCell";
currentBooking = [arrayBookings objectAtIndex:indexPath.row];
CustomBookingCell *cell = (CustomBookingCell *)[tableView dequeueReusableCellWithIdentifier:CustomCell];
if (cell == nil) {
UIViewController *c = [[UIViewController alloc] initWithNibName:#"CustomBookingCell" bundle:nil];
cell = (CustomBookingCell *)c.view;
[ c release ];
}
bookingImage = [[UIImageView alloc] initWithImage:
[UIImage imageNamed:currentBooking.imageSource]];
[cell.imageForBooking addSubview:bookingImage];
cell.selectionStyle = UITableViewCellSelectionStyleGray;
cell.contentView.backgroundColor = [UIColor clearColor];
UIView* backgroundView = [[UIView alloc] initWithFrame:CGRectZero];
UIImage* bgImage = [UIImage imageNamed:#"Background_300_82.png"];
UIColor *bgColor = [[UIColor alloc] initWithPatternImage: bgImage];
backgroundView.backgroundColor = bgColor;
cell.backgroundView = backgroundView;
cell.label.text = currentBooking.title;
[bookingImage release];
[bgColor release];
[backgroundView release];
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 90;
}
The height of the cell is 10 pixels higher that the tableCellBg.png.
My background view has also a image as background (this background is supposed to be shown between the cells of course).
So I tried to add 10 pixels with transparency to my tableCellBg.png in the bottom to fix this. But the space between the cells is black. I can't see the view background between my cells.
What shall I do? Do I have to create a UIView in cellForRowAtIndexPath with the height of the tableCellBg.png and then add the Custom UITableViewCell as subview to the created UIView with a less higher height?
Or is there a much more simplyfied way to accomplish this?
Your table view needs a clear background colour. For example
myTableView.backgroundColor = [UIColor clearColor];
I solved it by using another method to add the background image to the UITableViewCell:
UIImage *image = [UIImage imageNamed:#"ny_bg_event.png"];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
imageView.frame = CGRectMake(0, 0, 300, 84);
cell.backgroundView = imageView;
cell.backgroundColor = [UIColor clearColor];
[imageView release];
[cell setFrame:CGRectMake(0, 0, 300, 84)];
cell.contentView.backgroundColor = [UIColor clearColor];
Instead of creating a UIView I just used a UIImageView instead.