简体   繁体   中英

bug in UITableView layout after orientation change

I have an auto-layout (constraint) based application and noticed that there is a problem with a tableview after an orientation change. The repro steps are as follows (I have a very basic repro app - with a tableview and an add button that adds a new item).

  1. Rotate your application to Landscape mode so the tableview is now landscape.
  2. Add an item to the tableview see 1 below
  3. Rotate back to Portrait, the tableview will now float on horizontal pan (as though the scroll viewer content size is landscape), see [2]

1 Code to add

- (IBAction)onAdd:(id)sender {
    count ++;
    [self.tableView insertRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:count-1 inSection:0]] withRowAnimation:UITableViewRowAnimationBottom];
}

[2] Floating table view

在此输入图像描述

Any ideas on how to work around this problem? Also, how can I tell if this is known issue or something I should report to Apple?

I think this is a bug; if you convert the project away from auto layout and set appropriate resizing masks, everything works just fine. You should file a bug, particularly since you have a simple sample project that reproduces it nicely.

What is happening in your case is as you suspected - the scroll view's content view remains at the landscape width, even though the view itself has resized to portrait, so you suddenly get the ability to horizontally drag.

Luckily there are fairly simple workarounds. I experimented with various combinations of setNeedsLayout or setNeedsUpdateConstraints without success, but you can implement one of these two solutions:

-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
    [self.tableView beginUpdates];
    [self.tableView endUpdates];
}

Or,

-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
    CGSize contentSize = self.tableView.contentSize;
    contentSize.width = self.tableView.bounds.size.width;
    self.tableView.contentSize = contentSize;
}

I have found that the answers above work most of the time but not all of the time. The most robust solution is to subclass UITableView and set the contentSize within layoutSubviews:

- (void)layoutSubviews
{
    [super layoutSubviews];

    CGSize contentSize = self.contentSize;
    contentSize.width  = self.bounds.size.width;
    self.contentSize   = contentSize;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM