I am Updating a iOS5 project to storybaord and compatible to run with iOS6 / iOS7. my table view have 4 sections and each section have data of different length which may or may not be displayed as a single line.
the old code is some thing like this and I get a warning for the statement
CGSize size = [productToShow.pDesc sizeWithFont:self.lblHidden.font constrainedToSize:self.lblHidden.frame.size lineBreakMode:NSLineBreakByWordWrapping];
warning
sizeWithFont:constrainedToSize:lineBreakMode:is first deprecated in iOS7
so I have tried usingboundingRectWithSize:options:attributes:context: as suggested by the compiler.
but the code seems to be more complicated: apple wouldn't be making simpler things difficult. if some one can see my codes and suggest the best method or a better and simple method it would be of grate help to me and the community.
iOS5 code with XIBs
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 0)
{
NSString *tempPointStr = [self.shortDescArray objectAtIndex:indexPath.row];
self.lblHidden.frame = CGRectMake(58, 0, 945, 9999);
self.lblHidden.text = tempPointStr;
CGSize size = [tempPointStr sizeWithFont:self.lblHidden.font
constrainedToSize:self.lblHidden.frame.size
lineBreakMode:NSLineBreakByWordWrapping];
if (size.height < 50.0f)
{
return 50.0f;
}
else
{
return size.height;
}
}
elseif(indexPath.section == 1)
{
...
}
else
{
...
}
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 0)
{
static NSString *tempPoint = #"ProductPointsCell";
ProductPointsCell *cell = (ProductPointsCell*)[tableView dequeueReusableCellWithIdentifier:tempPoint];
if (cell == nil)
{
NSArray* nib = [[NSBundle mainBundle] loadNibNamed:#"ProductPointsCell_iPad" owner:self options:nil];
cell = [nib objectAtIndex:0];
cell.showsReorderControl = NO;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.backgroundColor=[UIColor clearColor];
cell.lblPoint.font = [UIFont fontWithName:#"Arial-BoldMT" size:18.0f];
}
NSString *tempPointStr = [self.shortDescArray objectAtIndex:indexPath.row];
cell.lblPoint.text = tempPointStr;
self.lblHidden.frame = CGRectMake(58, 0, 945, 9999);
self.lblHidden.text = tempPointStr;
CGSize size = [tempPointStr sizeWithFont:self.lblHidden.font
constrainedToSize:self.lblHidden.frame.size
lineBreakMode:NSLineBreakByWordWrapping];
if (size.height < 50.0f)
{
cell.lblPoint.frame = CGRectMake(58, 0, 945, 50.0f);
}
else
{
cell.lblPoint.frame = CGRectMake(58, 0, 945, size.height);
}
return cell;
}
elseif(indexPath.section == 1)
{
...
}
else
{
...
}
}
where as the same code in :
iOS6/7 codes with storybaord
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 0)
{
NSString *tempPointStr = (self.shortDescArray)[indexPath.row];
self.lblHidden.frame = CGRectMake(58, 0, 945, 9999);
self.lblHidden.text = tempPointStr;
CGSize constraint = CGSizeMake(945, 9999.0f);
NSDictionary * attributes = [NSDictionary dictionaryWithObject:[UIFont systemFontOfSize:14.0f] forKey:NSFontAttributeName];
NSAttributedString *attributedText = [[NSAttributedString alloc]initWithString:self.lblHidden.text attributes:attributes];
CGRect rect = [attributedText boundingRectWithSize:constraint options:NSStringDrawingUsesLineFragmentOrigin context:nil];
CGSize size = rect.size;
if (size.height < 50.0f)
{
return 50.0f;
}
else
{
return size.height;
}
}
elseif(indexPath.section == 1)
{
...
}
else
{
...
}
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 0)
{
static NSString *tempPoint = #"ProductPointsCell";
ProductPointsCell *cell = (ProductPointsCell*)[tableView dequeueReusableCellWithIdentifier:tempPoint];
cell.showsReorderControl = NO;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.backgroundColor=[UIColor clearColor];
cell.pointLbl.font = [UIFont fontWithName:#"Arial-BoldMT" size:18.0f];
[cell.pointLbl setLineBreakMode:NSLineBreakByWordWrapping];
[cell.pointLbl setNumberOfLines:0];
NSString *tempPointStr = (self.shortDescArray)[indexPath.row];
cell.pointLbl.text = tempPointStr;
CGSize constraint = CGSizeMake(945,9999.0f);
NSAttributedString *attributedText = [[NSAttributedString alloc]initWithString:cell.pointLbl.text attributes:#{NSFontAttributeName: [UIFont systemFontOfSize:17.0f]}];
CGRect rect = [attributedText boundingRectWithSize:constraint options:NSStringDrawingUsesLineFragmentOrigin context:nil];
CGSize size = rect.size;
if (size.height < 50.0f)
{
cell.pointLbl.frame = CGRectMake(58, 0, 945, 50.0f);
}
else
{
cell.pointLbl.frame = CGRectMake(58, 0, 945, size.height);
}
return cell;
}
elseif(indexPath.section == 1)
{
...
}
else
{
...
}
}
The purpose of these codes are to make the data displayed in a single line when it fits within a single line and when it doesn't the cell height is adjusted and the data is displayed as a multiline cell.
Also correct me if I should keep the autolayout on or off and should I set any parameters in the storyboard while converting.
if some one can suggest a better/faster and easier way please do so with examples.
Try it without NSAttributedString...this works for me:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
{
NSManagedObject *obj = [results objectAtIndex:indexPath.row];
NSString *text = [obj valueForKey:#"name"];
NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:[UIFont systemFontOfSize:FONT_SIZE], NSFontAttributeName, nil];
CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);
CGSize size = [text boundingRectWithSize:constraint options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:attributes context:nil].size;
CGFloat height = MAX(size.height, 45.0f);
return height ;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
TVCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[TVCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NSManagedObject *obj = [results objectAtIndex:indexPath.row];
NSString *text = [obj valueForKey:#"name"];
NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:[UIFont systemFontOfSize:FONT_SIZE], NSFontAttributeName, nil];
CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);
CGSize size = [text boundingRectWithSize:constraint options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:attributes context:nil].size;
[cell.cellText setText:text];
[cell.cellText setFrame:CGRectMake(CELL_CONTENT_MARGIN, 0.0, CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), MAX(size.height, 45.0f))];
return cell;
}
In TVCell.m:
self.cellText = [[UILabel alloc] initWithFrame:CGRectZero];
[self.cellText setLineBreakMode:NSLineBreakByWordWrapping];
[self.cellText setMinimumScaleFactor:FONT_SIZE];
[self.cellText setNumberOfLines:0];
[self.cellText setFont:[UIFont systemFontOfSize:FONT_SIZE]];
self.cellText.textColor = [UIColor colorWithRed:64/255.0 green:59/255.0 blue:59/255.0 alpha:1.0];
[self.contentView addSubview:self.cellText];
Related
i have created a custom cell with a textview. I need to expand the height of the textview and the height of the custom cell according to the content in the textview without using auto layout. can any one help me
This is the code:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 80;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return sendername.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier1 = #"MenuCtrl";
tsecureMsgConCell *cell = [tabVieConv dequeueReusableCellWithIdentifier:CellIdentifier1];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"MsgConCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
cell.userName.text = [sendername objectAtIndex:indexPath.row];
cell.msgContentTxView.text = [msgContents objectAtIndex:indexPath.row];
NSString * sentDateCell = [msgSenddate objectAtIndex:indexPath.row];
NSString * replyDateCell = [msgRevidate objectAtIndex:indexPath.row];
thredIdCell = [TSecureMsgId objectAtIndex:indexPath.row];
if ([sentDateCell isEqualToString:#"NULL"])
{
cell.dateLbl.text = [msgRevidate objectAtIndex:indexPath.row];
cell.timeLbl.text = [msgRecTime objectAtIndex:indexPath.row];
cell.imgVew.image = [UIImage imageNamed:#"recive.png"];
}
else if ([replyDateCell isEqualToString:#"NULL"])
{
cell.dateLbl.text = [msgSenddate objectAtIndex:indexPath.row];
cell.timeLbl.text = [msgSendTime objectAtIndex:indexPath.row];
cell.imgVew.image = [UIImage imageNamed:#"sent.png"];
}
return cell;
}
msgContentTxView - is my textview
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSUInteger row = indexPath.row;
if (row != NSNotFound)
{
if ([exapmlestring length] > 0)
{
CGFloat padding = 17.0f;
CGFloat labelWidth = self.tableview.bounds.size.width - padding*2;
NSDictionary *attributesDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
[UIFont fontWithName:#"HelveticaNeue" size:17.0], NSFontAttributeName,
nil];
NSAttributedString *text = [[NSAttributedString alloc] initWithString:exapmlestring attributes:attributesDictionary];
NSStringDrawingOptions options = NSStringDrawingUsesLineFragmentOrigin;
///size
CGRect boundingRect = [text boundingRectWithSize:CGSizeMake(labelWidth, CGFLOAT_MAX)
options:options
context:nil];
boundingRect.size.height = boundingRect.size.height + 100;
return (CGFloat) (ceil(boundingRect.size.height) + padding*2);
}
}
return 0;
}
Im trying to make dynamic uitableviewcell height for my custome cell.
the cell is subclassed for adding some background.
this is my uitableview controller class :
#define PADDING 23.0f
- (void)viewDidLoad
{
[super viewDidLoad];
[self.tableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSUInteger count = [self.entries count];
return count + _rowcount;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *reuseIdentifier = #"PlaceholderCell2";
SubcategoryTableViewCell * sctvCell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
if (sctvCell == nil) {
sctvCell= [[SubcategoryTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier];
}
NSUInteger nodeCount = [self.entries count];
sctvCell.contentView.translatesAutoresizingMaskIntoConstraints = NO;
UILabel *label = (UILabel *)[sctvCell.contentView viewWithTag:1];
if (nodeCount > 0)
{
NewsFetchAppRecord *appRecord = [self.entries objectAtIndex:indexPath.row];
[label setText:appRecord.title];
NSDictionary *attributes = #{NSFontAttributeName: [UIFont fontWithName:#"B MyFont" size:14.0f]};
CGRect rect = [appRecord.title boundingRectWithSize:CGSizeMake(label.frame.size.height - PADDING * 5, MAXFLOAT)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:attributes
context:nil];
CGRect newFrame = label.frame;
newFrame.size.height = rect.size.height;
label.frame = newFrame;
[label sizeToFit];
UIView *whiteRoundedCornerView = (UIView *)[sctvCell.contentView viewWithTag:1000];
CGRect newFrame2 = whiteRoundedCornerView.frame;
newFrame2.size.width = 300;
newFrame2.size.height = rect.size.height + 160;
[ whiteRoundedCornerView setFrame:newFrame2];
}
if ((unsigned long)indexPath.row == [self.entries count] - 1){
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0),
^{
NewsFetchParseOperation *p = [[NewsFetchParseOperation alloc]init];
NewsFetchAppRecord *appRecord = [self.entries objectAtIndex:indexPath.row];
p.cat = appRecord.Category;
self.intindex = self.intindex + 1;
p.index = [NSString stringWithFormat:#"%d", (int)self.intindex];
p.lastid = appRecord.ids;
[p main];
dispatch_async(dispatch_get_main_queue(), ^(void)
{
[self.tableView beginUpdates];
NSMutableArray *indexPaths = [NSMutableArray array];
NSInteger currentCount = self.entries.count;
for (NSUInteger i = 0; i < p.appRecordList.count; i++) {
[indexPaths addObject:[NSIndexPath indexPathForRow:currentCount+i inSection:0]];
}
NSArray *temp_1 =[self.entries arrayByAddingObjectsFromArray:p.appRecordList];
self.entries = temp_1;
[self.tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationLeft];
[self.tableView endUpdates];
});
});
}
return sctvCell;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *reuseIdentifier = #"PlaceholderCell2";
SubcategoryTableViewCell * sctvCell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
if (sctvCell == nil) {
sctvCell= [[SubcategoryTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier];
}
NewsFetchAppRecord *appRecord = [self.entries objectAtIndex:indexPath.row];
UILabel *label = (UILabel *)[sctvCell.contentView viewWithTag:1];
NSDictionary *attributes = #{NSFontAttributeName: [UIFont fontWithName:#"B MyFont" size:14.0f]};
CGRect rect = [appRecord.title boundingRectWithSize:CGSizeMake(label.frame.size.height - PADDING * 5, MAXFLOAT)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:attributes
context:nil];
return rect.size.height + PADDING * 6;
}
and my cell subclass :
- (void)awakeFromNib {
self.news_img.layer.cornerRadius = 4;
self.news_img.clipsToBounds = YES;
self.resource_icon_img.layer.cornerRadius = 4;
self.resource_icon_img.clipsToBounds = YES;
self.contentView.backgroundColor = [UIColor clearColor];
self.whiteroundcorner = [[UIView alloc] initWithFrame:CGRectMake(10,10,300,250)];
self.whiteroundcorner.backgroundColor = [UIColor whiteColor];
self.whiteroundcorner.layer.masksToBounds = NO;
self.whiteroundcorner.layer.cornerRadius = 3.0;
[self.whiteroundcorner.layer setShadowColor:[UIColor grayColor].CGColor];
self.whiteroundcorner.layer.shadowOffset = CGSizeMake(-1, 1);
self.whiteroundcorner.layer.shadowOpacity = 0.2;
self.whiteroundcorner.tag = 1000;
[self.contentView addSubview:self.whiteroundcorner];
[self.contentView sendSubviewToBack:self.whiteroundcorner];
}
im using story board for my table like this :
now problem is most of time the height calculated incorrectly.
also some time the height goes way beyond on cell and in the end of 10 cell
when i try to fetch new row the last cell apears incorrectly.
You will need to calculate the height for the cell after setting its content.
So something like this:
- (CGFloat)heightForCellAtIndexPath:(NSIndexPath *)indexPath {
static UITableViewCell *sizingCell = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sizingCell = [self.tableView dequeueReusableCellWithIdentifier:cellIdentifier];
});
/* Method where you set the content of the cell */
[self configureCell: atIndexPath:indexPath];
return [self calculateHeightForConfiguredSizingCell:sizingCell];
}
- (CGFloat)calculateHeightForConfiguredSizingCell:(UITableViewCell *)sizingCell {
[sizingCell setNeedsDisplay];
[sizingCell layoutIfNeeded];
CGSize size = [sizingCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
return size.height;
}
Guys can someone 'tell me why I can not align well the label in these cell? ... The space between the black and the yellow label should be the same but I can not figure out the exact point you want to change in the code ... Surely it is a trivial but I'm lost
This is the code I'm using
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
{
NSString *comment = [[self.objects objectAtIndex:[indexPath row]] objectForKey:#"TITOLO"];
CGFloat whidt = 220;
UIFont *FONT = [UIFont systemFontOfSize:13];
NSAttributedString *attributedText =[[NSAttributedString alloc] initWithString:comment attributes:# { NSFontAttributeName: FONT }];
CGRect rect = [attributedText boundingRectWithSize:(CGSize){whidt, MAXFLOAT}
options:NSStringDrawingUsesLineFragmentOrigin
context:nil];
CGSize size = rect.size;
return size.height +50;
}
- (FFCustomListaEsamiCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object {
FFCustomListaEsamiCell *cell = (FFCustomListaEsamiCell * )[self.tableView dequeueReusableCellWithIdentifier:#"Cell"];
if (!cell) {
cell = [[FFCustomListaEsamiCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Cell"];
}
NSString *text = [object objectForKey:#"TITOLO"];
CGSize constraint = CGSizeMake(220 , 20000.0f);
UIFont *FONT = [UIFont systemFontOfSize:13];
CGSize size = [text boundingRectWithSize:constraint options:NSStringDrawingUsesLineFragmentOrigin attributes:#{NSFontAttributeName:FONT }context:nil].size;
cell.FFTitoloEsameLabel.frame = CGRectMake(17,10, 240, MAX(size.height, 10.0)+10.0 );
cell.FFTitoloEsameLabel.text = text;
NSDateFormatter *FFDataFormattata = [[NSDateFormatter alloc] init];
[FFDataFormattata setDateFormat:FF_DATE_FORMATTER];
cell.FFDataEsameLabel.text = [NSString stringWithFormat: #"%#",[FFDataFormattata stringFromDate:[object objectForKey:FF_ESAMI_DATA_STRING]]];
PFObject *rowObject = [self.objects objectAtIndex:indexPath.row];
if([[rowObject objectForKey:FF_ESAMI_STATUS] boolValue]) {
cell.last.image = [UIImage imageNamed:#"FFIMG_ClockTAG"];
}
else
{
}
return cell;
}
I solved it by removing the auto-layout and setting the blocks with the size inspector ... I think it's the best solution and that is not a problem especially ... I hope ...
When I load UITabelView on viewDidLoad it does not show proper data in cells, but when I scroll the tabelview it sets proper data. What's wrong in my code?
Here the code I use.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
CustomCell *cell = [_AnswerKeyTable dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
NSArray *topLevelObject = [[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:self options:nil];
for(id currentObject in topLevelObject)
{
if([currentObject isKindOfClass:[UITableViewCell class]])
{
cell = (CustomCell*)currentObject;
}
}
}
ModelInfo *info = [mArray objectAtIndex:indexPath.row];
CGSize constraint = CGSizeMake(212, 20000.0f);
NSString *temp=[NSString stringWithFormat:#"%# (%#)",info.your_answer,info.answer_status];
CGSize question_size = [info.question sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
CGSize your_answer_size = [temp sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
CGSize correct_answer_size = [info.correct_answer sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
NSString * ans_string;
if([info.answer_status isEqualToString:#"Correct answered"])
{
ans_string = [NSString stringWithFormat:#"%#(<font color=\"#7EBA00\"><b>%#</b></font>)",info.your_answer,info.answer_status];
cell.lblCorrectAnswer.hidden = YES;
cell.lblC_Ans.hidden = YES;
}else if([info.answer_status isEqualToString:#"Not answered"]){
ans_string = [NSString stringWithFormat:#"<font color=\"#FF0000\"><b>%#</b></font>)",info.answer_status];
cell.lblCorrectAnswer.hidden = NO;
cell.lblC_Ans.hidden = NO;
cell.lblCorrectAnswer.text =info.correct_answer;
[cell.lblCorrectAnswer setFrame:CGRectMake(103,your_answer_size.height+question_size.height+9,212,correct_answer_size.height)];
[cell.lblC_Ans setFrame:CGRectMake(cell.lblC_Ans.frame.origin.x,your_answer_size.height+question_size.height+9,cell.lblC_Ans.frame.size.width,21)];
}else{
ans_string = [NSString stringWithFormat:#"%#(<font color=\"#FF0000\"><b>%#</b></font>)",info.your_answer,info.answer_status];
cell.lblCorrectAnswer.hidden = NO;
cell.lblC_Ans.hidden = NO;
cell.lblCorrectAnswer.text =info.correct_answer;
[cell.lblCorrectAnswer setFrame:CGRectMake(103,your_answer_size.height+question_size.height+9,212,correct_answer_size.height)];
[cell.lblC_Ans setFrame:CGRectMake(cell.lblC_Ans.frame.origin.x,your_answer_size.height+question_size.height+9,cell.lblC_Ans.frame.size.width,21)];
}
cell.lblQuestion.text = info.question;
cell.lblYourAnswer.text = ans_string;
cell.lblYourAnswer.attributedText=[OHASBasicHTMLParser attributedStringByProcessingMarkupInAttributedString:cell.lblYourAnswer.attributedText];
cell.lblQue.text = [NSString stringWithFormat:#"Question %d",indexPath.row+1];
[cell.lblQuestion setFrame:CGRectMake(103, 3,212,question_size.height)];
[cell.lblYourAnswer setFrame:CGRectMake(103,cell.lblQuestion.frame.size.height+6,212,your_answer_size.height)];
[cell.lblAns setFrame:CGRectMake(cell.lblAns.frame.origin.x,cell.lblQuestion.frame.size.height+6,cell.lblAns.frame.size.width,21)];
[cell.view setFrame:CGRectMake(5,1,310,cell.lblQuestion.frame.size.height+cell.lblYourAnswer.frame.size.height+cell.lblCorrectAnswer.frame.size.height)];
[cell setFrame:CGRectMake(0,0,320,cell.view.frame.size.height)];
[cell setFrame:CGRectMake(0,0,320,cell.frame.size.height+10)];
return cell;
}
You can't set the frame of a cell -tableView:cellForRowAtIndexPath:. That is handled automatically by the table view.
To tell the table view the height needed for a cell, use -tableView:heightForRowAtIndexPath:.
I would like to get some suggesstions about the code shown below. The scrolling is kind of slow on iPhone, but not on simulator. What I am trying to do is to show multiple hours and messages on each row and each row may have different numbers of hours and messages.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// message + hours
static NSString *CellIdentifier = #"Cell1";
// others
static NSString *CellIdentifier1 = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
UITableViewCell *cell1 = [tableView dequeueReusableCellWithIdentifier:CellIdentifier1];
UILabel *hoursLabel;
UILabel *infoLabel;
UILabel *dayLabel;
switch (indexPath.section) {
case 0:
cell1 = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier1] autorelease];
if ([hoursArray count] > 0 && [infoArray count] > 0) {
harray = [self seperateString:[hoursArray objectAtIndex:indexPath.row]];
iarray = [self seperateString:[infoArray objectAtIndex:indexPath.row]];
// check how many hours in an array
int loop = [harray count];
int currentInfoHeight = 0;
int currentHourHeight = 0;
int labelHeight = 0;
for (int i = 0; i < loop ; i++) {
NSString *Text = [[NSString alloc] initWithFormat:#"%#", [harray objectAtIndex:i]];
NSString *Text1 = [[NSString alloc] initWithFormat:#"%#", [iarray objectAtIndex:i]];
UIFont *cellFont = [UIFont systemFontOfSize:hourfontSize];
UIFont *cellFont1 = [UIFont systemFontOfSize:messageFontSize];
CGSize constraintSize = CGSizeMake(180.0f, MAXFLOAT);
CGSize labelSize = [Text sizeWithFont:cellFont constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap];
CGSize labelSize1 = [Text1 sizeWithFont:cellFont1 constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap];
/* HourLabel */
hoursLabel =
[[[UILabel alloc]
initWithFrame:
CGRectMake(
70.0 + 2.0 * cell1.indentationWidth,
currentHourHeight + gap,
tableView.bounds.size.width - 70.0 - 4.0 * cell1.indentationWidth,
labelSize.height)]
autorelease];
hoursLabel.text = [NSString stringWithFormat:[harray objectAtIndex:i]];
hoursLabel.backgroundColor = [UIColor clearColor];
hoursLabel.textColor = [UIColor blackColor];
// hoursLabel.shadowColor = [UIColor blackColor];
// hoursLabel.shadowOffset = CGSizeMake(0, 1);
hoursLabel.font = [UIFont systemFontOfSize:hourfontSize];
[cell1.contentView addSubview:hoursLabel];
if (![[iarray objectAtIndex:i] isEqualToString:#"-"]) {
/* infoLabel */
infoLabel =
[[[UILabel alloc]
initWithFrame:
CGRectMake(
70.0 + 2.0 * cell1.indentationWidth,
currentInfoHeight + gap + labelSize.height,
tableView.bounds.size.width - 70.0 - 4.0 * cell1.indentationWidth,
labelSize1.height)]
autorelease];
infoLabel.text = [NSString stringWithFormat:[iarray objectAtIndex:i]];
infoLabel.numberOfLines = 0;
infoLabel.backgroundColor = [UIColor clearColor];
infoLabel.textColor = [UIColor colorWithRed:51.0/255 green:51.0/255.0 blue:51.0/255.0 alpha:1.0];
infoLabel.font = [UIFont systemFontOfSize:messageFontSize];
[cell1.contentView addSubview:infoLabel];
labelHeight = (infoLabel.bounds.size.height);
}
else
{
labelHeight=0;
}
/* store current height of label */
currentHourHeight = (hoursLabel.bounds.size.height) + labelHeight + gap + currentHourHeight;
currentInfoHeight = (hoursLabel.bounds.size.height) + labelHeight + gap + currentInfoHeight;
}
}
/* dayLabel */
dayLabel =
[[[UILabel alloc]
initWithFrame:
CGRectMake(
2.0 * cell1.indentationWidth,
[self tableView:tableView_ heightForRowAtIndexPath:indexPath] / 2.0f - dayFontSize/2 ,
tableView.bounds.size.width -
70.0 - 4.0 * cell1.indentationWidth,
dayFontSize)]
autorelease];
[cell1.contentView addSubview:dayLabel];
/* Configure the properties for the text that are the same on every row */
dayLabel.backgroundColor = [UIColor clearColor];
dayLabel.textColor = [UIColor colorWithRed:207.0/255 green:181.0/255.0 blue:59.0/255.0 alpha:1.0];
dayLabel.font = [UIFont boldSystemFontOfSize:dayFontSize];
/* Draw a line to divide info and message into two sections */
UIView *lineView = [[[UIView alloc] initWithFrame:CGRectMake(79, 0, 1.5, cell1.contentView.bounds.size.height)] autorelease];
lineView.backgroundColor = [self.tableView_ separatorColor];
lineView.autoresizingMask = 0x3f;
[cell1.contentView addSubview:lineView];
NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
[formatter setDateFormat:#"EEE"];
dayLabel.text = [NSString stringWithFormat:[daysArray objectAtIndex:[indexPath row]]];
[cell1 setSelectionStyle:UITableViewCellSelectionStyleNone];
return cell1;
case 1:
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
cell.textLabel.text = #"View information for this location";
cell.textLabel.font = [UIFont systemFontOfSize:16];
cell.textLabel.textAlignment = UITextAlignmentCenter;
return cell;
case 2:
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
cell.textLabel.text = #"Show building on campus map";
cell.textLabel.font = [UIFont systemFontOfSize:16];
cell.textLabel.textAlignment = UITextAlignmentCenter;
return cell;
case 3:
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
cell.textLabel.text = #"Direction to building";
cell.textLabel.font = [UIFont systemFontOfSize:16];
cell.textLabel.textAlignment = UITextAlignmentCenter;
return cell;
default:
break;
}
return cell;
}
You are allocating a NSDateFormatter for each cell. In my experience NSDateFormatter allocation and configuration are some of the most expensive calls available. They take significant amount of time.
Make that NSDateFormatter an instance variable so you have to allocate and configure it exactly one time.
you are not reusing your cells. If you don't reuse your cells your performance will suffer.
The pattern to reuse is something like this:
.
- (NSDateFormatter *)weekDayDateFormatter {
if (!myWeekDayDateFormatter) {
myWeekDayDateFormatter = [[NSDateFormatter alloc] init];
[myWeekDayDateFormatter setDateFormat:#"EEE"];
}
return myWeekDayDateFormatter;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSInteger secondLabelTag = 1001;
static NSInteger imageViewTag = 1002;
static NSString *CellIdentifier1 = #"Cell1";
static NSString *CellIdentifier2 = #"Cell2";
UITableViewCell *cell = nil;
switch (indexPath.section) {
case 0: {
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier1];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier1];
// allocate subviews and configure properties that never change
UILabel *secondLabel = [[UILabel alloc] initWithFrame:CGRectZero];
secondLabel.tag = secondLabelTag;
secondLabel.textColor = [UIColor orangeColor];
[cell.contentView addSubview:secondLabel];
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectZero];
imageView.tag = imageViewTag;
imageView.contentMode = UIViewContentModeScaleAspectFill;
[cell.contentView addSubview:imageView];
}
// Whatever happened before you have a valid cell here
UILabel *secondLabel = (UILabel *)[cell.contentView viewWithTag:secondLabelTag];
UIImageView *imageView = (UIImageView *)[cell.contentView viewWithTag:imageViewTag];
secondLabel.text = [self.weekDayDateFormatter stringFromDate:[dataSource objectAtIndex:indexPath.row]];
imageView.image = [dataSource objectAtIndex:indexPath.row];
break;
}
case 1: {
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier2];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier2];
// configure properties that never change between cells
cell.textLabel.textColor = [UIColor greenColor];
cell.selectionStyle = UITableViewCellSelectionStyleGray;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
// configure properties that are different between cells
cell.textLabel.text = [dataSource objectAtIndex:indexPath.row];
cell.textLabel.backgroundColor = [dataSource objectAtIndex:indexPath.row];
break;
}
}
The code in the tableView:cellForRowAtIndexPath: parts that are called every time should execute as fast as possible. During scrolling this method is called for every single cell.
I guess, the performance isn't lost here, but in -cellForRowAtIndexPath:
Do you use – prepareForReuse / – dequeueReusableCellWithIdentifier:?