5

In iOS 6, I had a UITableView created using QuickDialog in my app. It scrolled normally. When I switched to iOS 7, the same UITableView does not scroll properly. I can drag to the bottom (the scroller compresses) but when I release, it pops back up the to the top. I've been playing with viewDidAppear to try and diagnose the problem. See the code block below.

-(void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    NSLog(@"Content height: %f",self.quickDialogTableView.contentSize.height);
    [self.quickDialogTableView reloadData];
    NSLog(@"Content height: %f",self.quickDialogTableView.contentSize.height);
    [self.quickDialogTableView layoutIfNeeded];
    NSLog(@"Content height: %f",self.quickDialogTableView.contentSize.height); 
 }

The output of this block in iOS 7 is

Content height: 0.000000
Content height: 836.000000
Content height: 0.000000

Meanwhile, the output of this block in iOS 6 (simulator) is

Content height: 836.000000
Content height: 836.000000
Content height: 836.000000

Also to try and diagnose the problem, I set up a button that would trigger [self.quickDialogTableView reloadData]. Whenever that button is pushed, the scrolling behavior begins to function normally. Then when I leave the view and come back, the scrolling fails again (until the button is pushed). To be clear, I have tried to put a reloadData in viewWillAppear by itself (i.e., removing the last two lines in the code block above) and it does not correct the scrolling.

I'm looking for clues as to where I might look to correct the issue. Thanks in advance for any help.

Tarek Hallak
  • 18,422
  • 7
  • 59
  • 68
Fausto Morales
  • 163
  • 1
  • 8

5 Answers5

7

Okay, so I couldn't figure out the source of the problem but I did find a workaround that I hope helps someone else. Or at least, maybe helps someone else point out what's really wrong.

I created a property called trueContentSize where I store what the correct size is.

-(void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    [self.quickDialogTableView reloadData]; // Calculates correct contentSize
    self.trueContentSize = self.quickDialogTableView.contentSize; 
}

Then, in -viewDidLayoutSubviews I correct the contentSize manually.

-(void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];
    self.quickDialogTableView.contentSize = self.trueContentSize; 
}
Fausto Morales
  • 163
  • 1
  • 8
  • This did not look like it would work, and sure enough, it did not work for me. I'm facing the same issue, however, in your solution you're simply taking the contentSize from the quickDialogTableView in viewDidAppear: and then reassigning it to the contentSize of the quickDialogTableView again in viewDidLayoutSubviews... I fail to understand how that would fix the issue. – Jamornh Oct 04 '13 at 07:39
  • 1
    @Jamornh Agreed. It doesn't make any sense. However, if I log the `self.quickDialogTableView.contentSize` in `-viewDidLayoutSubviews` before the `self.quickDialogTableView.contentSize = self.trueContentSize;` it turns out to be zero. So something is happening between `-viewDidAppear` and `viewDidLayoutSubviews` that is setting the `contentSize` to zero. I have no idea what. Sorry to hear my hack didn't work for you. Did you check to make sure that your custom `self.trueContentSize` property was returning your expected size before using it? – Fausto Morales Oct 06 '13 at 21:24
  • I've managed to fix it by manually resetting the tableView's superview's frames and bounds then resetting frame of the tableView to fit so the contentSize of the tableView is larger than its frame. Apparently the scrolling wasn't working because the tableView's frame is larger than the contentSize for some reason. Thanks for your response! – Jamornh Oct 07 '13 at 09:18
  • This works for me. It appears to be a known issue that occurs when you arrive at QuickDialog from a storyboard. Here's the issue on their github: https://github.com/escoz/QuickDialog/issues/588 – Ben M. May 28 '14 at 21:38
3

Just thought I might throw in my two cents here..

Same problem was happening to me. Table loads fine at first, but navigate to a different screen, come back, and the table view's contentSize is 0,0 and unscrollable. Fausto's workaround wasn't reliably working, either.

What turned out to be the case for me was just the act of referencing topLayoutGuide in -viewWillLayoutSubviews. Doing that causes all of the above symptoms. Try it out in a new project:

  1. Setup a table view controller inside a tab controller.
  2. Give it 30 rows with just static content.
  3. Run and you can scroll. Switch tabs, then back, and you can scroll.
  4. Add NSLog(@"%@", self.topLayoutGuide); in -viewWillLayoutSubviews
  5. Run again, you can scroll, but switch tabs, no more scrolling.

Weird. Sounds like an iOS bug, or you just shouldn't reference topLayoutGuide in that method. Removing any reference to that property will fix the issue.

Edit: As of earlier this year, Apple confirmed via a Radar report I made this is an iOS bug. Don't reference topLayoutGuide until it's been resolved (whenever that will be, heh). :)

Stephen C
  • 455
  • 5
  • 10
  • Same issue! Just commenting out topLayoutGuide call made table scrolling working fine... – Cemen Nov 06 '14 at 14:41
  • Found a workaround: Replace `UITableViewController` with plain custom `UIViewController`. Here: http://stackoverflow.com/questions/19595479/calling-toplayoutguide-breaks-scrolling-altogether – Cemen Nov 06 '14 at 14:50
1

This is my current temporary fix. Anyone figure out the real fix?

@interface UITableView (Extension)
@end

@implementation UITableView (Extension)

- (void)setContentSize:(CGSize)contentSize {
  if (contentSize.height != 0) {
    [super setContentSize:contentSize];
    NSLog(@"set content height %f", contentSize.height);
  } else {
    NSLog(@"set content size zero");
  }
}

@end
ajayjapan
  • 349
  • 4
  • 18
0

Faced the same problem and the only solution found was to reload the data in the table. Hope that helps.

0

I had a similar issue. My issue was that I had an explicit height set for the table view in the storyboard. Updating my table view to make use auto layout by setting distance to the views above / below made it work for me.

yarrichar
  • 423
  • 5
  • 17