3

In my iOS app, I have a UITextView inside a tableview cell.

The UITextView and hence the cell height expands when the frame required for the text entered by user exceeds the current height of the cell.

In order to achieve the above, I am calling [tableView beginUpdates] followed by [tableView endUpdates] to reload the height for the cells.

The above is resulting duplicate section headers overlapping the expanded cell.

Is there a way to fix this without calling [tableView reloadData]?

Appended below is some relevant code:

When there is a text change, I verify if the text will fit in current text view, if not the cell is expanded to the new height:

- (void)textViewDidChange:(UITextView *)textView {

    CGFloat oldTextViewHeight = [(NSNumber *)[self.cachedTextViewHeightsDictionary objectForKey:indexPath] floatValue];

    CGFloat newTextViewHeight = [textView sizeThatFits:CGSizeMake(textView.frame.size.width, CGFLOAT_MAX)].height + CELL_HEIGHT_PADDING;

    if (newTextViewHeight > oldTextViewHeight ||
        (newTextViewHeight != oldTextViewHeight && oldTextViewHeight != TEXTVIEW_CELL_TEXTVIEW_HEIGHT)) {

        [self reloadRowHeights];

    }
}

- (void)reloadRowHeights {
    // This will cause an animated update of the height of the UITableViewCell
    [self.tableView beginUpdates];
    [self.tableView endUpdates];
}

It's also important to note that I am using a custom section header, which makes my problem similar to one mentioned here: UITableView Custom Section Header, duplicate issue

I cannot however use the solution to above problem because I cannot reloadData for the tableView in middle of user entering text.

Community
  • 1
  • 1
Vibhor Goyal
  • 2,405
  • 2
  • 22
  • 35
  • What about showing us some piece of your code to help us understand what you want to achieve exactly? Don't worry, we are not going to steal any of it. – Ozgur Vatansever Feb 05 '15 at 01:06
  • @ozgurv: I have added some relevant code to the question to give a better perspective. – Vibhor Goyal Feb 05 '15 at 01:12
  • What happened when you called `[tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone:]` between beginUpdates/endUpdates calls? – Ozgur Vatansever Feb 05 '15 at 01:18
  • When you say "duplicate section headers" what exactly do you mean? You get a new header on top of the original one? – joakim Feb 05 '15 at 01:18
  • @joakim: I get two section headers, One is where it should be and the other one is at the initial position (After the initial position, the cell has expanded and thus the original header now overlaps the expanded cell). – Vibhor Goyal Feb 05 '15 at 01:24
  • @ozgurv: reloadRows resigns the first the first responder, hence causing keyboard to go away while the user is still typing. – Vibhor Goyal Feb 05 '15 at 01:25
  • Can you show a screenshoot as well? – Yuchen Feb 05 '15 at 01:41
  • Did you find any solution for this bug – Manoj Aug 12 '16 at 16:20
  • @joakim What exactly happens is tableview calls viewForHeader and instead of getting the reusableHeaderView, it allocates a new one and that header view gets added to tableview showing multiple header view. I am struggling for last 4-5 days to fix this issue. – Manoj Aug 12 '16 at 16:22
  • @ManojAher same problem form me, did you find a solution? – adauguet Sep 26 '17 at 09:26
  • @adauguet sadly I could not find any answer, but I cached the headers(not a recommended way) instead of creating a new one. – Manoj Sep 28 '17 at 10:31

2 Answers2

0

Try implementing

tableView(_ tableView: UITableView, estimatedHeightForHeaderInSection section: Int)

delegate method if you didn't

kostya
  • 1
0

Little late to the party, but I couldn't find a working solution on SO, and then I figured one out, so I thought I'd share.

I use UITableViewAutomaticDimension both for cell heights and for section header heights. My header view class is just a UIView subclass with some subviews as needed. Inside my tableView(:viewForHeaderInSection:) class, I just initialized a new header view as needed, and I was experiencing this duplicate headers issue. Not even reloadData helped.

What seems to have fixed it for me was to implement basic "cell re-use" for the headers. Something like this:

Store the header views in a dictionary somewhere in your view controller.

class ViewController: UIViewController {
   var sectionHeaders: [Int: UIView] = [:]
   // etc...
}

Then, upon request, return your existing section header view if available, or else create and store a new one.

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
   if let sectionHeader = self.sectionHeaders[section] {
      return sectionHeader
   } else {
      let sectionHeader = YourSectionHeader()
      // Setup as needed...
      self.sectionHeaders[section] = sectionHeader
      return sectionHeader
   }
}
Phlippie Bosman
  • 5,378
  • 3
  • 26
  • 29