UITableView with UILabel SizeToFit get mess when Scrolling
Asked Answered
S

5

8

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???

Squeeze answered 5/6, 2013 at 20:46 Comment(9)
What is messageLabel and is it different than the label one line aboveAguascalientes
Where did you create the cell's view. You might want to set label's lineBreakMode property there only.Aguascalientes
awooo sorry i fixed it, i just changed the names to make it simple to readSqueeze
I'm Using Storyboard so i create it there and using [cell ViewWithTag:1]Squeeze
@Lukas Spieß what exactly you edited?Squeeze
@DekelMaman See the revisions historyVinitavinn
@LukasSpieß where i can see it ?Squeeze
You could click the link in my comment above or in general click on the "edited $date at $time" link under your question.Vinitavinn
You can't if it has been upvoted or has accepted answers or answers that have been upvoted.Vinitavinn
I
1

you should probably subclass your cell and clean the UILabel on

 override func prepareForReuse() {
    super.prepareForReuse()
    self.label.text = nil
}
Ilona answered 23/2, 2017 at 9:2 Comment(0)
C
20

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.

Conversion answered 5/6, 2013 at 22:42 Comment(4)
Getting this Error: Initializing 'CGRect *' (aka 'struct CGRect *') with an expression of incompatible type 'CGRect' (aka 'struct CGRect') On the row CGRect *frame = messageLabel.frame;Squeeze
ok so it's working great Thanks you very much, but i was needed to you the SizeToFit after all because if I'm not using it the text fill only one row. Anyway it's work fine with this code: messageLabel.lineBreakMode = UILineBreakModeWordWrap; messageLabel.numberOfLines = 0; CGRect frame = messageLabel.frame; frame.size.width = 236.0; //you need to adjust this value messageLabel.frame = frame; [messageLabel sizeToFit];Squeeze
@DekelMaman Yes. For the first solution. I mentioned you need to adjust the width everytime before calling sizeToFit. No need for sizeToFit for 2nd solution.Conversion
Check on XIB or StoryBoard - Autolayout is cheked?Shoffner
I
1

you should probably subclass your cell and clean the UILabel on

 override func prepareForReuse() {
    super.prepareForReuse()
    self.label.text = nil
}
Ilona answered 23/2, 2017 at 9:2 Comment(0)
B
0
Bamboozle answered 18/11, 2014 at 11:43 Comment(0)
T
0

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))
Their answered 21/1, 2016 at 10:11 Comment(0)
R
0

You can set preferred Width property of label. That worked for me

preferred Width

Radiotelegraphy answered 7/12, 2017 at 6:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.