I am trying to make a UITableviewController with two separate sections, one with some UIImages and the other with a UIButton. This is the code. The first section works perfectly, but if I set return 2 to the number of sections the app crashes with error:
'NSRangeException', reason: '*** -[__NSArrayI objectAtIndex:]: index 1 beyond bounds [0 .. 0]'
*** First throw call stack:
This is the code:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 2;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (section==0)
{
return [arrayOfMessages count];
}
else{
return 1;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (indexPath.section==0)
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
balloonView = [[UIImageView alloc] initWithFrame:CGRectZero];
balloonView.tag = 1;
label = [[UILabel alloc] init];
label.backgroundColor = [UIColor clearColor];
label.textColor = [UIColor whiteColor];
label.tag = 2;
label.numberOfLines = 0;
label.lineBreakMode = UILineBreakModeWordWrap;
label.font = [UIFont fontWithName:#"Chalkduster" size:14];
UIView *message = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, cell.frame.size.width, cell.frame.size.height)];
message.tag = 0;
[message addSubview:balloonView];
[message addSubview:label];
message.autoresizingMask = UIViewAutoresizingFlexibleWidth;
[cell.contentView addSubview:message];
cell.backgroundColor = [UIColor clearColor];
cell.backgroundView = [UIView new];
cell.selectedBackgroundView = [UIView new];
}
else
{
balloonView = (UIImageView *)[[cell.contentView viewWithTag:0] viewWithTag:1];
label = (UILabel *)[[cell.contentView viewWithTag:0] viewWithTag:2];
}
NSString *textAll = [arrayOfMessages objectAtIndex:indexPath.row];
NSString *textMessage = [textAll substringFromIndex:2];
NSString *textType = [textAll substringToIndex:2];
CGSize size = [textMessage sizeWithFont:[UIFont fontWithName:#"Chalkduster" size:14] constrainedToSize:CGSizeMake(240.0f, 480.0f) lineBreakMode:UILineBreakModeWordWrap];
if ([textType isEqualToString:#"ME"]) {
balloonView.frame = CGRectMake(318.0f - (size.width + 28.0f), 2.0f, size.width + 28.0f, size.height + 15.0f);
balloonView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
balloon = [[UIImage imageNamed:#"GreenMessage.png"] stretchableImageWithLeftCapWidth:24 topCapHeight:15];
label.frame = CGRectMake(307.0f - (size.width + 5.0f), 8.0f, size.width + 5.0f, size.height);
label.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
label.textColor = [UIColor whiteColor];
} else if ([textType isEqualToString:#"HE"]) {
balloonView.frame = CGRectMake(2.0, 2.0, size.width + 28, size.height + 15);
balloonView.autoresizingMask = UIViewAutoresizingFlexibleRightMargin;
balloon = [[UIImage imageNamed:#"GrayMessage.png"] stretchableImageWithLeftCapWidth:24 topCapHeight:15];
label.frame = CGRectMake(16, 8, size.width + 5, size.height);
label.autoresizingMask = UIViewAutoresizingFlexibleRightMargin;
label.textColor = [UIColor blackColor];
}
balloonView.layer.cornerRadius = 5;
balloonView.clipsToBounds = YES;
balloonView.image = balloon;
label.text = textMessage;
}
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *body = [arrayOfMessages objectAtIndex:indexPath.row];
CGSize size = [body sizeWithFont:[UIFont fontWithName:#"Chalkduster" size:14] constrainedToSize:CGSizeMake(240.0, 480.0) lineBreakMode:UILineBreakModeWordWrap];
return size.height + 20;
}
How can I do it?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:
cellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
// Your's code here
}
NSString *textAll = nil;
if (indexPath.section == 0)
{
// fetch array object here
textAll = [arrayOfMessages objectAtIndex:indexPath.row];
}
else if (indexPath.section == 1)
{
// Since your array for section 1 returns only one array's object
// you should fetch it appropriately by specifying the index of the array
textAll = [arrayOfMessages objectAtIndex:"Specify the index of the array you want to fetch here which should be within the the bound of arrayOfMessages"];
}
// configure your cell here
return cell;
}
The error is not related to the sections. what you did is right. It's the NSArray arrayOfMessages that might be causing the crash.
In section 1 (second section) the number of rows is 1 according to your code:
if (section==0)
{
return [arrayOfMessages count];
}
else
{
return 1;
}
but what if there is no data in the NSArray arrayOfMessages?
NSString *textAll = [arrayOfMessages objectAtIndex:indexPath.row];
The code will break here.
The problem is you are not creating an instance of tableviewcell when tableview starts creating for section 2 remove if(indexPath.section == 0). In addition to this if you have section based tableview you need to store 2 dimentional array. First array is for section and items for each section. For insance
self.arrayOfMessages = #[ #[ #"Section_Text1" , #"Section1_Text2" ], #[ #"Section2_Text1" , #"Section2_Text2" , #"Section2_Text3" ] ];
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.arrayOfMessages[indexPath.section].count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *text = self.arrayOfMessages[indexPath.section][indexPath.row];
///TODO
}
Related
I want to make a tableview height dynamic (based on number of cells loaded) to a specific limit. and after reaching that limit I want to make UITableView scrollable. I do not want use autolayout for this. Please help me. Thanks in advance.
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return arrScreenTime.count;
}
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString * cellIdentifier =#"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.textLabel.text = [arrScreenTime objectAtIndex:indexPath.row];
cell.backgroundColor = [UIColor clearColor];
cell.textLabel.textAlignment = NSTextAlignmentCenter;
cell.textLabel.numberOfLines = 0;
cell.textLabel.lineBreakMode = NSLineBreakByWordWrapping;
cell.textLabel.font = [UIFont fontWithName:kRobotoRegular size:25];
cell.textLabel.textColor = kColor(2, 109, 150, 1);
UIView *customColorView = [[UIView alloc] init];
customColorView.backgroundColor = kColor(53, 144, 177, 1);
cell.selectedBackgroundView = customColorView;
cell.textLabel.highlightedTextColor = kColor(255, 255, 255, 1);
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellText = [arrScreenTime objectAtIndex:indexPath.row];
UIFont *cellFont = [UIFont fontWithName:kRobotoRegular size:25];
CGSize constraintSize = CGSizeMake(280.0f, MAXFLOAT);
CGSize labelSize = [cellText sizeWithFont:cellFont constrainedToSize:constraintSize lineBreakMode:NSLineBreakByWordWrapping];
NSLog(#"height=%f",labelSize.height);
return labelSize.height + 8;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
}
-(void) tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
CGFloat tableHeight = 0.0f;
float baseHeightofTableView = tblViewTitle.frame.size.height;
NSLog(#"baseHeightofTableView = %f",baseHeightofTableView);
for (int i = 0; i < [arrScreenTime count]; i++) {
tableHeight += [self tableView:tblViewTitle heightForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0]];
}
tblViewTitle.frame = CGRectMake(tblViewTitle.frame.origin.x, tblViewTitle.frame.origin.y, tblViewTitle.frame.size.width, tableHeight);
NSLog(#"tblViewTitle.frame = %#",NSStringFromCGRect(tblViewTitle.frame));
tblViewTitle.center = CGPointMake(self.frame.size.width / 2,
self.frame.size.height / 2);
}
You can use below code,
if ([rowCount] > 5) { // 5 is the specific limit to which you wanted to increase table height and after that it goes in else part to not increase the height of tableview instead it will make tableview scrollable.
tableview.frame = CGRectMake(0,0, self.tableview.frame.size.width, 5 * [height of row]);
} else {
tableview.frame = CGRectMake(0, 0, self.tableview.frame.size.width, [rowCount] * 50);
}
Replace rowCount and height of row based on your requirement.
Hope it will help you out!
Cheers
I have implimented this code snippet and it is working fine for me..
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return arrBasics.count;
}
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString * cellIdentifier =#"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.textLabel.text = [arrBasics objectAtIndex:indexPath.row];
cell.backgroundColor = [UIColor clearColor];
cell.textLabel.textAlignment = NSTextAlignmentCenter;
cell.textLabel.numberOfLines = 0;
cell.textLabel.lineBreakMode = NSLineBreakByWordWrapping;
cell.textLabel.font = [UIFont fontWithName:kRobotoRegular size:25];
cell.textLabel.textColor = kColor(2, 109, 150, 1);
UIView *customColorView = [[UIView alloc] init];
customColorView.backgroundColor = kColor(53, 144, 177, 1);
cell.selectedBackgroundView = customColorView;
cell.textLabel.highlightedTextColor = kColor(255, 255, 255, 1);
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellText = [arrBasics objectAtIndex:indexPath.row];
UIFont *cellFont = [UIFont fontWithName:kRobotoRegular size:25];
CGSize constraintSize = CGSizeMake(280.0f, MAXFLOAT);
CGSize labelSize = [cellText sizeWithFont:cellFont constrainedToSize:constraintSize lineBreakMode:NSLineBreakByWordWrapping];
NSLog(#"height=%f",labelSize.height);
return labelSize.height + 8;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
}
-(void) tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
CGFloat tableHeight = 0.0f;
float baseHeightofTableView = tblViewTitle.frame.size.height;
for (int i = 0; i < [arrBasics count]; i++)
{
if (tableHeight < baseHeightofTableView) {
tableHeight += [self tableView:tblViewTitle heightForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0]];
}
else{
tableHeight = baseHeightofTableView;
break;
}
}
tblViewTitle.frame = CGRectMake(tblViewTitle.frame.origin.x, tblViewTitle.frame.origin.y, tblViewTitle.frame.size.width, tableHeight);
NSLog(#"tblViewTitle.frame = %#",NSStringFromCGRect(tblViewTitle.frame));
tblViewTitle.center = CGPointMake(self.frame.size.width / 2,
self.frame.size.height / 2);
}
I am using an Expandable UITableview created by Tom Fewster. I want to tweak the example using two NSMutableArrays, which is a scenario whereby if someone wants to populate an expandable/collapse treeview table from webservice json data would want to achieve. So since in his example the GroupCell does not have an array of, I am wondering how can I do it? Please bear in mind that my Objective-C is still rusty hence, I'm asking this question.
With my attempt is only displaying the first ObjectAtIndex:indexPath:0 for the group.
I want to be able to populate the table and get output like this;
Group A
Row 1a
Row 2a
Row 3a
Group B
Row 1b
Row 2b
Group C
Row 1c
Row 2c
Row 3c
and so on.
You may use JSON data as well to explain your answer if you understand it better that way.
Here i want to populate the table with JSON data so the GroupCell show class_name and rowCell show subject_name. This is the console of what I am parsing from the JSON web-service;
(
{
"class_id" = 70;
"class_name" = Kano;
subject = (
"subject_id" = 159;
"subject_name" = "Kano Class";
}
);
},
{
"alarm_cnt" = 0;
"class_id" = 71;
"class_name" = Lagos;
subject = (
"subject_id" = 160;
"subject_name" = "Lagos Class";
}
);
},
{
"alarm_cnt" = 3;
"class_id" = 73;
"class_name" = Nasarawa;
subject = (
"subject_id" = 208;
"subject_name" = "DOMA Class";
},
"subject_id" = 207;
"subject_name" = "EGGON Class";
},
"subject_id" = 206;
"subject_name" = "KARU Class";
},
"subject_id" = 209;
"subject_name" = "LAFIA Class";
},
"subject_id" = 161;
"subject_name" = "Nasarawa State Class";
}
);
},
{
"alarm_cnt" = 2;
"class_id" = 72;
"class_name" = Rivers;
subject = (
"subject_id" = 162;
"subject_name" = "Rivers Class";
}
);
}
)
I have tried this here is my snippet
- (UITableViewCell *)tableView:(ExpandableTableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"RowCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
NSDictionary *d=[_sitesJson objectAtIndex:0] ;
NSArray *arr=[d valueForKey:#"subject_name"];
NSDictionary *subitems = [arr objectAtIndex:0];
NSLog(#"Subitems: %#", subitems);
NSString *siteName = [NSString stringWithFormat:#"%#",subitems];
cell.textLabel.text =siteName;
//}
NSLog(#"Row Cell: %#", cell.textLabel.text);
// just change the cells background color to indicate group separation
cell.backgroundView = [[UIView alloc] initWithFrame:CGRectZero];
cell.backgroundView.backgroundColor = [UIColor colorWithRed:232.0/255.0 green:243.0/255.0 blue:1.0 alpha:1.0];
return cell;
}
- (UITableViewCell *)tableView:(ExpandableTableView *)tableView cellForGroupInSection:(NSUInteger)section
{
static NSString *CellIdentifier = #"GroupCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
UILabel *textLabel = (UILabel *)[cell viewWithTag:2];
NSDictionary *d2 = [_regionsJson objectAtIndex:0];
NSArray *arr2 = [d2 objectForKey:#"class_name"];
NSString *regions = [[arr2 objectAtIndex:section]objectAtIndex:0];
textLabel.textColor = [UIColor whiteColor];
textLabel.text = [NSString stringWithFormat: #"%# (%d)", regions, (int)[self tableView:tableView numberOfRowsInSection:section]];
NSLog(#"Group cell label: %#", textLabel.text);
// We add a custom accessory view to indicate expanded and colapsed sections
cell.accessoryView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"ExpandableAccessoryView"] highlightedImage:[UIImage imageNamed:#"ExpandableAccessoryView"]];
UIView *accessoryView = cell.accessoryView;
if ([[tableView indexesForExpandedSections] containsIndex:section]) {
accessoryView.transform = CGAffineTransformMakeRotation(M_PI);
} else {
accessoryView.transform = CGAffineTransformMakeRotation(0);
}
return cell;
}
He, just need to update one single method little bit way
- (UITableViewCell *)tableView:(ExpandableTableView *)tableView cellForGroupInSection:(NSUInteger)section
{
static NSString *CellIdentifier = #"GroupCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
NSIndexPath *indexPath;
NSString *regions = [[_dataGroup objectAtIndex:section]objectAtIndex:0];
cell.textLabel.text = [NSString stringWithFormat: #"%# ", regions];
// We add a custom accessory view to indicate expanded and colapsed sections
cell.accessoryView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"ExpandableAccessoryView"] highlightedImage:[UIImage imageNamed:#"ExpandableAccessoryView"]];
UIView *accessoryView = cell.accessoryView;
if ([[tableView indexesForExpandedSections] containsIndex:section]) {
accessoryView.transform = CGAffineTransformMakeRotation(M_PI);
} else {
accessoryView.transform = CGAffineTransformMakeRotation(0);
}
return cell;
}
May help it you.
HTH, Enjoy Coding !!
I think you need to create a TableView which will have a sections array, and each sections row will be populated using the corresponding sections array. Tapping on a section will expand it and it's all rows will be visible.
To meet your requirements, you could follow the below steps as well -
1) Your modal should have a array for sections. The sections array will contain the sections objects, name of the section and corresponding array of the rows.
2) Implement the data source methods of the table view like
- (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView
{
return [section count];
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 50; // sections height
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return nil;
}
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
return nil;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIView *view = [[[UIView alloc] initWithFrame:CGRectMake(0 , 0, tableView.frame.size.width , 50)] autorelease];
[view setBackgroundColor:[UIColor redColor]];
view.layer.masksToBounds = YES;
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(5 , 2 , view.frame.size.width - 10 , view.frame.size.height - 3)];
label.text = ((SectionObject *)[section objectAtIndex:indexPath.section]).sectionName;
label.backgroundColor = [UIColor clearColor];
label.textAlignment = NSTextAlignmentLeft;
label.textColor = [UIColor WwhiteColor];
label.clipsToBounds = YES;
label.font = [UIFont fontWithName:#"HelveticaNeue-CondensedBold" size:14.0f];
label.layer.masksToBounds = YES;
UIImageView *arrowImage = [[UIImageView alloc] initWithFrame:CGRectMake(view.frame.size.width - 30, 0, 17 , 17)];
[arrowImage setCenter:CGPointMake(arrowImage.center.x , (view.frame.size.height/2) ) ];
if(section == self.m_currentSelectedSection)
[arrowImage setImage:self.m_upArrowImage];
else
[arrowImage setImage:self.m_downArrowImage];
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, view.frame.size.width, view.frame.size.height)];
button.tag = section;
[button addTarget:self action:#selector(sectionTapped:) forControlEvents:UIControlEventTouchUpInside];
button.backgroundColor = [UIColor clearColor];
[view addSubview:label];
[label release];
[view addSubview:arrowImage];
[arrowImage release];
[view addSubview:button];
[button release];
view.clipsToBounds = YES;
return view;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSInteger count = 0;
if(self.m_currentSelectedSection == section)
count = [((SectionObject *)[section objectAtIndex:indexPath.section]).rowArray count];
return count;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 40.0;
}
- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString * cellId = #"cellIdentifier";
UITableViewCell *cell = nil;
cell = (UITableViewCell *) [tableView dequeueReusableCellWithIdentifier:cellId];
if(cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier] autorelease];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
//customize cell
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:NO];
}
When ever any section will be tapped following event will be invoked
- (void) sectionTapped:(UIButton *)button
{
self.m_currentSelectedSection = button.tag;
[self performSelector:#selector(refreshView) withObject:nil afterDelay:POINT_ONE_SECOND];
if(m_winnerSlotList->at(self.m_currentSelectedSection).m_leaderboardList.size())
[self.m_leaderboardTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:button.tag] atScrollPosition:UITableViewScrollPositionTop animated:YES];
UIView *baseView = [button superview];
if(baseView)
{
for(int ii = 0 ; ii < [[baseView subviews] count] ; ii++ )
{
UIView *anyView = [[baseView subviews] objectAtIndex:ii];
if([anyView isKindOfClass:[UIImageView class]])
[(UIImageView *)anyView setImage:self.m_upArrowImage];
}
}
}
Initialize self.m_currentSelectedSection = 0, for the first time, this will show the rows for 0th section. As any section is tapped it's rows will be visible (corresponding section rows will expand) and the rows for the previous selected section will be hidden(previous section rows will collapse).
If you need to show more than one section as expanded than you need to keep track of all the section whether a section is expanded or not and accordingly load show/ hide the cells for the corresponding section.
I am trying to create a table with multiple columns, I am using array of cells.
Following is my code, I get single columns every time.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = #"Cell";
TableViewCell *cell = (TableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
cell = [[TableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier] ;
CGFloat x = 0.0f;
UIView *lastCol = [[cell columnCells] lastObject];
if (lastCol) x = lastCol.frame.origin.x + lastCol.frame.size.width;
for (int i = 0; i < 2; i++) {
UILabel *l = [[UILabel alloc] initWithFrame:CGRectMake(0.0f, 0.0f, i, 40.0f)] ;
UIView *gridCell = l;
CGRect f = gridCell.frame;
f.origin.x += x;
gridCell.frame = f;
[cell.contentView addSubview:gridCell];
CGFloat colWidth = [self widthForColumn:i];
x += colWidth + 1.0f;
[[cell columnCells] addObject:gridCell];
}
for (int i = 0; i < 2; i++) {
UILabel *l = (UILabel*)[cell columnCells][i];
l.text =self.department[indexPath.row];
}
return cell;
}
How about this?
// table view delegates
- (int)numberOfSectionsInTableView:(UITableView *) tableView {
return 1;
}
- (int) tableView:(UITableView *) tableView numberOfRowsInSection:(NSInteger)section {
return 100;
}
-(UITableViewCell *) tableView:(UITableView *) tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MainCell"];
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"MainCell"];
double boxWidth = self.view.frame.size.width/3;
for (int i=0;i<=2;i++) {
UIView *mView = [[UIView alloc] initWithFrame:CGRectMake(boxWidth*i, 0, boxWidth, 100)];
if (i==0) {
mView.backgroundColor = [UIColor redColor];
} else if (i==1) {
mView.backgroundColor = [UIColor greenColor];
} else if (i==2) {
mView.backgroundColor = [UIColor blueColor];
}
[cell addSubview:mView];
}
cell.backgroundColor = [UIColor clearColor];
cell.contentView.backgroundColor = [UIColor clearColor];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
Thanks to Fahim, I just modified his code and got what I wanted.
Here's the exact requirement which I was looking for.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MainCell"];
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"MainCell"];
double boxWidth = self.view.frame.size.width/3;
for (int i=0;i<=2;i++) {
UIView *mView = [[UIView alloc] initWithFrame:CGRectMake(boxWidth*i, 0, boxWidth, 100)];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 50, 250, 15)];
[label setText:self.department[indexPath.row]];
[cell addSubview:mView];
[mView addSubview:label];
}
cell.backgroundColor = [UIColor clearColor];
cell.contentView.backgroundColor = [UIColor clearColor];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
I have created an app with a table view. Which uses a view and a label in each cell. But if I create the views and cells in the (!cell) code it returns empty cells and if I remove the (!cell) condition it displays the data but does not take dynamic height. Can anyone please help me.
- (void)viewDidLoad{
NSString *Path = [[NSBundle mainBundle] bundlePath];
NSString *DataPath = [Path stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.plist", LanguageFile]];
NSMutableDictionary *tempDict = [[NSMutableDictionary alloc] initWithContentsOfFile:DataPath];
self.reloadArray = [tempDict objectForKey:#"Rows"];}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [self.reloadArray count];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 1;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
// Get data for the current row
NSString *textData = [reloadArray objectAtIndex:indexPath.section]
CGFloat dataTextHeight = [self getLabelHeightForIndex:textData];
if(dataTextHeight < 44)
{
dataTextHeight = 44;
}
return dataTextHeight;
}
-(CGFloat)getLabelHeightForIndex:(NSString *)string
{
CGSize maximumSize = CGSizeMake(280, 10000);
CGSize labelHeightSize = [string sizeWithFont:[UIFont fontWithName:#"Helvetica" size:14.0f] constrainedToSize:maximumSize lineBreakMode:NSLineBreakByWordWrapping];
if(labelHeightSize.height < 44){
labelHeightSize.height = 44;
}
return labelHeightSize.height;
}
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"Cell";
static const int textViewTag = 1, textLabelTag = 2;
UIImageView *img = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"standard_back.png"]];
img.frame = tableView.frame;
tableView.backgroundView = img;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
// First view
UIView *textView = [[UIView alloc] initWithFrame: CGRectMake(0.0, 0.0, 280.0, 36.00)];
textView.tag = textViewTag;
textView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
[cell.contentView addSubview:textView];
// First label
UILabel *textLabel = [[UILabel alloc] initWithFrame:CGRectMake(10.0, 0.0, 270.0, 36.00)];
textLabel.tag = textLabelTag;
textLabel.font = [UIFont fontWithName:#"Helvetica-Bold" size:14.0f];
textLabel.textColor = [UIColor whiteColor];
textLabel.backgroundColor = [UIColor clearColor];
textLabel.numberOfLines = 0;
textLabel.lineBreakMode = NSLineBreakByWordWrapping;
textLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth;
// textLabel.clipsToBounds = YES;
[cell.contentView addSubview:textLabel];
}
NSString *textData = [reloadArray objectAtIndex:(indexPath.section)];
CGFloat dataTextHeight = [self getLabelHeightForIndex:textData];
UIView *textView = [cell.contentView viewWithTag:textViewTag];
CGRect textViewFrame = textView.frame;
textView.frame = CGRectMake(0.0, 0.0, textViewFrame.size.width, dataTextHeight);
UILabel *textLabel = [cell.contentView viewWithTag:textLabelTag];
CGRect textLabelFrame = textLabel.frame;
textLabel.frame = CGRectMake(10.0, 0.0, textLabelFrame.size.width, dataTextHeight);
textLabel.text = textData;
textLabel.backgroundColor= [UIColor clearColor];
textLabel.textAlignment = NSTextAlignmentCenter;
cell.backgroundColor = [UIColor colorWithWhite:0 alpha:.65];
cell.textLabel.numberOfLines = 0; // Multiline
cell.textLabel.lineBreakMode = NSLineBreakByWordWrapping;
cell.textLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
return cell;
}
Thanks in advance.
I saw a lot of solutions but all was wrong or uncomplet.
You can solve all problems with 5 lines in viewDidLoad and autolayout.
This for objetive C:
_tableView.delegate = self;
_tableView.dataSource = self;
self.tableView.estimatedRowHeight = 80;//the estimatedRowHeight but if is more this autoincremented with autolayout
self.tableView.rowHeight = UITableViewAutomaticDimension;
[self.tableView setNeedsLayout];
[self.tableView layoutIfNeeded];
self.tableView.contentInset = UIEdgeInsetsMake(20, 0, 0, 0) ;
For swift 2.0:
self.tableView.estimatedRowHeight = 80
self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.setNeedsLayout()
self.tableView.layoutIfNeeded()
self.tableView.contentInset = UIEdgeInsetsMake(20, 0, 0, 0)
Now create your cell with xib or into tableview in your Storyboard
With this you no need implement nothing more or override. (Don forget number os lines 0) and the bottom label (constrain) downgrade "Content Hugging Priority -- Vertical to 250"
You can donwload the code in the next url:
https://github.com/jposes22/exampleTableCellCustomHeight
References: http://candycode.io/automatically-resizing-uitableviewcells-with-dynamic-text-height-using-auto-layout/
This is a part of my code which i used in my app. It works for me fine.Ping me if u need help.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
{
CGSize constraintSize = {230.0, 20000}; //230 is cell width & 20000 is max height for cell
CGSize neededSize = [ [NSString stringWithFormat:#"%#",[cellar objectAtIndex:indexPath.row]] sizeWithFont:[UIFont fontWithName:#"HelveticaNeue-Medium" size:15.0f] constrainedToSize:constraintSize lineBreakMode:UILineBreakModeCharacterWrap];
return MAX(45, neededSize.height +33);
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
{ cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
CGSize constraintSize = {230.0, 20000};
UILabel* label = [[UILabel alloc] init];
[label setNumberOfLines:0];
label.backgroundColor = [UIColor clearColor];
[label setFont:[UIFont fontWithName:#"HelveticaNeue-Medium" size:15.0f]];
label.adjustsFontSizeToFitWidth = NO;
CGSize neededSize = [ [NSString stringWithFormat:#"%#",[cellar objectAtIndex:indexPath.row] ] sizeWithFont:[UIFont fontWithName:#"HelveticaNeue-Medium" size:15.0f] constrainedToSize:constraintSize lineBreakMode:UILineBreakModeCharacterWrap];
// NSLog(#"Height%f",neededSize.height);
//NSLog(#"width%f",neededSize.width);
[label setText:[NSString stringWithFormat:#"%#",[cellar objectAtIndex:indexPath.row] ]];
[label setFrame:CGRectMake(10, 2, 230, MAX(neededSize.height+30, 44.0f))];
[[cell contentView] addSubview:label];
cell.selectionStyle=UITableViewCellSelectionStyleNone;
return cell;
}
Hope it helps.!!!
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return "your content height";
}
How can I retrieve the current header section name from an NSTableViewCell item?
Currently I have a method called configureCell which determines how to style the custom cell I have. This data comes from a pList file.
-(void)configureCell:(UITableViewCell *)tableViewCell forIndexPath:(NSIndexPath *)indexPath{
UILabel *label;
UIView *backView;
// NSString *country = [self tableView: tableViewCell titleForHeaderInSection:indexPath.section];
NSString *fatPercent = [[self.milkTypes valueForKey:#"Finland"] objectAtIndex:indexPath.row];
label = (UILabel *)[tableViewCell viewWithTag:1];
label.text = #"Fat Percent test";
backView = (UIView *)[tableViewCell viewWithTag:2];
backView.backgroundColor = [self colorWithHexString: fatPercent];
}
Where I've commented out the line for *country I need to retrieve the current section I'm in. Currently it's statically set to Finland which is the array name from the pList.
For a better understanding on how my code is laid out, here is the majority of the Table Controller.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [self.milkTypes count];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return [[self.milkTypes allKeys] objectAtIndex:section];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSString *country = [self tableView:tableView titleForHeaderInSection:section];
return [[self.milkTypes valueForKey:country] count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *cellIdentifier;
UITableViewCell *cell;
cellIdentifier = [NSString stringWithFormat:#"MilkCell"];
cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell==nil) {
cell = [self tableViewCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
}
[self configureCell:cell forIndexPath:indexPath];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
-(UITableViewCell *)tableViewCellWithReuseIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath{
CGRect rect;
UILabel *label;
UIView *backView;
UITableViewCell *cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier] autorelease];
float center = (float) (40-20)/2;
rect = CGRectMake(15, center, 270, 20);
label = [[UILabel alloc] initWithFrame:rect];
label.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth;
label.tag = 1;
label.backgroundColor = [UIColor clearColor];
label.textColor = [UIColor blackColor];
[cell.contentView addSubview:label];
[label release];
rect = CGRectMake(280, 10, 20, 40-20);
backView = [[UIView alloc] initWithFrame:rect];
backView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleWidth;
backView.backgroundColor = [UIColor clearColor];
backView.tag = 2;
[cell.contentView addSubview:backView];
[backView release];
return cell;
}
-(void)configureCell:(UITableViewCell *)tableViewCell forIndexPath:(NSIndexPath *)indexPath {
UILabel *label;
UIView *backView;
// NSString *country = [self tableView: tableViewCell titleForHeaderInSection:indexPath.section];
NSString *fatPercent = [[self.milkTypes valueForKey:#"Sweden"] objectAtIndex:indexPath.row];
label = (UILabel *)[tableViewCell viewWithTag:1];
label.text = #"Fat Percent test";
backView = (UIView *)[tableViewCell viewWithTag:2];
backView.backgroundColor = [self colorWithHexString: fatPercent];
}
It seems you already have it anyway, in [[self.milkTypes allKeys] objectAtIndex:section] - just use that instead, so
NSString *country = [[self.milkTypes allKeys] objectAtIndex: indexPath.section];