Adjust width of UITableView based on UITableViewCell with longest width - iphone

I have a UITableView that serves as a pop up menu and I want to set its width to the width of its widest UITableViewCell. However, I've tried obtaining the width of the cell UILabel / contentView and it always returns 0. I try doing this after I've added to the subview and after the table has been reloaded and still the same result. I've done it within the tableView:cellForRowAtIndexPath: method and outside of it and same result. Is it possible to do this? My code is listed below:
- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"Cell";
UITableViewCell *tableViewCell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (tableViewCell == nil)
{
tableViewCell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier] autorelease];
}
[[tableViewCell textLabel] setFont:[UIFont fontWithName: #"Helvetica-Bold" size: 17]];
[[tableViewCell textLabel] setText: [self.menuItems objectAtIndex:0]];
[[tableViewCell imageView] setImage: [self.menuItems objectAtIndex:1]];
if (tableViewCell.textLabel.frame.size.width > tableView.frame.size.width)
{
CGRect tableViewFrame = tableView.frame;
tableViewFrame.size.width = tableViewCell.textLabel.frame.size.width;
tableView.frame = tableViewFrame;
}
return tableViewCell;
}
UPDATE: Just to clarify, I'm not interested in changing the width of the TableViewCell while the TableView is reloading. I'd be fine with loading the table, then calculating the appropriate max width, then reloading it again with the new appropriate width.

The best way to approach this may be from another angle. The textLabel won't expand based on the text it contains.
You should loop through the self.menuItems array and call the function that can be applied to an NSString.
- (CGSize)sizeWithFont:(UIFont *)font;
e.g.
width = [menuItem sizeWithFont:font].width;
Keep tabs of the widest width in the array and set your tableview to be that width. The font is whatever font your cell is drawing it's label in.

Related

UILabels within a UITableView cell are overlaying each other in iOS7

I didn't have this problem with iOS6, but am currently having it with iOS7. I have a UITableView and you can see 8 cells at the time the view is loaded. Each populated with different names from and array. If you scroll down, the next two cells look good, but everything past that gets text laid on top of it; That text being the contents of what was in the previous cells. So the 10th cell will have what was in the first cell, as well as what is supposed to be in the 10th cell laid on top of it.
Code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
//Create Label for Name inside cell
UILabel *name = [[UILabel alloc] initWithFrame:CGRectMake( 7.0, 5.0, 300.0, 30.0 )];
[name setText:[self.entriesArray objectAtIndex:indexPath.row]];
//Check to see if current person is a Parent or Child
NSString *class = [self.database getCellDataWithMembership:[self.MembershipArray objectAtIndex:indexPath.row] andColIndex:4];
if([class isEqualToString:#"CHILD"])
{
name.textColor = [UIColor colorWithRed:25.0f/255.0f green:111.0f/255.0f blue:45.0f/255.0f alpha:1.0f];
name.font = [UIFont fontWithName:#"Helvetica-Bold" size:17.0];
}
[cell.contentView addSubview:name];
return cell;
}
My skill with Table views is makeshift at best. I've been reading lots of documentation and researching solutions, but was not able to come up with a solution. I just find it odd that it works perfect for iOS6, but not for iOS7.
So it fetches a person's name from an array and I want to populate the cells with those names. I was able to originally accomplish this using:
cell.textLabel.text = [self.entriesArray objectAtIndex:indexPath.row];
if([class isEqualToString:#"CHILD"])
{
cell.textLabel.textColor = [UIColor colorWithRed:25.0f/255.0f green:111.0f/255.0f blue:45.0f/255.0f alpha:1.0f];
cell.textLabel.font = [UIFont fontWithName:#"Helvetica-Bold" size:17.0];
If I use that instead of the "name" UILabel actions from the first code block, then it displays the names perfectly with no text overlay, but what becomes an issue is the text color. If they are labeled as a CHILD then they should be green text and bold. However, after scrolling down, every person becomes green when they shouldn't be.
Sorry for the lengthy question. I've been working on this and racking my brain around it and I just can't seem to figure it out. Any help would be greatly appreciated.
I'm dynamically adding UI objects to cells. As "caglar" notes, adding and then removing is probs not the best-practice. But, I am doing this also. The way I get around adding loads of UI objects to the cell, each time it's displayed, is by removing all my subviews first. The willDisplayCell delegate then adds them back. Clearly, if you want to remove only certain views, you'll have to tag the view and be more selective with your removal. But you can remove all with the following.
-(void)tableView:(UITableView *)tableView
willDisplayCell:(UITableViewCell *)cell
forRowAtIndexPath:(NSIndexPath *)indexPath {
[[cell.contentView subviews] makeObjectsPerformSelector:#selector(removeFromSuperview)];
}
Just ensure you're adding / removing your labels to the cell's contentView. In iOS7, you'll remove that too, if you're not careful.
Hope it helps you out.
In your code, labels are added to cell whenever cellForRowAtIndexPath: method is called. I mean you add labels many times. You can remove the label which was added before.
//If label was added with tag = 500, remove it
for (UIView *sv in cell.contentView.subviews)
{
if (sv.tag == 500)
{
[sv removeFromSuperview];
}
}
//Create Label for Name inside cell
UILabel *name = [[UILabel alloc] initWithFrame:CGRectMake( 7.0, 5.0, 300.0, 30.0 )];
[name setText:[self.entriesArray objectAtIndex:indexPath.row]];
name.tag = 500;
However, this solution is not a good solution. I think creating a custom UITableViewCell is the right thing to do.
You can try this method, when the cell is nil, you need to creare the UILabel* name, then you set the name label with a tag name.tag = 1000, then you can access this label with this method UILabel* name = (UILabel*)[cell.contentView viewWithTag:1000];.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
//Create Label for Name inside cell
UILabel *name = [[UILabel alloc] initWithFrame:CGRectMake( 7.0, 5.0, 300.0, 30.0 )];
name.tag = 1000;
[cell.contentView addSubview:name];
}
UILabel* name = (UILabel*)[cell.contentView viewWithTag:1000];
[name setText:[self.entriesArray objectAtIndex:indexPath.row]];
//Check to see if current person is a Parent or Child
NSString *class = [self.database getCellDataWithMembership:[self.MembershipArray objectAtIndex:indexPath.row] andColIndex:4];
if([class isEqualToString:#"CHILD"])
{
name.textColor = [UIColor colorWithRed:25.0f/255.0f green:111.0f/255.0f blue:45.0f/255.0f alpha:1.0f];
name.font = [UIFont fontWithName:#"Helvetica-Bold" size:17.0];
}
return cell;
}
You can set uilabels by using ios6/7 delta shown is size inspector .firstly set your total view for ios7 by changing values x,y,width,height and then change value in ios6/7 delta to make it for ios6 .Hope you get
you may change the this code.
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; -> UITableViewCell *cell = nil;

can i give space between two cells in tableview in ipohne?

static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
NSLog(#"%d",indexId);
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
///////////////////// Cell Title /////////////////////
//cell.textLabel.font = [UIFont fontWithName:#"Noteworthy" size:20.0];
cell.textLabel.font = [UIFont boldSystemFontOfSize:14.0];
cell.textLabel.highlightedTextColor = [UIColor orangeColor];
}
///////////////////// Cell Title /////////////////////
cell.textLabel.text = [NSString stringWithFormat:#" %#", [test.arrTitle objectAtIndex:indexPath.row]];
the above code where i need change code for get sapce between tableview cell label
thanks and regards
There's a few ways to add space between cells in a table view.
You can adjust the height of the table view cells in Interface Builder, you can do custom cells with different heights, or you can programatically return different heights via the tableView:heightForRowAtIndexPath: delegate method.
A easy way to add space between two cells would be to use the sections to display the data. Make sure that each section contains just one cell. Then, you can add sectionHeaderView or sectionFooterView between subsequent sections to make it right.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return [myItems count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return 1;
}
#define customSeparatorHeight 3
- (UIView*)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
return [UIView alloc] initWithFrame:CGRectMake(0,0, tableView.bounds.size.width, customSeparatorHeight)];
}

When I set the rowHeight for UITableView, shouldn't the height of cell changed as well?

Question:
When I set the rowHeight for UITableView, shouldn't the height of cell changed as well?
Here is the situation that leads me to think about it:
I want to set a separate line for each table view cell at bottom, what's more, I want to set the row height for it from 44 to 32. The result I want is like below:
Row height setting is done correctly:
- (void)viewDidLoad
{
[super viewDidLoad];
[self.tableView setRowHeight:32.0f];
[self.tableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];
//...
}
// Even use the delegate of UITableView
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 32.0f;
}
However, when I was adding separate line for cell, I met a issue: I want to set the separate line at bottom of the cell, so I set the y position by cell.frame.size.height - 1.0f. Unfortunately, the result shown as below:
When I did selecting, cell changed like below:
1. Selected row No.1:
2. Selected row No.2:
3. Selected row No.3:
It seems that the height of cell before selected was 44, when selected, it changed to 32. They were overlapped one by one like cards, right? Weird!
The main code:
- (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] autorelease];
[cell.textLabel setFont:[UIFont fontWithName:#"Futura-Medium" size:15.0f]];
UIView * seperateLine = [[UIView alloc] initWithFrame:CGRectMake(10.0f, cell.frame.size.height - 1.0f, 300.0f, 1.0f)];
NSLog(#">>>>>>>>>>>>>>>> %f", cell.frame.size.height);
[seperateLine setBackgroundColor:[UIColor grayColor]];
[cell.contentView addSubview:seperateLine];
[seperateLine release];
}
//...
}
I tried to check the cell.frame.size.height, and finally it was 44. And then, I replace the line
UIView * seperateLine = [[UIView alloc] initWithFrame:CGRectMake(10.0f, cell.frame.size.height - 1.0f, 300.0f, 1.0f)];
to
UIView * seperateLine = [[UIView alloc] initWithFrame:CGRectMake(10.0f, 31.0f, 300.0f, 1.0f)];
It worked as the first image shown above. But the cell's height was still 44, they(which we just cannot see totally) ware still overlapped. What I had done is just added a separate line at where y position is 32 but its total height is 44.
So what do you think about this? :?
Problem:
According to apple's HIG the default tapable area is 44, so by default all control has 44 height.
you define new UITableViewCell inside
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
which is by default 44 and you change nothing in UITableViewCell's frame and return it.
Solution:
try setting the frame size of the UITableViewCell i.e cell.frame = CGRectMake(0.0f, 0.0f, 320.0f, 32.0f)
Please refer documentation and look for tableView:heightForRowAtIndexPath: delegate method. Using which you can set height for each row. It can be fixed or can be dynamic as well as per your requirement.
Hope it helps.

How to scroll UI tableview vertically and horizontally?

i have table view in my app and each row have long text so its possible to scroll whole table so user can read entire text
also i am using following code to set up my cell
-
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//buttonCount=0;
static NSString *CellIdentifier = #"Cell";
static NSUInteger const kLeftLabel = 100;
static NSUInteger const kRightLabel = 101;
row = [indexPath row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
CGRect leftFrame = CGRectMake(2, 5, 45, 30);
CGRect rightFrame = CGRectMake(50, 5, 400, 30);
left = [[[UILabel alloc]initWithFrame:leftFrame]autorelease];
left.tag = kLeftLabel;
left.font = [UIFont systemFontOfSize:13];
[cell.contentView addSubview:left];
right = [[[UILabel alloc]initWithFrame:rightFrame]autorelease];
right.tag=kRightLabel;
right.font = [UIFont systemFontOfSize:13];
[cell.contentView addSubview:right];
}
else {
left = (UILabel*)[cell.contentView viewWithTag:kLeftLabel];
right=(UILabel*)[cell.contentView viewWithTag:kRightLabel];
}
left.text =[secondSplitArrayValue objectAtIndex:row];
right.text=[splitArrayValue objectAtIndex:row];
if (indexPath.row == 0)
{
[cell setSelectionStyle:UITableViewCellSelectionStyleNone ];
}
return cell;
}
by use of above code i have two column so 1st column have small text but 2nd is very much big and to read i want to scroll it horizotally.
i hope some one will solve this problem.
thank you in advance
To solve your problem there is no need to modify scrolling of table view you can do it by following code... by using this code you can show ur text in multiline in the default label of table view cell.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"MyCell";
UITableViewCell *cell =(UITableViewCell*) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
cell.textLabel.numberOfLines = 0;
cell.textLabel.text = #"Its for testing. Its for testing. Its for testing. Its for testing. Its for testing. Its for testing. Its for testing. Its for testing. Its for testing. Its for testing. Its for testing. ";
return cell;
}
You need to use the multiline label for the long text and set the height of your long cell properly by calculating with long text in below function.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
for more you can read the tutorial
place your UITableView in UIScrollview
But looking at your case there is no need to do such thing, I would prefer to make the cells height Dynamic according to the Text.
Just use above code which might help to solve your problem:
You need to use Custom Cell having TextView in cell;
//Calculate the Height & Width of Text
CGSize stringSize = [#"Your sample text whose height & Width need to be calulated" sizeWithFont:[UIFont boldSystemFontOfSize:[YurTextField font] constrainedToSize:CGSizeMake(230, 9999) lineBreakMode:UILineBreakModeWordWrap];
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"MyCell";
UITableViewCell *cell =(UITableViewCell*) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
[Over here take TextView calculating the Height & width of String ];
// [add TextView it cells contentView];
[cell.contentView addSubview:TextView];
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath*)indexPath {
CGSize stringSize = [#"Your sample text whose height & Width need to be calulated" sizeWithFont:[UIFont boldSystemFontOfSize:[YurTextField font] constrainedToSize:CGSizeMake(230, 9999) lineBreakMode:UILineBreakModeWordWrap];
return stringSize.height;
}
if it doesn't solve your purpose then try using below alternative
Although I can suggest you to use the ScrollView & set it Delegate.
Add your UITAbleView as SubView to ScrollView & keep the size of scrollview according to the view how much you want to Scroll.
->View
-->ScrollView
--->UITableView

Variable height UIViews and labels

Ok so I'm not in a table cell at this point. (I've seen a lot of threads regarding the height of cells.)
I have a detail view with a title and description at the top of the view, followed by a tableView below it. If the description is going to vary in length, how do I get the tableView to adjust with it accordingly so it always starts directly below it?
I see apple doing this in the app store application. If you look at an application description (as if you were going to buy it), they have an application description, and wherever that ends a scrolling pane of screenshots follow. How do they do the varying height on the text description like that?
Are they doing this all programmatically or can I use the layout controls in IB to do the same thing?
you need to add table view programmatically in your view and set its frame as per your detail view's size
1> get the current frame of the detailView
2> add it's height and than add tableview to your view
like
UITableView *table = [[UITableView alloc] initWithFrame:CGRectMake(initX , initY + DetailViewFrame.size.height, TableWidth, TableHeight) style:UITableViewStylePlain];
[view addSubView:table];
The layout controls in IB change how a view is sized when its parent view resizes. In this case, (I assume) the label and table view are sibling views, so you need to do this programatically. Having sizes the label to fit, find the bottom of it (the origin's y location plus the label's height) and use that to guide where you place the table view. You would probably do this in -viewDidLoad or -viewWillAppear:, depending on when you have enough information to do the calculation.
I think you need to use the "sizeWithFont" to calculate the cell height at run time, see following :
- (CGFloat) tableView: (UITableView *) tableView heightForRowAtIndexPath: (NSIndexPath *) indexPath
{
CGSize labelSize = CGSizeMake(200.0, 20.0);
if ([string length] > 0)
labelSize = [string sizeWithFont: [UIFont boldSystemFontOfSize: 17.0] constrainedToSize: CGSizeMake(labelSize.width, 1000) lineBreakMode: UILineBreakModeWordWrap];
return 24.0 + labelSize.height;
}
And in "cellForRowAtIndexPath"
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryNone;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.autoresizingMask = UIViewAutoresizingFlexibleHeight;
}
cell.textLabel.text = #"Your string with variable length";
[cell.textLabel setFont:[UIFont boldSystemFontOfSize:12]];
//[cell.textLabel setAdjustsFontSizeToFitWidth:YES];
[cell.textLabel setBaselineAdjustment:UIBaselineAdjustmentAlignBaselines];
[cell.textLabel setLineBreakMode:UILineBreakModeWordWrap];
[cell.textLabel setNumberOfLines:0];
return cell;
}
Hope this helps you ...