I have a UITableView with multiple height for each cell:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.row == 0){
return 100;
}
else if (indexPath.row==7){
return 200;
}
else {
return 40;
}
}
The problem is in the 7th row with height 200, I have this:
It's just showing the end of the label.
I modified the number of lines of that label to "0" in IB.
What could be the problem.
Thank you for your help.
Increase the label's dimensions. Enlarge the label's size to occupy all the space available in the cell.
If you're using Xib for creating this cell. Attach struts to bottom of the view and let spring's enlarge it. If you're doing it programmatically, enlarge the frame like this:
label.frame = CGRectMake(50, 10, 320, 150); // replace these with appropriate values.
give
myLabel.numberOfLines = 0;
[myLabel sizeToFit];
Also this Question 1 and Question 2 is very helpful for you.
Related
I am trying for chat app. Chat working fine. Facing some UI issues.
1. I am using auto layout for label. So automatically label get expand according to the message size. But, I am having label in UITableViewCell. I couldn't calculate row height dynamically.
My Code:
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
CGSize textSize = {268, CGFLOAT_MAX};
CGSize size = [message sizeWithFont:[UIFont fontWithName:#"Helvetica Neue" size:14] constrainedToSize:textSize lineBreakMode:NSLineBreakByWordWrapping];
CGFloat height = size.height < 65 ? 65 : size.height;
return height;
}
My Label Sub class Code
- (void)drawTextInRect:(CGRect)rect
{
self.textInsets = UIEdgeInsetsMake(5, 5, 5, 5);
return [super drawTextInRect:UIEdgeInsetsInsetRect(rect, self.textInsets)];
}
- (CGSize) intrinsicContentSize
{
self.textInsets = UIEdgeInsetsMake(5, 5, 5, 5);
CGSize superSize = [super intrinsicContentSize] ;
superSize.height += self.textInsets.top + self.textInsets.bottom ;
superSize.width += self.textInsets.left + self.textInsets.right ;
return superSize ;
}
The above code working for small messages, like 400 to 800 characters. More than that it is not working. Cell size not getting increase, as per label size. Kindly guide me.
My Output:
In the above screenshot, small messages displaying time and full message. If we type large text, 20% of message getting hide. kindly guide me. How to solve this?
Use Storyboard for your label and use only single label Set your label to have all 4 constraints, left,right,top,bottom Set number of lines 0.
In your ViewController use these 2 methods,Table view will automatically set height depend on your text
-(CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return UITableViewAutomaticDimension;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return UITableViewAutomaticDimension;
}
I make custom cell with 2 multiline labels and pin this labels to all sides. When in -tableView:heightForRowAtIndexPath: for iOS >= 8 I return UITableViewAutomaticDimension. But when table view appears the cell height is bigger than should be. After I scroll down and then scroll up the cell takes the normal height. How to fix this behavior?
Code for height:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8) {
return UITableViewAutomaticDimension;
}
static CCTopicTableViewCell *cell;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
cell = [tableView dequeueReusableCellWithIdentifier:#"topicCellIdentifier"];
});
cell.topic = [self.topics topicAtIndexPath:indexPath];
cell.bounds = CGRectMake(0, 0, CGRectGetWidth(self.tableView.bounds), CGRectGetHeight(cell.bounds));
[cell setNeedsLayout];
[cell layoutIfNeeded];
CGSize size = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
return size.height + 1;
}
And the result:
After scrolling:
The problem is gone when I don't set tableView's estimatedRowHeight for iOS 8 and update preferredMaxLayoutWidth every time when sets the text for multiline labels
I solved this issue by setting "text" property of multiline labels to "nil":
override func prepareForReuse() {
_label.text = nil
}
Also table properies "estimatedRowHeight" and "rowHeight" should be set correctly:
_tableView.estimatedRowHeight = 44
_tableView.rowHeight = UITableViewAutomaticDimension
Automatic dimension is not working well for some UILabel if that label is aligned with different label by top edges or bottom edges. Just make sure that you do not have such alignments.
Set automatic dimension in viewDidLoad() method or viewWillAppear() (both code in same place)
tableView.rowHeight = UITableViewAutomaticDimension;
tableView.estimatedRowHeight = 160.0;//(Maximum Height that should be assigned to your cell)
Visit Using Auto Layout in UITableView for dynamic cell layouts & variable row heights an intuitive guide for both iOS 7 and iOS 8
I have a custom uitableviewcell.
i want to change its height based on some if condition.
How can i be able to do this ?
I tried doing this in cellForRowAtIndexPath -
if (cell.newsFeedImage.image == NULL)
{
NSLog(#"NULL");
cell.uDisplayImage.frame = CGRectMake(20, 20, 20, 20);
}
The log message appears, but the frame never changes.
Please help.
try to do this in heightForRowAtIndexPath
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
CustomCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];
if (cell.newsFeedImage.image == nil) {
cell.uDisplayImage.frame = CGRectMake(20, 20, 20, 20);
}
else return 40;
}
The height of the cell is set in the tableView datasource method
heightForRowAtIndexPath
It's a little more complicated than that.
This questions has been answered at great length here: Using Auto Layout in UITableView for dynamic cell layouts & variable row heights
Hi I have a tableView which I change the width programmatically by his constraint:
self.widthTableLeft.constant = self.view.frame.size.width;
I do this in the viewDidLoad.
In the delegate method:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
I need the contentview frame of each cell to calculate the hight of the cell, but when get it, this is the old size, I mean the size if I wouldn't have done the resize.
When the table is showed the size of the table is right but the hight of the cell is wrong.
I have tried to call:
[cell setNeedsUpdateConstraints];
[cell updateConstraintsIfNeeded];
[cell.contentView setNeedsLayout];
[cell.contentView layoutIfNeeded];
The question is, before to show the view of my view controller, when is the best place to update the width constraint of a UITableView and to get the right contentView in the cells in the method heightForRowAtIndexPath.
Sorry but I'm lost, could you give me any ideas?
Thanksssss
UPDATE
This is the code in heightForRowAtIndexPath
static const NSInteger ROC_TITLE_LABEL_TAG = 2;
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
ROCAgendaItemDetailEntity *agendaItemDetail = [self.listRight objectAtIndex:indexPath.row];
UITableViewCell *cell = [self.tableLeft dequeueReusableCellWithIdentifier:#"cellVideo"];
//I get the label which will make the cell bigger
UILabel *titleLabel = (UILabel *)[cell viewWithTag:ROC_TITLE_LABEL_TAG];
//We init the height title with the min height.
float extraSpaceHeightLabel = 0;
if (agendaItemDetail.agendaItem.title.length > 0) {
//I will use his width to get the hight that I need to write all text
float width = titleLabel.frame.size.width;
CGSize size = CGSizeMake(width, CGFLOAT_MAX);
//we get the size
CGSize sizeTitleLabel = [agendaItemDetail.agendaItem.title sizeWithFont:[ROCTextsInformation imagoMed:15] constrainedToSize:size lineBreakMode:titleLabel.lineBreakMode];
//we substract the current height of the label to know the extra space to write all text
sizeTitleLabel.height -= titleLabel.frame.size.height;
extraSpaceHeightLabel = sizeTitleLabel.height;
}
//The final hight will be the contenViewHeight pluss the extra space needed.
return cell.contentView.frame.size.height + extraSpaceHeightLabel;
}
and this is the cell in the table view
Thanks again
viewDidLoad is too early to try and access the geometries of your views. Instead, access self.view's width in viewDidLayoutSubviews.
#interface CustomViewController ()
#property (nonatomic) BOOL isFirstTimeViewDidLayoutSubviews; // variable name could be re-factored
#end
#implementation CustomViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.isFirstTimeViewDidLayoutSubviews = YES;
}
- (void)viewDidLayoutSubviews
{
// only after layoutSubviews executes for subviews, do constraints and frames agree (WWDC 2012 video "Best Practices for Mastering Auto Layout")
if (self.isFirstTimeViewDidLayoutSubviews) {
// execute geometry-related code...
self.widthTableLeft.constant = self.view.frame.size.width;
}
self.isFirstTimeViewDidLayoutSubviews = NO;
}
Hi everyone I have problem with my tableview, i make Cell with uilabel with SizeToFit and then calculate the UILabel Height for set the cell Height everything work well except when i scrolling my tableView the text get weird like one char per line:
My TableViewVell Method is:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
UILabel *label = (UILabel *)[cell viewWithTag:1];
label.text = [someArray objectAtIndex:indexPath.row];
// Set the UILabel to fit my text;
messageLabel.lineBreakMode = UILineBreakModeWordWrap;
messageLabel.numberOfLines = 0;
[messageLabel sizeToFit];
return cell;
}
The Cell Height stay in the correct Size the problem only with the UILabel ...
this the result when i load the view:
First screenshot
And this is after i start scroll the TableView:
Second screenshot
Any Help???
The method sizeToFit respects the width of the frame and adjust the height. And table view cell reuse the cells. Combining those two behaviors can cause the issue you described.
One of your label, which is very short in content (e.g. in the 4th cell with the word "jio"), is resized with sizeToFit and the resulting width is smaller than the original width you intended.
After that, table view reuse the cell and sizeToFit still respects the small width calculated from previous call of sizeToFit.
Solutions:
1) set the width of the frame to your original intended label width everytime before you call sizeToFit:
CGRect frame = messageLabel.frame;
frame.size.width = 100.0; //you need to adjust this value
messageLabel.frame = frame;
2) use your row height calculation and set the frame height instead. No need to use sizeToFit.
you should probably subclass your cell and clean the UILabel on
override func prepareForReuse() {
super.prepareForReuse()
self.label.text = nil
}
This might help
http://www.cimgf.com/2009/09/23/uitableviewcell-dynamic-height/
The approach in given reference and solution provided by #Verbumdei is nearby same.
If you are not using autolayout, this can also be solved by adding a category on UIView
public func sizeToFit(constrainedSize: CGSize) -> CGSize {
var newSize = sizeThatFits(constrainedSize)
newSize.width = min(newSize.width, constrainedSize.width)
newSize.height = min(newSize.height, constrainedSize.height)
self.size = newSize
return newSize
}
The idea is to use sizeThatFits with a constrained size to determine the size to adopt and then use the min expected width/height.
Then you just have to do something like
yourLabel.sizeToFit(self.contentView.size) // or
yourLabel.sizeToFit(CGSize(width: maxWidth, height: self.contentView.size.height))
You can set preferred Width property of label. That worked for me
preferred Width