Calling topLayoutGuide breaks scrolling altogether

2019-02-04 18:02发布

I am having weird issues with the topLayoutGuide method, which I have to use in a situation where setAutomaticallyAdjustsScrollViewInsets: doesn't work. To narrow down the cause of the problem, I've created the following minimal example, which just sets up a basic table view for testing:

  1. Set up a new iOS Single View application in Xcode.
  2. Paste the following code in ViewController.m's implementation:

    @implementation ViewController
    
    - (void)loadView
    {
        [self setTableView:[[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain]];
    }
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        [self setAutomaticallyAdjustsScrollViewInsets:NO]; // [*]
    }
    
    - (void)viewDidLayoutSubviews
    {
        UITableView *tableView = [self tableView];
    
        UIEdgeInsets insets = [tableView contentInset];
        // insets.top = [[self topLayoutGuide] length]; // [1]
        // insets.top = 100;                            // [2]
    
        [tableView setContentInset:insets];
        [tableView setScrollIndicatorInsets:insets];
    }
    
    #pragma mark - Table view data source
    
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
        return 100;
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        static NSString *CellIdentifier = @"Cell";
    
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    
        if (cell == nil) {
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        }
    
        [[cell textLabel] setText:[NSString stringWithFormat:@"%d", [indexPath row]]];
    
        return cell;
    }
    
    @end
    

The issues that I'm having are these:

  1. If I uncomment the line marked with [1], the correct inset is applied, but scrolling the table view no longer works. When I try to scroll, the table just bounces back to the initial scroll position after I release my finger. This behaviour is also triggered by a plain call to [self topLayoutGuide], without assigning the result to anything.

  2. If I uncomment line [2] instead of [1], scrolling works. The inset of 100 pt is applied as well. But now the initial scrolling position is automatically adjusted so that the content underlaps the status bar.

([*]: This really only seems to do anything in combination with a containing navigation controller. I doesn't seem to make a difference in this example, but I want to disable any automatic behaviour just to be sure.)

Is there anything obvious I'm doing wrong? I'm really at a loss here.

2条回答
Rolldiameter
2楼-- · 2019-02-04 18:57

This is definitely a bug in iOS 7 (doesn't appear to be fixed in 7.1) but seems to only affect UITableViewControllers. I switched over to using a UIViewController with an embedded UITableView since I am not using static cells and don't need any of the 'magic' that a UITableViewController gives you.

Once I wired up the UITableViewDataSource and UITableViewDelegate manually I was able to start using self.topLayoutGuide without messing up the tableView's contentSize.

This was an acceptable workaround for me until Apple fixes the bug.

查看更多
Viruses.
3楼-- · 2019-02-04 19:01

Same thing to me, instead of getting the topLayoutGuide, try this:

CGFloat topOffset = CGRectGetMaxY(self.refController.navigationController.navigationBar.frame);
查看更多
登录 后发表回答