I load a table with images and scroll up and down. After a minute or so, I get a "Received memory warning" notification. After seeing this message a few times, the app crashes.
I load by scrolling position 5 images every time the user scrolls to the bottom of the table.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"aCell";
PostTable_Cell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
CGFloat cellHeight = (screenWidth / 16) * 10 + self.view.frame.size.height * 0.09;
cell = [[PostTable_Cell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier withParentWidth:self.view.frame.size.width withCellHeight:cellHeight withParent:self withPostArray:[postsArray objectAtIndex:indexPath.row] withCurrentIndexPostArray:(int)indexPath.row];
[cell setUserInteractionEnabled:YES];
cell.selectionStyle = UITableViewCellStyleDefault;
tableView.separatorColor = [UIColor blackColor];
return cell;
}
Edit :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"aCell";
PostTable_Cell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
CGFloat cellHeight = (screenWidth / 16) * 10 + self.view.frame.size.height * 0.09;
if (cell == nil)
{
cell = [[PostTable_Cell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier withParentWidth:self.view.frame.size.width withCellHeight:cellHeight withParent:self withPostArray:[postsArray objectAtIndex:indexPath.row] withCurrentIndexPostArray:(int)indexPath.row];
[cell setUserInteractionEnabled:YES];
cell.selectionStyle = UITableViewCellStyleDefault;
tableView.separatorColor = [UIColor blackColor];
}
else
{
[cell reloadCellContetWithParent:self withPostArray:[postsArray objectAtIndex:indexPath.row] withCurrentIndexPostArray:(int)indexPath.row];
}
return cell;
}
Edit 3 :
#implementation PostTable_Cell
- (void)awakeFromNib
{
// Initialization code
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
-(void)dealloc
{
#ifdef DEBUG
NSLog(#"%# destoyed",NSStringFromClass([self class]));
#endif
}
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier withParentWidth:(CGFloat)parentWidth withCellHeight:(CGFloat)celltHeight withParent:(id)parent withPostArray:(id)postArray withCurrentIndexPostArray:(int)IndexNumber
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self)
{
mainDalegate = (Main*)parent;
self.backgroundColor = [UIColor clearColor];
Post *curPost = (Post*)postArray;
postId = [curPost getPostId];
postText = [curPost getPostText];
postImageUrl = [curPost getImageUrl];
commentsCount = [curPost getCommentsCount];
likesCount = [curPost getLikesCount];
likeByMe = [curPost getLikeByMe];
facebookId = [curPost getCreatorFacebookId];
publisherName =[curPost getCreatorName];
currentIndexPostArray = IndexNumber;
[GeneralMethods setNew_width:parentWidth ToView:self];
[GeneralMethods setNew_height:celltHeight ToView:self];
[self cellBuilderForPost];
}
return self;
}
mainDalegate = (Main*)parent;
It looks like this might be your issue. Your cells are not getting released because you are creating a retain cycle.
rules to avoid retain cycles.
Related
I want to hide the NSArrays (menuItems, about, and charting) on the click for the specific section header for the tableview cell arrays. I got the section header to highlight and de-highlight depending on tap gesture recognizer count but I can not get the tableview cells to hide when that specific section header is clicked. Can someone please help? Thank you! Here is my .m code. My GCF float method is located at the bottom of the .m.
#interface SidebarTableViewController ()
#end
#implementation SidebarTableViewController {
NSArray *menuItems;
NSArray *about;
NSArray *charting;
}
- (void)viewDidLoad {
[super viewDidLoad];
menuItems = #[#"Home",#"Field Goal", #"Punt", #"Kick Off", #"Snapper", #"Punter"];
about = #[#"Home",#"About Us", #"Tutorial"];
charting = #[#"Home",#"Charting"];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
if (indexPath.section==0) {
NSString *CellIdentifier = [menuItems objectAtIndex:indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
return cell;
}
else if(indexPath.section==1) {
NSString *CellIdentifier2 = [charting objectAtIndex:indexPath.row];
UITableViewCell *cell2 = [tableView dequeueReusableCellWithIdentifier:CellIdentifier2 forIndexPath:indexPath];
return cell2;
}
else {
NSString *CellIdentifier1 = [about objectAtIndex:indexPath.row];
UITableViewCell *cell1 = [tableView dequeueReusableCellWithIdentifier:CellIdentifier1 forIndexPath:indexPath];
return cell1;
}
}
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Set the title of navigation bar by using the menu items
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
UINavigationController *destViewController = (UINavigationController*)segue.destinationViewController;
destViewController.title = [[menuItems objectAtIndex:indexPath.row] capitalizedString];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 3 ;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (section==0)
{
return [menuItems count];
}
else if(section==1)
{
return [charting count];
}
else{
return [about count];
}
}
- (UIView*) tableView: (UITableView*) tableView viewForHeaderInSection: (NSInteger) section
{
UILabel *headerLabel = [[UILabel alloc]init];
headerLabel.tag = section;
headerLabel.userInteractionEnabled = YES;
headerLabel.backgroundColor = [UIColor grayColor];
if(section == 0){
headerLabel.text = [NSString stringWithFormat:#"Timers Without Charting"];
}
else if(section==1)
{
headerLabel.text = [NSString stringWithFormat:#"Charting with Timers"];
}
else{
headerLabel.text = [NSString stringWithFormat:#"About Us/Tutorial"];
}
headerLabel.frame = CGRectMake(0, 0, tableView.tableHeaderView.frame.size.width, tableView.tableHeaderView.frame.size.height);
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(catchHeaderGesture:)];
tapGesture.cancelsTouchesInView = NO;
[headerLabel addGestureRecognizer:tapGesture];
return headerLabel;
//return nil;
}
-(void)catchHeaderGesture:(UIGestureRecognizer*)sender
{
border ++;
if (border == 1)
{
UILabel *caughtLabel = (UILabel*)sender.view;
caughtLabel.layer.borderColor = [UIColor yellowColor].CGColor;
caughtLabel.layer.borderWidth = 2;
}
if (border == 2 )
{
UILabel *caughtLabel = (UILabel*)sender.view;
caughtLabel.layer.borderColor = [UIColor clearColor].CGColor;
caughtLabel.layer.borderWidth = 2;
border = 0;
}
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
border ++;
if (border == 1)
{
UITableViewCell* cell = [menuItems objectAtIndex:indexPath.row];
cell.hidden = YES;
return 40.0;
}
if (border == 2 )
{ border = 0;
UITableViewCell* cell = [menuItems objectAtIndex:indexPath.row];
cell.hidden = YES;
}
return 0;
}
#end
You need a few couple things to make this work.
section headers that respond to taps.
a method for expanding or collapsing a section.
some way to track which sections are collapsed.
The first is trivial. Return a UIView for the header, and attach a UITapGestureRecognizer to it. You'll need a method to figure out which section it is. You can use the tag property, or you can store the views in an NSMutableArray.
In tableView:numberOfRowsInSection: you return 0 if the section is collapsed, or the actual number, if not.
In the handler for the gesture recognizer, you toggle the collapsed/expanded state, and then you call `[self.tableView reloadSections:withRowAnimation:] to update the visuals.
(I do see in your posted code that you already handle part of this.)
I'd like to add UIGestureRecognizer to UITableViewCell.
When I call panAction: in CustomCell class, it will work.
But I'd like to call the method in ViewController class, and in this case, it will not work.
How do I fix it to work panAction:?
- (void)viewDidLoad
{
_tableView = [[UITableView alloc]initWithFrame:self.view.frame];
_tableView.delegate = self;
_tableView.dataSource = self;
[_tableView registerClass:[CustomCell class] forCellReuseIdentifier:#"Cell"];
[self.view addSubview:_tableView];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *nibName = #"Cell";
CustomCell *cell = (CustomCell*)[tableView dequeueReusableCellWithIdentifier:nibName];
if (!cell) {
cell = (CustomCell*)[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nibName];
}
return cell;
}
- (void)setupGesture
{
UIPanGestureRecognizer* panRecognizer = [[UIPanGestureRecognizer alloc]initWithTarget:self action:#selector(panAction:)];
CustomCell* cell = (CustomCell*)[_tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
[cell addGestureRecognizer:panRecognizer];
}
- (void)panAction:(UIPanGestureRecognizer *)sender
{
CGPoint location = [sender translationInView:sender.view];
NSLog(#"%f", location);
[sender setTranslation:CGPointZero inView:sender.view];
}
In the code posted above, you don't call setupGesture. This way your cell won't pick up the gestures. Also, you should just add create and add panRecognizer to the cell in tableview:cellForRowAtIndexpath: like so:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *nibName = #"Cell";
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:nibName];
UIPanGestureRecognizer* panRecognizer = [[UIPanGestureRecognizer alloc]initWithTarget:self action:#selector(panAction:)];
[cell addGestureRecognizer:panRecognizer];
return cell;
}
This one has me thrown and I'm wondering if anyone can help. I am trying to display a shadow on my selected UITableViewCell and it works fine on the Simulator but not on my iPad 3rd Gen running iOS 7.0.4
I have a subclassed UITableViewCell which is alloc/initting a subclassed UIView as its selectedBackground. All works fine other than it not displaying on the Device.
In my subclassed UITableViewCell...
- (void)awakeFromNib
{
self.selectedBackgroundView = [[OTHD_CellSelectedView alloc] initWithFrame:self.bounds];
}
And in my OTHD_CellSelectedView...
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self createLayer];
}
return self;
}
- (void) createLayer
{
CALayer *the_layer = [CALayer layer];
[self.layer insertSublayer:the_layer atIndex:0];
the_layer.frame = self.bounds;
the_layer.backgroundColor = [[UIColor whiteColor] CGColor];
the_layer.shadowColor = [UIColor blackColor].CGColor;
the_layer.shadowOffset = CGSizeMake(0, 0);
the_layer.shadowRadius = 10.0;
the_layer.shadowOpacity = 0.7;
}
I think you should bringToFront the cell in Table I have tried this and it is working for me... I hope this will help you:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 10;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell"];
if (!cell)
{
cell = [[UITableViewCell alloc] initWithStyle:(UITableViewCellStyleDefault) reuseIdentifier:#"Cell"];
}
if (indexPath.row == selected)
{
cell.layer.backgroundColor = [[UIColor whiteColor] CGColor];
cell.layer.shadowColor = [UIColor blackColor].CGColor;
cell.layer.shadowOffset = CGSizeMake(0, 0);
cell.layer.shadowRadius = 10.0;
cell.layer.shadowOpacity = 0.7;
[cell.superview bringSubviewToFront:cell];
}
else
{
cell.layer.shadowOpacity = 0;
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
selected = indexPath.row;
[tableView reloadData];
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:(UITableViewRowAnimationNone)];
}
There is a custom cell. In it there is two labels. One of them called nameLabel's height has to change dynamically. It can be 1,2 or 3 lines sometimes. But the rows are on eachother, they cross their own row lines. How can I solve this problem?
The labels and Custom Cell object's Use Autolayout option is disabled.
The label height has to change dynamic, And then the CustomCell's. And then tableRow. My head is confused. And why can't I see CustomCell's background color is changing?
Thanks
Here is my code for :
- (CGFloat)tableView:(UITableView *)tableView
heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
UILabel *label = [[UILabel alloc] init];
label.numberOfLines = 0; // allows label to have as many lines as needed
label.text = [[self.dataList objectAtIndex:indexPath.row] objectForKey:#"NAME"];
CGSize labelSize = [label.text sizeWithFont:label.font constrainedToSize:CGSizeMake(320, 63) lineBreakMode:NSLineBreakByWordWrapping];
CGFloat h = labelSize.height;
NSInteger x=0.0;
if (h==63.0) x=30;
if (h==42.0) x=20;
if (h==21.0) x=10;
return h+30;
}
- (UITableViewCell*)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellID = #"cellid";
CustomCell *cell = (CustomCell*)[tableView dequeueReusableCellWithIdentifier:cellID];
if (cell == nil)
{
cell = (CustomCell*)[[[NSBundle mainBundle]
loadNibNamed:#"CustomCell" owner:nil options:nil]
lastObject];
}
// customization
NSDictionary *d = [self.dataList objectAtIndex:indexPath.row];
cell.nameLabel.text = [d objectForKey:#"NAME"];
cell.cityLabel.text = [d objectForKey:#"CODE"];
cell.indexPath = indexPath;
return cell;
}
At this link there is picture of simulator and xib of the Custom Cell to understand easy the problem:
http://compfreek.wordpress.com/2013/08/14/custom-cell-for-table-row-height-changes-dynamic/
Hear is another way try this change according to ur code it may different, but it may solve your problem.I am putting all views through code only, because it is easy for me check this out.
//in your subclassed class
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
//may be u did same i am adding the label to cell
UILabel *nameLabel = [[UILabel alloc]initWithFrame:CGRectZero];
nameLabel.numberOfLines = 5; //set number of lines
nameLabel.tag = 100;
[self addSubview:nameLabel];
UILabel *otherLabel = [[UILabel alloc] initWithFrame:CGRectZero];
otherLabel.tag = 200;
[self addSubview:otherLabel];
}
return self;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
//do your customisation when cell is selected
}
-(void)layoutSubviews
{
//in this method i am setting the frames for label
[super layoutSubviews];
UILabel *nameLabel = (UILabel *) [self viewWithTag:100];
nameLabel.text = self.nameString;
CGSize maxSize = CGSizeMake(self.bounds.size.width / 2, MAXFLOAT);//set max height
CGSize nameSize = [self.nameString sizeWithFont:[UIFont systemFontOfSize:17]
constrainedToSize:maxSize
lineBreakMode:NSLineBreakByWordWrapping];
nameLabel.frame = CGRectMake(self.bounds.origin.x +2,self.bounds.origin.y+3, nameSize.width, nameSize.height);
UILabel *otherLabel = (UILabel *) [self viewWithTag:200];
otherLabel.frame = CGRectMake(nameLabel.frame.size.width+15,self.bounds.origin.y+3, 100, 40);
otherLabel.text = self.otherString;
}
//in your main class
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:#"CustomCell"];
if(cell == nil)
{
cell = [[[CustomCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"CustomCell"]autorelease];
}
//change it for ur need
NSString *name = #"hear is your long length name uzamaki naruto from uzamaki clan";
NSString *other = #"other name";
cell.nameString = name;
cell.otherString = other;
return cell;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *name = #"hear is your long length name uzamaki naruto from uzamaki clan";
//replace it your height logic
float cellWidth = 350; // ur cell width
CGSize maxSize = CGSizeMake( cellWidth / 2, MAXFLOAT);//set max height
CGSize nameSize = [name sizeWithFont:[UIFont systemFontOfSize:17]
constrainedToSize:maxSize
lineBreakMode:NSLineBreakByWordWrapping];
return nameSize.height + 10;// for ur height
}
in iOS5.0 I'm trying to instantiate a subclassed uitableviewcell programatically with initwithstyle. the code I'm using is below. When I instantiate using UITableViewCell alloc... i get the table separators, but when I do so using thumbCell alloc, the table row separator lines do not appear, the text that I setup in the thumbCell does not appear.. and the screen appears all white.. Pls help me understand what am I doing wrong..
In my ViewController
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *identifier = #"GroupCell";
thumbCell *cell = [self.testTableView dequeueReusableCellWithIdentifier:identifier];
//UITableViewCell *cell = [self.testTableView dequeueReusableCellWithIdentifier:identifier]; (this works)
if(!cell) {
cell = [[thumbCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
//cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];(this works)
}
[cell.textLabel setText:#"test"];
return cell;
}
and in thumbCell subclass
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
[self.textLabel setText:#"thumbCell"];
}
return self;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *identifier = #"GroupCell";
thumbCell *cell = [self.testTableView dequeueReusableCellWithIdentifier:identifier];
//UITableViewCell *cell = [self.testTableView dequeueReusableCellWithIdentifier:identifier]; (this works)
if(!cell) {
cell = [[thumbCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
//cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];(this works)
}
NSInteger sectionRows = [tableView numberOfRowsInSection:[indexPath section]];
NSInteger row = indexPath.row;
[cell setCellBackground:sectionRows:row];
[cell.textLabel setText:#"test"];
return cell;
}
In thumbCell class (custom cell class)
-(void)setCellBackground:(NSInteger)sectionRows:(NSInteger)row
{
UIImage *rowBackground;
UIImage *selectionBackground;
if (row == 0 && row == sectionRows - 1)
{
rowBackground = [UIImage imageNamed:#"topAndBottomRow.png"];
selectionBackground = [UIImage imageNamed:#"topAndBottomRowSelected.png"];
}
else if (row == 0)
{
rowBackground = [UIImage imageNamed:#"topRow.png"];
selectionBackground = [UIImage imageNamed:#"topRowSelected.png"];
}
else if (row == sectionRows - 1)
{
rowBackground = [UIImage imageNamed:#"bottomRow.png"];
selectionBackground = [UIImage imageNamed:#"bottomRowSelected.png"];
}
else
{
rowBackground = [UIImage imageNamed:#"middleRow.png"];
selectionBackground = [UIImage imageNamed:#"middleRowSelected.png"];
}
((UIImageView *)self.backgroundView).image = rowBackground;
((UIImageView *)self.selectedBackgroundView).image = selectionBackground;
}