How to change the height of table view cell - objective-c

i m trying to read some RSS data. I have the data that is of different sizes. the data is present in tabke view data object. I used the label to add the data and resize the dat. No success. Please help.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
NSLog(#"in the tabel view cell");
heightOfCell=[self tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Default"];
if (cell == nil)
{
//cell = [[[UITableViewCell alloc] initWithFrame:CGRectMake(55.0,42.0,245.0,heightOfCell) reuseIdentifier:#"Default"] autorelease];
UILabel *label = [[UILabel alloc] init];
NSString *cellText = [[TableViewData news] valueForKey:[NSString stringWithFormat:#"%d",[indexPath row]]];
UIFont *cellFont = [UIFont fontWithName:#"Helvetica" size:10.0];
CGSize constraintSize = CGSizeMake(280.0f, MAXFLOAT);
label.text = [[TableViewData news] valueForKey:[NSString stringWithFormat:#"%d",[indexPath row]]];
CGSize labelSize = [[[TableViewData news] valueForKey:[NSString stringWithFormat:#"%d",[indexPath row]]] sizeWithFont:cellFont constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap];
label.lineBreakMode=UILineBreakModeWordWrap;
[label sizeThatFits:labelSize];
cell = [[[UITableViewCell alloc] initWithFrame:CGRectMake(55.0,42.0,245.0,heightOfCell) reuseIdentifier:#"Default"] autorelease];
//[label sizeToFit];
[cell addSubview:label];
[label release];
}
}

you need to use the following method.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 45;
}
you need to change the height as per your requirements
It should be noted that the default height is 44.

You need to implement the following method:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
// some code that compute row's height
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 50;
// This is just Programatic method you can also do that by xib !
}
You can also change it in Interface Builder. Open the *.xib file, select the table, show the Size Inspector, and change the row height. But, please note that the default height is 44 pixels.

There are two methods to set the UITableViewCell's height .:
UITableView has a property named rowHeight, with which you can use to set all the UITableViewCell to the same row height;
If you implement the UITableViewDelegate protocol , and include tableView:heightForRowAtIndexPath: method, it's you responsbility to decide the current UITableViewCell'height. In practice, we always use the delegate method to set the cell's height, only if each cell's height may be dynamic! And the method is preference to the UITableView's rowHeight property!
So, I think you may prefer the second method:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
NSString *cellText = [[TableViewData news] valueForKey:[NSString stringWithFormat:#"%d",[indexPath row]]];
UIFont *cellFont = [UIFont fontWithName:#"Helvetica" size:10.0];
CGSize labelSize = [cellText sizeWithFont:cellFont
constrainedToSize:constraintSize
lineBreakMode:UILineBreakModeWordWrap];
return lableSize ;
}

I saw a lot of solutions but all was wrong or uncomplet. You no need calculate nothing (no font, no size, nothing)...
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/

You have to know the heights of all cells before the tableView:cellForRowAtIndexPath: delegate call which may require you to store heights inside your view controller or some other list.
The function to customise the heights of cells is tableView:heightForRowAtIndexPath:. The default height for a table view is 44 pixels, for reference.
You can find the documentation here.

Related

Calculating dynamically the height of a custom UITableViewCell

I am building a application without the IB and I am writing everything from scratch. I have a custom UITableViewCell and when I try to calculate the height, it behaves like there are no subviews. I could find a lot of discussion about dynamically setting the height, but nothing really about how to calculate it, based on the subviews and how and where to set the constraints. What I did is setting constraints for my first component - UIImageView and add them the contenView of my cell. What I get is 0.
I will appreciate any input on that or at least direction!
heightForRowAtIndexPath:
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell* cell = [[UITableViewCell alloc]init];
cell.imageView.image = [UIImage imageNamed:#"avatar"];
cell.imageView.translatesAutoresizingMaskIntoConstraints=NO;
NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|-30-[image]" options:0 metrics:nil views:#{ #"image": cell.imageView }];
[cell.contentView addConstraints:constraints];
NSArray *constraints2 = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|-20-[image]" options:0 metrics:nil views:#{ #"image": cell.imageView}];
[cell.contentView addConstraints:constraints2];
[ NSLayoutConstraint constraintWithItem:cell.imageView attribute: NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual toItem:cell.imageView attribute:NSLayoutAttributeHeight multiplier:1.0 constant:0.0f];
CGFloat height = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
NSLog(#"%f",height);
return height;
}
My solution for this kind of problem is UITableViewAutomaticDimension. You just return this in heightForRowAtIndexPath method. You will have to set tableView.estimatedRowHeight to some value that is close to what you will get.
For instance, if you have 5 cells with height [100,200,250,270,300] you can set estimatedRowHeight to 220 (or something similar).
You can take a look at first answer at Using Auto Layout in UITableView for dynamic cell layouts & variable row heights as well.
I'm not sure that will work, or that it is correct but try this way
static NSInteger someCell = 1;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [UITableViewCell new];
cell.tag = someCell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if (cell.tag == someCell) return 100.;
return 30.;
}

UITableView willDisplayCell Acting Weird, Cells borders adjusted only after reuse

I am trying to have 10 pixels gap between cells and the edge of the screen. I implemented willDisplayCell:forRowAtIndexPath and also the heightForCell since am using two different prototype cells in my table view.
The problem am having is really weird. The cells are only adjusted when i pull the list up, am guessing only when they are reused! check the images please.![enter image description here][1]
This is the initial screen:
https://www.dropbox.com/s/epl2n8a5zohhdmz/Edited.screenShot.01.png?dl=0
This is the screen after the table view is scrolled:
https://www.dropbox.com/s/c81dx9wmaq0mgr5/Edited.screenShot.02.png?dl=0
Here is my code:
- (void) tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
cell.layer.borderWidth = 5.0f;
cell.layer.borderColor = [UIColor grayColor].CGColor;
cell.layer.cornerRadius = 7.0;
cell.layer.bounds = CGRectMake(0, 0, 260, cell.bounds.size.height - 10);
cell.backgroundColor = [UIColor colorWithRed:207/255.0 green:207/255.0 blue:207/255.0 alpha:1.0];
CGRect cellFrame = CGRectMake(20, cell.frame.origin.y, 280, cell.frame.size.height);
cell.frame = cellFrame;
cell.contentView.frame = cellFrame;
[cell.contentView alignmentRectForFrame:cellFrame];
[cell setNeedsLayout];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([[self.namesList[indexPath.row] objectForKey:#"Relation"] length] == 0) {
return 69.0;
} else {
return 89.0;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSMutableString *details = [[NSMutableString alloc] init];
UITableViewCell *cell = [[UITableViewCell alloc] init];
UILabel *nameLabel;
UILabel *relationLabel;
UILabel *ageLabel;
UILabel *dayLabel;
UILabel *dateLabel;
Helper *dateConvert = [[Helper alloc] init];
if ([[self.namesList[indexPath.row] objectForKey:#"Relation"] length] == 0) {
cell = [tableView dequeueReusableCellWithIdentifier:#"Cell2" forIndexPath:indexPath];
} else {
cell = [tableView dequeueReusableCellWithIdentifier:#"Cell3" forIndexPath:indexPath];
relationLabel = (UILabel *) [cell viewWithTag:2];
relationLabel.text = [self.namesList[indexPath.row] objectForKey:#"Relation"];
}
nameLabel = (UILabel *) [cell viewWithTag:1];
ageLabel = (UILabel *) [cell viewWithTag:3];
dayLabel = (UILabel *) [cell viewWithTag:4];
dateLabel = (UILabel *) [cell viewWithTag:5];
[details appendString:[self.namesList[indexPath.row] objectForKey:#"Age"]];
[details appendString:#")"];
ageLabel.text = details;
dayLabel.text = [dateConvert getWeekDay:[self.namesList[indexPath.row] objectForKey:#"Date"]];
dateLabel.text = [self.namesList[indexPath.row] objectForKey:#"Date"];
return cell;
}
I have spent days trying to find the problem :( every help is greatly appreciated :)
Why not make your life easier and design the cell in Interface Builder to have the 10 px space already. You can add a UIView, make that 10 px from top, left, right and bottom, then put you UI elements inside of that. I would suggest subclassing your UITableViewCells and have code in those to display your data and set the borders.

UICollectionViewCell dynamic height with autolayout

I am using auto layout with UICollectionViewCell. So the idea is to allow CollectionViewCell to determine it's size based on layouts. All the constraints are set properly but the problem is that I can not calculate it's size for data source method
collectionView:layout:sizeForItemAtIndexPath:
Ideally I would like to calculate Cell's height doing the following:
static MyCell *myCell = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
myCell = [[MyCell alloc] initWithFrame:CGRectZero];
});
cell.model = model;
[cell updateConstraints];
[cell layoutSubviews];
return cell.frame.size;
but it doesn't force constraints to update, so the cell's frame is zero. Can you advice me how can I calculate cell's size based on it's constraints?
Thanks
here is the solution
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
YourCollectionCell * cell = (YourCollectionCell *) [YourCollectionViewObj cellForItemAtIndexPath:indexPath];
if (cell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"YourCollectionCell" owner:self options:nil];
cell = [topLevelObjects objectAtIndex:0];
cell.frame = CGRectMake(0, 0, CGRectGetWidth(self.view.frame), 20);
// SET YOUR CONTENT
[cell layoutIfNeeded];
}
CGSize CellSize = [cell systemLayoutSizeFittingSize:UILayoutFittingCompressedSize withHorizontalFittingPriority:UILayoutPriorityDefaultHigh verticalFittingPriority:UILayoutPriorityDefaultLow];
return CellSize;
}
I think you should return this size:
return [cell systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
For your dynamic height of the UICollectionViewCell in UIcollectionViewcontroller , you need to implement below method: -
(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath

How to calculate number lines required for text

I know this is going to be a stupid daft simple question but I'm going round in circles.
I have several strings which i want displaying in a uitableview. Some of these strings are very long. I have previously asked how to calculate the cell height, and choose the following answer:
- (CGFloat)cellHeightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellString = <YOUR MODEL OBJECT>;
NSDictionary *attributes = #{ NSFontAttributeName : [UIFont systemFontOfSize:16.0f] };
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc]
initWithString: cellString
attributes:attributes];
CGFloat width = self.tableView.frame.size.width - 32.0f;
CGRect frame = [attributedString boundingRectWithSize:CGSizeMake(width, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin context:nil];
// Add some extra padding to the height
CGFloat height = frame.size.height + 16.0f;
return ceil(height);
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return [self cellHeightForRowAtIndexPath:indexPath];
}
how can I get the number of lines required in the uitableview to display the strings.
The best way to actually calculate a cell height is to use a prototype cell for calculating the height.
Add a property to your interface extension:
#interface TableViewController ()
#property (nonatomic, strong) TableViewCell *prototypeCell;
#end
Then lazily load it:
- (TableViewCell *)prototypeCell
{
if (!_prototypeCell)
{
_prototypeCell = [[TableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Prototype"];
}
return _prototypeCell;
}
Change your -[tableView:cellForRowAtIndexPath:] method to use a -[configureCell:forRowAtIndexPath:] type pattern:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"CellId" forIndexPath:indexPath];
[self configureCell:cell forRowAtIndexPath:indexPath];
return cell;
}
-(void)configureCell:(TableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
// Set up you cell from your model
}
Now use this method to setup your prototype and then use the height of that for -[tableView:heightForRowAtIndexPath:]:
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
[self configureCell:self.prototypeCell forRowAtIndexPath:indexPath];
[self.prototypeCell layoutIfNeeded];
CGSize size = [self.prototypeCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
return ceil(size.height);
}

UITableViewCell width is greater than UITableView width

I encountered a weird problem. I am creating a custom selected view for my tableviews. However, this selection view doesn't fit well. I found out that this is because my selection view is 300px while the cell itself is 320px. The weird part is that the UITableView's width is actually just 300px only. How will I adjust the cell width of my table?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *tableIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:tableIdentifier];
if (cell == nil)
cell = [[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:tableIdentifier] autorelease];
if (tableView == bandTable)
{
UIImageView *imageBg = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"column1_selected.png"]];
[imageBg setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
[tableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];
[cell setSelectionStyle:UITableViewCellSelectionStyleGray];
[cell setSelectedBackgroundView:imageBg];
[imageBg release];
NSArray *array = [bandDictionary objectForKey:#"Bands"];
cell.textLabel.text = [array objectAtIndex:indexPath.row];
NSLog(#"CELL: %f", cell.bounds.size.width);
}
return cell;
}
Just set
cell.frame = CGRectMake(0,
0,
self.tableView.frame.size.width,
cell.frame.size.height);
in cellForRowAtIndexPath.
Add this two lines after your cell gets created,
[[cell contentView] setFrame:[cell bounds]];
[[cell contentView] setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
#IvorPrebeg, you shouldn't set the frame for the UITableViewCell inside cellForRowAtIndexPath. The UITableViewCell will automatically be set to the width of the UITableView after the cell did execute layoutSubviews. This will be done automatically after setting a value on the label you inserted in the cell.
Its just important to calculate inside heightForRowAtIndexPath a size based on the font and the text inserted into the cell which is equal to the one inside your cell. In my case it looks like this:
- (CGFloat)tableView:(UITableView *)tableView
heightForRowAtIndexPath:(NSIndexPath *)indexPath{+
ChatMessage *message =
[self.fetchedResultsController objectAtIndexPath:indexPath];
CGSize size = [message.text sizeWithFont:self.messageCell.labelMessage.font
constrainedToSize:CGSizeMake(self.tableView.frame.size.width * 0.8f, HUGE_VAL)
lineBreakMode:NSLineBreakByWordWrapping];
return size.height;
}
And than inside the UITableViewCell:
- (void)layoutSubviews{
[super layoutSubviews];
if( _fInitWidth == 0 ){
self.labelMessage.preferredMaxLayoutWidth =
self.bounds.size.width * 0.8f;
}
[self.contentView setNeedsDisplay];
}
Like you can see, the prefferedMaxLayoutWidth of the UILabel inside my UITableViewCell will be 0.8 of the cells width (320 * 0.8). LayoutSubviews will be excecuted inside cellForRowAtIndex after setting up the cells properties. After that, UITableView will call the heightForRowAtIndexPath and calculate the size for the height. Therefore I calculate the UILabels size by passing a width * 0.8 for constrainedToSize ( tableview width is 320.0 * 0.8 ) the same as in the cell.
The example values are for iPhone devices, they will change on bigger screens of course.
On C#:
public UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath){
UITableViewCell cell = new UITableViewCell();
cell.Frame = new CoreGraphics.CGRect(0, 0,this.selectSchoolTableview.Frame.Width, cell.Frame.Size.Height);
cell.ContentView.AutosizesSubviews = true;
return cell;
}
Another trick:
public UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath){
UITableViewCell cell = new UITableViewCell();
cell.Accessory = UITableViewCellAccessory.None;
cell.ContentView.AutoresizingMask = UIViewAutoresizing.FlexibleWidth;
cell.ContentView.AutoresizingMask = UIViewAutoresizing.FlexibleHeight;
return cell;
}