I have problem with a UITableview, I'm fetching some data and displaying it in a custom cell views, almost everything is going well except two issues :
When I scroll down, some new cells show content from previous cells (especially the TextView cellText)
sometime the app crashes with [UIImageView setText:]: unrecognized selector sent to instance at line :
[cellText setText:postText];
Here is my cellForRowAtIndexPath method :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *PostCellIdentifier;
Post *info = [posts objectAtIndex:indexPath.row];
NSString *PostType = info.type;
if([PostType isEqualToString:#"quote"]) {
PostCellIdentifier = #"NewsQuoteCell";
} else if([PostType isEqualToString:#"article"]) {
PostCellIdentifier = #"NewsArticleCell";
} else if([PostType isEqualToString:#"picture"]) {
PostCellIdentifier = #"NewsPictureCell";
} else if([PostType isEqualToString:#"video"]) {
PostCellIdentifier = #"NewsVideoCell";
} else if([PostType isEqualToString:#"audio"]) {
PostCellIdentifier = #"NewsAudioCell";
}
NewsQuoteCell *cell = [tableView dequeueReusableCellWithIdentifier:PostCellIdentifier];
if (cell == nil) {
cell = [[NewsQuoteCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:PostCellIdentifier];
}
UILabel *cellLabel = (UILabel *)[cell.contentView viewWithTag:1];
[cellLabel setText:info.masjid_name];
UILabel *cellDate = (UILabel *)[cell.contentView viewWithTag:2];
[cellDate setText:info.date];
UITextView *cellText = (UITextView *)[cell.contentView viewWithTag:5];
NSString *postText = info.title;
[postText stringByDecodingHTMLEntities];
if ([postText length] > 300) {
postText = [postText substringToIndex:300];
postText = [postText stringByAppendingString:#"..."];
}
[cellText setText:postText];
CGRect frame = cellText.frame;
frame.size.height = cellText.contentSize.height;
cellText.frame = frame;
UIImageView *cellImage = (UIImageView *)[cell.contentView viewWithTag:3];
NSString *imagePath = info.masjid_thumb;
[cellImage setImage:[UIImage imageNamed:[NSString stringWithFormat:#"%#", imagePath]]];
cell.backgroundView = [ [UIImageView alloc] initWithImage:[ [UIImage imageNamed:#"news_bg"] resizableImageWithCapInsets:UIEdgeInsetsMake(10, 0, 10, 0)] ];
cell.selectedBackgroundView = [ [UIImageView alloc] initWithImage:[ [UIImage imageNamed:#"news_bg"] resizableImageWithCapInsets:UIEdgeInsetsMake(10, 0, 10, 0)] ];
if([PostType isEqualToString:#"article"]) {
cellText.userInteractionEnabled = YES;
UITapGestureRecognizer *pgrText = [[UITapGestureRecognizer alloc]
initWithTarget:self action:#selector(handleTapArticle:)];
[cellText setTag:indexPath.row];
[cellText addGestureRecognizer:pgrText];
UIImageView *cellMedia = (UIImageView *)[cell.contentView viewWithTag:10];
cellMedia.userInteractionEnabled = YES;
UITapGestureRecognizer *pgr = [[UITapGestureRecognizer alloc]
initWithTarget:self action:#selector(handleTapArticle:)];
[cellMedia setTag:indexPath.row];
[cellMedia addGestureRecognizer:pgr];
} else if ([PostType isEqualToString:#"video"]) {
cellText.userInteractionEnabled = YES;
UITapGestureRecognizer *pgrText = [[UITapGestureRecognizer alloc]
initWithTarget:self action:#selector(handleTap:)];
[cellText setTag:indexPath.row];
[cellText addGestureRecognizer:pgrText];
UIImageView *cellMedia = (UIImageView *)[cell.contentView viewWithTag:10];
cellMedia.userInteractionEnabled = YES;
UITapGestureRecognizer *pgr = [[UITapGestureRecognizer alloc]
initWithTarget:self action:#selector(handleTap:)];
[cellMedia setTag:indexPath.row];
[cellMedia addGestureRecognizer:pgr];
} else if ([PostType isEqualToString:#"audio"]) {
cellText.userInteractionEnabled = YES;
UITapGestureRecognizer *pgrText = [[UITapGestureRecognizer alloc]
initWithTarget:self action:#selector(handleTap:)];
[cellText setTag:indexPath.row];
[cellText addGestureRecognizer:pgrText];
UIImageView *cellMedia = (UIImageView *)[cell.contentView viewWithTag:10];
cellMedia.userInteractionEnabled = YES;
UITapGestureRecognizer *pgr = [[UITapGestureRecognizer alloc]
initWithTarget:self action:#selector(handleTap:)];
[cellMedia setTag:indexPath.row];
[cellMedia addGestureRecognizer:pgr];
} else if ([PostType isEqualToString:#"picture"]) {
cellText.layer.shadowColor = [[UIColor blackColor] CGColor];
cellText.layer.shadowOffset = CGSizeMake(1.0f, 1.0f);
cellText.layer.shadowOpacity = 0.5f;
cellText.layer.shadowRadius = 0.5f;
UIImageView *cellMedia = (UIImageView *)[cell.contentView viewWithTag:7];
NSString *mediaPath = info.media;
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:mediaPath]];
AFImageRequestOperation *operation = [AFImageRequestOperation imageRequestOperationWithRequest:request success:^(UIImage *image) {
UIImage* scaled2 = [image scaleToFitSize:(CGSize){284, 284}];
[cellMedia setImage:scaled2];
CGRect frame1 = cellMedia.frame;
frame1.size.width = 284;
frame1.size.height = scaled2.size.height;
cellMedia.frame = frame1;
}];
[operation start];
cellMedia.userInteractionEnabled = YES;
UITapGestureRecognizer *pgr = [[UITapGestureRecognizer alloc]
initWithTarget:self action:#selector(handleTapPicture:)];
[cellMedia setTag:indexPath.row];
[cellMedia addGestureRecognizer:pgr];
if ([postText length] > 300) {
postText = [postText substringToIndex:300];
postText = [postText stringByAppendingString:#"..."];
}
[cellText setText:postText];
CGRect frame = cellText.frame;
frame.size.height = cellText.contentSize.height;
frame.origin.y = cellMedia.frame.origin.y + (cellMedia.frame.size.height - cellText.contentSize.height);
cellText.frame = frame;
}
return cell;
}
Any help please ?
It looks like you have a subclass of UITableViewCell called NewsQuoteCell. You can override the prepareForReuse method in the NewsQuoteCell class to fix your new cell shows content of previous cell issue. The other issue seemed to have to do with the your tag for view number 5 was not a UITextView but a UIImageView. I would double check your NewsQuoteCell's implementation file.
I assume you have created NewsQuoteCell in a seperate nib file. If thats the case why dont you setup proper IBOutlets to bind different components like the cellLabel, cellDate, cellText etc. That way you don't have to retrieve these components using viewWithTag.
And you are probably doing something funny with the tag. Have you setup the tags properly? One definite problem is your second error message. You are retrieving a UIImageView with the viewWithTag call and referencing it with UITextView. Make sure that tags are set up properly. And it never hurts to set the tag values to something unique, like 101, 102,103... etc.
Hope this helps.
Related
I'm adding the same selector for multiple UIButtons which are part of a UITableViewCell and it works only for the first one. Am I missing something?
Here's my code:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
NSDictionary *d = [tableData objectAtIndex:indexPath.row];
NSArray *answers = [d objectForKey:#"answers"];//array of { id = 35; text = "\U03c4\U03a\U03c0\U03bf\U03c4\U03b1"; }
UILabel *startDate = (UILabel *)[cell viewWithTag:100];
long long startDateEpoch = [[d objectForKey:#"startDate"] longLongValue];
NSDate *sDate = [NSDate dateWithTimeIntervalSince1970:startDateEpoch/1000];
NSDateFormatter *startDateFormatter = [[NSDateFormatter alloc] init];
[startDateFormatter setDateFormat:#"dd/MM/yyyy"];
startDate.text = [startDateFormatter stringFromDate:sDate];
((UILabel *)[cell viewWithTag:101]).text = [d objectForKey:#"subject"];
NSArray *tags = [d objectForKey:#"tags"];
((UILabel *)[cell viewWithTag:102]).text = [tags componentsJoinedByString:#" "];
NSString *imageURL = [d objectForKey:#"media"];
UIImageView *iv = (UIImageView *)[cell viewWithTag:103];
iv.contentMode = UIViewContentModeScaleAspectFit;
[iv sd_setImageWithURL:[NSURL URLWithString:imageURL]
placeholderImage:[UIImage imageNamed:#"placeholder.png"]];
UIView *buttonsContainer = (UIView *)[cell viewWithTag:104];
for(UIView *vv in buttonsContainer.subviews){
[vv removeFromSuperview];
}
int index = 0;
NSLog(#"buttonsContainer children: %d", buttonsContainer.subviews.count);
for(NSDictionary *answer in answers){
UIView *v = [[UIView alloc] initWithFrame:CGRectMake(0, index * 40 + (index+1)*5, [UIScreen mainScreen].bounds.size.width, 40)];
v.backgroundColor = [UIColor whiteColor];
CGRect labelFrame = v.frame;
labelFrame.origin.y = 0;
UILabel *l = [[UILabel alloc] initWithFrame:labelFrame];
l.text = (NSString *)[answer objectForKey:#"text"];
l.textAlignment = NSTextAlignmentCenter;
UIView *bottomLine = [[UIView alloc] initWithFrame:CGRectMake(0, v.frame.size.height - 1, v.frame.size.width, 1)];
bottomLine.backgroundColor = [UIColor colorWithRed:238.0/255.0 green:205.0/255.0 blue:103.0/255.0 alpha:1.0];
UIButton *b = [[UIButton alloc] initWithFrame:v.frame];
[b addTarget:self action:#selector(answered:) forControlEvents:UIControlEventTouchUpInside];
[v addSubview:l];
[v addSubview:bottomLine];
[v addSubview:b];
[buttonsContainer addSubview:v];
index++;
}
}
So for example if 4 buttons are added, the selector is called only when I click on the first one. When I click on the other three nothing happens.
EDIT:
adding the answered: code:
- (void)answered:(UIButton *)sender
{
NSLog(#"#answered");
}
ok, I found it. Many cudos to TomSwift since his point gave me the idea to place borders on all the views in order to debug their frames size and origin.
Notice that I give to my buttons the same frame as their superviews, which is wrong since they should not have the same origin. The buttons' origin should be 0,0 since they have the same frame size as their superviews.
lessons learn for noobs like me:
When a button does not work, place borders in order to make sure their frame is within the superview's bounds.
Do not assign the same frame on a view and its subview. It will place it outside of the superview's bounds which in 92% of the cases brings undesirable behaviour.
I have UITableView in my iOS app and I want to add some subviews to cell. I do it by using
[cell.contentView addSubview:someView];
and it works well, but... When I scroll down, subviews are starting to hide from cells that are on top and when I scroll back to top, they wont appear again... What I'm doing wrong? Is there some solution please?
EDIT
Mainly, I'm talking about "detailtext" label, but I have those problems in more cases...
Here is whole code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell;
switch (indexPath.row) {
case 0:
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
break;
default:
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
break;
}
UIView *separatorLine = [[UIView alloc] init];
separatorLine.frame = CGRectMake(15.0f, 60 - 0.5f, cell.frame.size.width-15.0f, 0.5f);
separatorLine.tag = 4;
separatorLine.backgroundColor = [UIColor lightGrayColor];
cell.layer.masksToBounds = NO;
tableView.backgroundColor = [UIColor colorWithRed:33.0 / 255.0 green:157.0 / 255.0 blue:147.0 / 255.0 alpha:1.0];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
UIView *row2 = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 200)];
UIView *profileBorder = [[UIView alloc] initWithFrame:CGRectMake(self.view.frame.size.width/2-50, 50, 102, 102)];
profileBorder.layer.borderColor = [UIColor whiteColor].CGColor;
profileBorder.layer.borderWidth = 5; //2
profileBorder.layer.cornerRadius = 50;
NZCircularImageView *profileImage = [[NZCircularImageView alloc] initWithFrame:CGRectMake(1,1, 100, 100)];
profileImage.image = profilePhoto;
profileImage.contentMode = UIViewContentModeScaleAspectFill;
UITapGestureRecognizer *showBigProfilePhoto = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(showImage:)];
profileImage.userInteractionEnabled = YES;
[profileImage addGestureRecognizer:showBigProfilePhoto];
[profileBorder addSubview:profileImage];
UILabel *numberFeelings = [[UILabel alloc] initWithFrame:CGRectMake(10, 100-25, 100, 50)];
numberFeelings.text = [NSString stringWithFormat:#"%#\nFeelings", feelings];
numberFeelings.font = [UIFont boldSystemFontOfSize:16];
numberFeelings.textAlignment = NSTextAlignmentCenter;
numberFeelings.textColor = [UIColor whiteColor];
numberFeelings.numberOfLines = 0;
UILabel *numberFriends = [[UILabel alloc] initWithFrame:CGRectMake(self.view.frame.size.width/2+60, 100-25, 100, 50)];
numberFriends.text = [NSString stringWithFormat:#"%#\nFollowers", friends];
numberFriends.font = [UIFont boldSystemFontOfSize:16];
numberFriends.textColor = [UIColor whiteColor];
numberFriends.numberOfLines = 0;
numberFriends.textAlignment = NSTextAlignmentCenter;
[row2 addSubview:profileBorder];
[row2 addSubview:numberFriends];
[row2 addSubview:numberFeelings];
int rectButtons = cell.frame.size.width-246;
UIImageView *graph = [[UIImageView alloc] initWithFrame:CGRectMake(rectButtons/2, -20, 82, 82)];
UIImageView *badgets = [[UIImageView alloc] initWithFrame:CGRectMake(rectButtons/2+82, -20, 82, 82)];
UIImageView *photos = [[UIImageView alloc] initWithFrame:CGRectMake(rectButtons/2+164, -20, 82, 82)];
graph.image = [UIImage imageNamed:#"graph.jpg"];
badgets.image = [UIImage imageNamed:#"badgets.jpg"];
photos.image = [UIImage imageNamed:#"photos.jpg"];
graph.userInteractionEnabled = YES;
badgets.userInteractionEnabled = YES;
photos.userInteractionEnabled = YES;
UITapGestureRecognizer *graphTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(showGraph:)];
[graph addGestureRecognizer:graphTap];
NSArray *jmenoCasti = [name componentsSeparatedByString:#" "];
krestni = [jmenoCasti objectAtIndex:0];
int indexOfPost = indexPath.row-3;
NSMutableAttributedString *str;
int countFeeling;
int countString;
int countBeforeFeeling;
if (indexPath.row >=3) {
str = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:#"%# was %#", krestni, [naladyHim objectAtIndex:[[[posts objectAtIndex:indexOfPost] objectForKey:#"_feel"] integerValue]]]];
countFeeling = [[naladyHim objectAtIndex:[[[posts objectAtIndex:indexOfPost] objectForKey:#"_feel"] integerValue]] length];
countString = krestni.length+5+countFeeling;
countBeforeFeeling = countString-countFeeling+1;
int rangeStart = countBeforeFeeling-1;
int rangeStop = str.length-rangeStart;
NSLog(#"%i ... %i", countBeforeFeeling-1, countString-1);
[str addAttribute:NSFontAttributeName value: [UIFont fontWithName:#"Helvetica-Bold" size:16.0f] range:NSMakeRange(rangeStart, rangeStop)];
[str addAttribute:NSForegroundColorAttributeName value:[UIColor colorWithRed:32.0 / 255.0 green:147.0 / 255.0 blue:138.0 / 255.0 alpha:1.0] range:NSMakeRange(rangeStart, rangeStop)];
}
UILabel *mainText = [[UILabel alloc] initWithFrame:CGRectMake(15, 70, cell.frame.size.width-10, 20)];
mainText.attributedText = str;
UILabel *detailText;
if (!detailText) {
detailText = [[UILabel alloc] initWithFrame:CGRectMake(15, 90, cell.frame.size.width-10, 30)];
}
detailText.textColor = [UIColor grayColor];
detailText.font = [UIFont systemFontOfSize:13];
switch (indexPath.row) {
case 0:
cell.textLabel.textAlignment = NSTextAlignmentCenter;
cell.textLabel.text = name;
cell.textLabel.textColor = [UIColor whiteColor];
cell.textLabel.font = [UIFont systemFontOfSize:20];
cell.backgroundColor = [UIColor clearColor];
break;
case 1:
[cell.contentView addSubview:row2];
cell.backgroundColor = [UIColor clearColor];
break;
case 2:
cell.backgroundColor = [UIColor colorWithRed:236.0 / 255.0 green:235.0 / 255.0 blue:210.0 / 255.0 alpha:1.0];
[cell.contentView addSubview:graph];
[cell.contentView addSubview:badgets];
[cell.contentView addSubview:photos];
break;
default:
detailText.text = [[posts objectAtIndex:indexPath.row-3] objectForKey:#"_text"];
[cell.contentView addSubview:detailText];
cell.textLabel.attributedText = str;
cell.backgroundColor = [UIColor colorWithRed:236.0 / 255.0 green:235.0 / 255.0 blue:210.0 / 255.0 alpha:1.0];
break;
}
return cell; }
This is an easy way thats works for me:
for(UIView *subview in cell.contentView.subviews)
{
if([subview isKindOfClass: [UIView class]])
{
[subview removeFromSuperview];
}
}
You can use it at the begin of
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
In your tableView:cellForRowAtIndexPath:, you hide the info when you don't want it to be shown, but you don't explicitly unhide it for cells where it should be shown.
Look at the first two lines in that method: What you are - correctly - doing is reusing your cells, so when cells are scrolled out of view, they are removed from the UITableView and put into the reuse queue. Then, when cells should become visible, the TableView gets cells from that queue - or creates new ones if none are available.
This all goes very well, but after a while, cells with hidden info buttons are put on the queue. And then, some time later, those cells are reused - and sometimes for rows in which there should be info visible.
There are two solutions to this: You could either explicitly unhide the information for those rows where you want it to be shown, or you could use two different kinds of cell, one with hidden info, and one with visible info. You then give each of those cells a different identifier, and based on what row the cells are in, set the identifier before dequeuing/creating cells.
You should create a subclass of UITableViewCell for each different cell and add all your view related code that doesn't change depending on the data into an initialization method. Then create a method in each cell called something like configureWithData and pass in the data relevant to the cell. The creation of your attributed string and modification of label frames can occur in this configuration method.
It will dramatically reduce the clutter in your UITableViewController and is much better design wise. There is no real need for your view controller to know what your table cells look like.
Here is an example of what I am talking about:
-(void)awakeFromNib
{
if( self.accessoryType == UITableViewCellAccessoryDisclosureIndicator )
{
DTCustomColoredAccessory *accessory = [DTCustomColoredAccessory accessoryWithColor:[UIColor whiteColor]];
accessory.highlightedColor = [UIColor blackColor];
self.accessoryView = accessory;
}
}
-(void)configureCellWithObject:(id)inObject
{
TableDataModel *dataObject = (TableDataModel *)inObject;
self.titleLabel.text = dataObject.titleString;
self.subtitleLabel.text = dataObject.subtitleString;
self.accessibilityIdentifier = dataObject.accessIdString;
if( dataObject.imageUrlString != nil )
{
UIImage *iconImage = [UIImage imageNamed:dataObject.imageUrlString];
if( iconImage != nil )
{
NSInteger yOffset = [StaticTools centerYOffset:self.frame.size objectFrameSize:iconImage.size];
self.iconImageView.image = iconImage;
CGRect frame = self.iconImageView.frame;
frame.origin.y = yOffset;
frame.size = iconImage.size;
[self.iconImageView setFrame:frame];
}
else
{
[self.iconImageView loadImageFromUrl:dataObject.imageUrlString];
}
}
}
The problem I encounter is that whenever a row goes out of view, the scroll has a very fast and short lag.
This is my code:
- (UICollectionViewCell *)collectionView:(UICollectionView *)_collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = [self.collView dequeueReusableCellWithReuseIdentifier:#"cell" forIndexPath:indexPath];
Saints *note = nil;
int aX=0;
int aY=0;
note = [self.fetchedResultsController objectAtIndexPath:indexPath];
for (UIView *view in cell.contentView.subviews) {
if([view isKindOfClass:[UIImageView class]])
{
[view removeFromSuperview];
}
else if([view isKindOfClass:[UILabel class]])
{
[view removeFromSuperview];
}}
cell.backgroundColor = [UIColor clearColor];
UIImage *imgbackground = [UIImage imageNamed:#"today-left-side-images-bg.png"];
NSArray *messages = [[NSArray alloc] initWithObjects: #"random-saint-text-bg-brown.png",#"random-saint-text-bg-brightblue.png",#"random-saint-text-bg-green.png",#"random-saint-text-bg-grey.png",#"random-saint-text-bg-lightblue.png",#"random-saint-text-bg-lime.png",#"random-saint-text-bg-purple.png",#"random-saint-text-bg-red.png",#"random-saint-text-bg-teal.png",nil];
int randNum = arc4random() % [messages count];
NSString *returnValue = [messages objectAtIndex:randNum];
NSString *rndBGImg= returnValue;
UIImage *imgbackgroundlower = [UIImage imageNamed:rndBGImg];
UIImageView *imgViewlower = [[UIImageView alloc] initWithImage:imgbackgroundlower];
//imgViewlower.frame=CGRectMake(aX, aY+140, 140,73);
imgViewlower.frame=CGRectMake(aX+4, aY+114, 119,43);
UIImageView *imgView = [[UIImageView alloc] initWithImage:imgbackground];
imgView.frame=CGRectMake(aX, aY, 127,162);
UIImageView *imgSaintPic = [[UIImageView alloc]init];
imgSaintPic.tag=1;
imgSaintPic.frame=CGRectMake(aX+6, aY+6, 114,145);
//NSString *imgname = [aDic objectForKey:#"saint_image"];
NSString *imgname = note.saint_imagethumbnail;
UIImage *tempimg= [UIImage imageNamed:imgname];
[imgSaintPic setImage:tempimg];
UILabel *lblNamelocal=[[UILabel alloc]init];
NSString *strSaintName=note.saint_name;
//lblNamelocal.text=strSaintName;
if([note.saint_title length]>1)
lblNamelocal.text=[NSString stringWithFormat:#"%# %#",note.saint_title,strSaintName];
else
lblNamelocal.text=[NSString stringWithFormat:#"%#",strSaintName];
//lblNamelocal.frame = CGRectMake(aX+6, aY+109, 116,30);
[lblNamelocal sizeToFit];
lblNamelocal.frame = CGRectMake(aX+5, aY+115, 118,26);
lblNamelocal.lineBreakMode = UILineBreakModeWordWrap;
lblNamelocal.numberOfLines = 0;
lblNamelocal.backgroundColor = [UIColor clearColor];
lblNamelocal.textColor = [UIColor whiteColor];
lblNamelocal.font = [UIFont fontWithName:#"HelveticaNeue-CondensedBold" size:11 ];
// lblNamelocal.textAlignment=UITextAlignmentLeft;
lblNamelocal.baselineAdjustment = UIBaselineAdjustmentAlignCenters;
lblNamelocal.shadowColor = [UIColor darkGrayColor];
lblNamelocal.shadowOffset = CGSizeMake(0,0.5);
lblNamelocal.textAlignment = UITextAlignmentCenter;
UILabel *lblsubtitle=[[UILabel alloc]init];
//NSString *strSaintSubtitle=[aDic objectForKey:#"saint_title"];
lblsubtitle.text=note.saint_subtitle;
//lblsubtitle.frame = CGRectMake(aX+6, aY+132, 116, 25);
lblsubtitle.frame = CGRectMake(aX+5, aY+140, 113, 20);
lblsubtitle.lineBreakMode = UILineBreakModeWordWrap;
lblsubtitle.numberOfLines = 2;
lblsubtitle.backgroundColor = [UIColor clearColor];
lblsubtitle.textColor = [UIColor whiteColor];
lblsubtitle.font = [UIFont fontWithName:#"HelveticaNeue" size:10];
// Removed CJamesRun lblsubtitle.textAlignment=UITextAlignmentLeft;
lblsubtitle.shadowColor = [UIColor darkGrayColor];
lblsubtitle.shadowOffset = CGSizeMake(0,0.5);
lblsubtitle.textAlignment = UITextAlignmentCenter;
imgViewlower.tag=3;
lblNamelocal.tag=2;
lblsubtitle.tag=4;
[cell.contentView addSubview:imgView];
[cell.contentView addSubview:imgSaintPic];
[cell.contentView addSubview:imgViewlower];
[cell.contentView addSubview:lblNamelocal];
[cell.contentView addSubview:lblsubtitle];
// cell.layer.masksToBounds = NO;
cell.layer.shouldRasterize = YES;
cell.layer.rasterizationScale = [UIScreen mainScreen].scale;
return cell;
}
What I've tired is to rasterize the cell layer, and also to remove the views from the SuperView upon creating a new cell.
Any other suggestions?
I would recommend setting up your cells' subviews just once, and then only updating the contents inside collectionView:cellForItemAtIndexPath:. E.g. you're loading some images in each cell, but those are the same for every cell, so loading them every time the cell is reused is unnecessary.
I am pretty new to Xcode and this simple problem has been driving me mad! I have created an expandable table that works fine. This is some of the code on a UIView subclass for the section that expands when you tap on a cell:
- (id)initWithFrame:(CGRect)frame WithTitle: (NSString *) title Section:(NSInteger)sectionNumber delegate: (id <SectionView>) Delegate
{
self = [super initWithFrame:frame];
if (self) {
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(discButtonPressed:)];
[self addGestureRecognizer:tapGesture];
self.userInteractionEnabled = YES;
self.section = sectionNumber;
self.delegate = Delegate;
CGRect LabelFrame = CGRectMake(100, 100, 100, 100);
LabelFrame.size.width -= 100;
CGRectInset(LabelFrame, 1.0, 1.0);
//BUTTON
CGRect buttonFrame = CGRectMake(LabelFrame.size.width, 0, 100, LabelFrame.size.height);
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = buttonFrame;
//[button setImage:[UIImage imageNamed:#"carat.png"] forState:UIControlStateNormal];
//[button setImage:[UIImage imageNamed:#"carat-open.png"] forState:UIControlStateSelected];
[button addTarget:self action:#selector(discButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:button];
self.discButton = button;
//My IMAGE
NSString *imageName = #"gradient1.png";
UIImage *myImage = [UIImage imageNamed:imageName];
UIImageView *sectionHeaderView = [[UIImageView alloc] initWithImage:myImage];
UIImageView *imageView = [[UIImageView alloc] initWithImage:myImage];
imageView.frame = CGRectMake(20,50,100,100);
[self addSubview:sectionHeaderView];
self.headerBG = sectionHeaderView;
//HEADER LABEL
UILabel *label = [[UILabel alloc] initWithFrame: CGRectMake(22, 12, sectionHeaderView.frame.size.width, 35.0)];
label.textAlignment = NSTextAlignmentLeft;
label.backgroundColor = [UIColor clearColor];
label.textColor = [UIColor whiteColor];
label.shadowColor = [UIColor darkGrayColor];
label.shadowOffset = CGSizeMake(0.0, -1.0);
label.text = title;
label.font = [UIFont fontWithName:#"AvenirNext-Bold" size:20.0];
sectionHeaderView.backgroundColor = [UIColor clearColor];
//label.textAlignment = UITextAlignmentLeft;
[self addSubview:label];
self.sectionTitle = label;
}
return self;
}
I have a custom image on the cell #"gradient1.png" but I don't seem to be able to resize it? Here is the header code in the UITableViewController:
- (UIView *) tableView:(UITableView *)tableView viewForHeaderInSection: (NSInteger)section
{
SectionInfo *array = [self.sectionInfoArray objectAtIndex:section];
if (!array.sectionView)
{
NSString *title = array.category.name;
array.sectionView = [[SectionView alloc] initWithFrame:CGRectMake(0, 10, self.tableView.bounds.size.width, 0) WithTitle:title Section:section delegate:self];
}
return array.sectionView;
}
Sorry if this is a trivial question, your help is greatly appreciated!
I don't see where you are trying to resize the image so I can't offer any help in why it is not resizing, but I found this confusing:
//My IMAGE
NSString *imageName = #"gradient1.png";
UIImage *myImage = [UIImage imageNamed:imageName];
UIImageView *sectionHeaderView = [[UIImageView alloc] initWithImage:myImage];
UIImageView *imageView = [[UIImageView alloc] initWithImage:myImage];
imageView.frame = CGRectMake(20,50,100,100);
[self addSubview:sectionHeaderView];
self.headerBG = sectionHeaderView;
In this part of code you create two imageviews, then you resize one and add the other to the cell (I'm assuming cell) subviews. Is it possible that you are trying to resize the view that you never added as a subview of the cell?
Also, resizing should happen inside - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath.
Make sure that you are resizing the proper view, ten make sure you are resizing it in the proper place.
So sometimes upon returning to my main menu for my game I am greeted by something quite extraordinary. As you can see from the picture I have replicated cells outside the UIView Table. Now at first I thought it was a graphics corruption that was based on memory issues, Then I discovered you could interact with them, they are valid cells...not ghost images and they respond to code, So I then did a little search and though that my table was stuck in editing mode or something so I call setediting:NO everywhere I could. And it haunts me still.
Does anyone even have the first idea what could be causing this? It does not happen all the time but it only ever seems to happen...IF it does when I am popping back to this screen from another view on top of it. I also can't replicate it consistently so it's hard to fix and know what is causing it.
Please keep in mind I might be doing something or not doing something I have not mentioned so don't forget to ask everything you may think relevant and I will be happy to inform you.
EDIT:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger) tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section
{
return [[[CurrentGamesInfo sharedCurrentGamesInfo] _currentGames] count];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
_indexPath = indexPath;
NSLog(#"%i",_indexPath.row);
[_indexPath retain];
[[CurrentGamesInfo sharedCurrentGamesInfo] SetCurrentGameWithIndex:[_indexPath row]];
UIView *tempView = [[[tableView cellForRowAtIndexPath:indexPath] contentView] viewWithTag:200];
if([[[(UIButton*)[tempView viewWithTag:CELL_BUTTONTEXT_ID] titleLabel] text] isEqualToString:#"Waiting"])
{
return;
}
if( ![[CurrentGamesInfo sharedCurrentGamesInfo] _selectedGame].isGameReady )
{
[_PopUp OptionsMessage:#"Game Not Ready" withTitle:#"Hold Your Horsies" hideBackButton:YES];
return;
}
NSString *gameID = [[[CurrentGamesInfo sharedCurrentGamesInfo] _selectedGame] GetGameID];
NSLog(#"%i",[[[CurrentGamesInfo sharedCurrentGamesInfo] _selectedGame] GetTurnNumber].intValue);
NSData *pngData = [NSData dataWithContentsOfFile:[AppDelegate applicationDocumentDirectory:gameID]];
UIImage *image = [UIImage imageWithData:pngData];
PhotoImage *photoImg = [[PhotoImage alloc]init];
[photoImg set_imageToSend:image];
[[[CurrentGamesInfo sharedCurrentGamesInfo] _selectedGame] SetImageToSend:photoImg];
[photoImg release];
UIImageView * imgView = (UIImageView*)[[[[tableView cellForRowAtIndexPath:indexPath] contentView]viewWithTag:300] viewWithTag:301];
[[[CurrentGamesInfo sharedCurrentGamesInfo]_selectedGame]setOpponentProfilePic:imgView.image];
[self TempCurrentGameFunction];
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
return UITableViewCellEditingStyleDelete;
}
WARNING: HEFTY FUNCTION INCOMING
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell;
GameInfo *gameThisRow = [[[CurrentGamesInfo sharedCurrentGamesInfo]_currentGames] objectAtIndex:indexPath.row];
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"MyIdentifier"] autorelease];
cell.selectionStyle = UITableViewCellSelectionStyleBlue;
NSLog(#"row : %i",indexPath.row);
NSLog(#"current game count : %i",[[[CurrentGamesInfo sharedCurrentGamesInfo] _currentGames]count]);
NSString *gameType = #"";
UIButton *gameStatusButton = [[UIButton alloc]initWithFrame:CGRectMake(100, -5, 90, 70)];
Boolean isYourTurn = [[gameThisRow GetPlayerRole] intValue] ? YES : NO;
NSString *gameStateString = #"Your Move";
[cell setUserInteractionEnabled:YES];
[cell setTag:ACTIVE_GAME_CELL];
if(!isYourTurn)
{
//_activeGameCount--;
gameStateString = #"Waiting";
[cell setUserInteractionEnabled:NO];
[cell setTag:INACTIVE_GAME_CELL];
}
[gameStatusButton setTitle:gameStateString forState:UIControlStateNormal];
[[gameStatusButton titleLabel] setFont:[UIFont fontWithName:#"Fredoka One" size:10]];
[gameStatusButton setTag:CELL_BUTTONTEXT_ID];
if( indexPath.row < [[[CurrentGamesInfo sharedCurrentGamesInfo] _currentGames]count])
{
switch ([gameThisRow gameType])
{
case 0:
gameType = #"Open Game";
[gameStatusButton setBackgroundImage:[UIImage imageNamed:#"buttonB_blue.png"] forState:UIControlStateNormal];
break;
case 1:
{
gameType = #"Challenge Game";
[gameStatusButton setBackgroundImage:[UIImage imageNamed:#"buttonB_orange.png"] forState:UIControlStateNormal];
}
break;
case 2:
{
gameType = #"Battle Game";
[gameStatusButton setBackgroundImage:[UIImage imageNamed:#"buttonB_pink.png"] forState:UIControlStateNormal];
}
break;
default:
break;
}
}
NSLog(#"%#",[[gameThisRow GetFaceBookData]objectForKey:#"name"]);
NSString *name = [[gameThisRow GetFaceBookData]objectForKey:#"name"];
UIView *labelView = [[UIView alloc] initWithFrame:CGRectMake(80, 10, 100, 50)];
[labelView setTag:200];
[labelView addSubview:gameStatusButton];
[gameStatusButton release];
[labelView setBackgroundColor:[UIColor clearColor]];
UILabel *labelName = [[UILabel alloc] initWithFrame:CGRectMake(0, 5, 100, 20)];
NSString *text = name;
NSArray *nameArray = [text componentsSeparatedByString:#" "];
NSString *nameWithInitials;
nameWithInitials = [NSString stringWithFormat:#"%#",[nameArray objectAtIndex:0]];
for( int i = 1; i < nameArray.count; ++i )
{
NSString *temp = [nameArray objectAtIndex:i];
nameWithInitials = [nameWithInitials stringByAppendingFormat:#" %C.",[temp characterAtIndex:0]];
}
text = nameWithInitials;
int maxSize = 20;
int minSize = 8;
UIFont *font = [UIFont fontWithName:#"Fredoka One"size:maxSize];
/* Time to calculate the needed font size.
This for loop starts at the largest font size, and decreases by two point sizes (i=i-2)
Until it either hits a size that will fit or hits the minimum size we want to allow (i > 10) */
for(int i = maxSize; i > minSize; i=i-2)
{
// Set the new font size.
font = [font fontWithSize:i];
// You can log the size you're trying: NSLog(#"Trying size: %u", i);
/* This step is important: We make a constraint box
using only the fixed WIDTH of the UILabel. The height will
be checked later. */
CGSize constraintSize = CGSizeMake([labelName frame].size.width, MAXFLOAT);
// This step checks how tall the label would be with the desired font.
CGSize labelSize = [text sizeWithFont:font constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap];
/* Here is where you use the height requirement!
Set the value in the if statement to the height of your UILabel
If the label fits into your required height, it will break the loop
and use that font size. */
if(labelSize.height <= [labelName bounds].size.height)
break;
}
// You can see what size the function is using by outputting: NSLog(#"Best size is: %u", i);
// Set the UILabel's font to the newly adjusted font.
[labelName setFont:font];
// Put the text into the UILabel outlet variable.
[labelName setText:text];
[labelName setTextColor:[UIColor grayColor]];
[labelName setBackgroundColor:[UIColor clearColor]];
[labelName setTextAlignment:UITextAlignmentCenter];
[labelView addSubview:labelName];
[labelName release];
UILabel *labelSubtitle = [[UILabel alloc] initWithFrame:CGRectMake(0, 20, 100, 50)];
[labelSubtitle setText:gameType];
[labelSubtitle setFont:[UIFont fontWithName:#"Fredoka One" size:10]];
[labelSubtitle setTextColor:[UIColor grayColor]];
[labelSubtitle setBackgroundColor:[UIColor clearColor]];
[labelSubtitle setTextAlignment:UITextAlignmentCenter];
[labelView addSubview:labelSubtitle];
[labelSubtitle release];
[[cell contentView] addSubview:labelView];
NSString *path = [NSString stringWithFormat:#"http://graph.facebook.com/%#/picture?width=200&height=200",[[gameThisRow GetFaceBookData]objectForKey:#"id"] ];
UIImageView *pictureImage = [[UIImageView alloc] init];
[pictureImage setImageWithURL:[NSURL URLWithString:path] placeholderImage:[UIImage imageNamed:#"Icon-Small.png"]success:^(UIImage *image)
{
pictureImage.image = [image imageScaledToSize:CGSizeMake(100, 100)];
} failure:^(NSError *error)
{
[pictureImage setImage:[[UIImage imageNamed:#"Icon-Small.png" ]imageScaledToSize:CGSizeMake(50, 50)]];
NSLog(#"%#",[error localizedDescription]);
}];
NSLog(#"%#",[pictureImage image]);
pictureImage.layer.masksToBounds = YES;
[pictureImage setFrame:CGRectMake(pictureImage.frame.origin.x+20, 37 - 25, 50, 50)];
UIImageView *pictureFrameView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"profile_frame.png"]];
CGRect temp = pictureImage.frame;
//hand & hard coded, i feel so ashamed and sullied
temp.origin.x -= 12;
temp.origin.y -= 9;
temp.size.width = 70;
temp.size.height = 73;
[pictureFrameView setFrame:temp];
UIView *pictureView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 80, 80)];
[pictureView addSubview:pictureFrameView];
[pictureView addSubview:pictureImage];
[pictureImage setTag:301];
[pictureFrameView release];
[pictureImage release];
[[cell contentView] addSubview:pictureView];
[pictureView setTag:300];
[pictureView release];
//custom stuff start
UIImage *rowBackground;
//UIImage *selectionBackground;
NSInteger sectionRows = [tableView numberOfRowsInSection:[indexPath section]];
NSInteger row = [indexPath row];
if (row == 0 && row == sectionRows - 1)
{
rowBackground = [UIImage imageNamed:#"table_bottom.png"];
//selectionBackground = [UIImage imageNamed:#"topAndBottomRowSelected.png"];
}
else if (row == 0)
{
rowBackground = [UIImage imageNamed:#"table_top.png"];
//selectionBackground = [UIImage imageNamed:#"topRowSelected.png"];
}
else if (row == sectionRows - 1)
{
rowBackground = [UIImage imageNamed:#"table_bottom.png"];
//selectionBackground = [UIImage imageNamed:#"bottomRowSelected.png"];
}
else
{
rowBackground = [UIImage imageNamed:#"table_mid.png"];
//selectionBackground = [UIImage imageNamed:#"middleRowSelected.png"];
}
UIImageView *imageView = [[UIImageView alloc] initWithImage:rowBackground];
[cell setBackgroundView:imageView];
[imageView release];
//((UIImageView *)cell.selectedBackgroundView).image = selectionBackground;
//custom stuff end
__block CGRect newPos = inviteFriendsParentView.frame;
CGRect tempCurrentGameSubMenuFrame = currentGameSubMenu.frame;
tempCurrentGameSubMenuFrame.size.height = [friendsTable rowHeight] * [friendsTable numberOfRowsInSection:0] + 10;
currentGameSubMenu.frame = tempCurrentGameSubMenuFrame;
float bottomofFrameYPos = currentGameSubMenu.frame.size.height;
newPos.origin.y += bottomofFrameYPos;
return cell;
}