View offset after modal display - possibly related to AutoLayout

I present a simple view with several shortcuts and a button, all inside UIScrollViewand laid out using an automatic layout.

The button represents another view that includes a navigation element for terminating.

After dismissal, however, the contents of the original are UIScrollViewshifted. Oddly enough, the amount by which it is shifted is similar to the scroll position during a presentation.

The demo project here is a small example of this problem. Run it in the iPhone simulator and scroll down to use the modal button. After rejecting the modal attempt to scroll back up, the problem should be clear.

Or look at the scroll bar in the images below to see the problem.

BEFORE THE PRESENTATION

BEFORE PRESENTATION

AFTER PRESENTATION

AFTER PRESENTATION

+2
source share
2 answers

I'm not an expert in AutoLayout, but I fixed it by adding label and button restrictions to self.viewinstead self.scrollView.

For instance:

[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[l1]"
                                                                  options:0
                                                                  metrics:nil
                                                                    views:@{@"l1":self.l1}]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|[l1]"
                                                                  options:0
                                                                  metrics:nil
                                                                    views:@{@"l1":self.l1}]];

Why does this fix it ... I have no idea: D

+3
source

I had the same problem, and after much research, it looks like a bug in UIKit regarding scrollviews and AutoLayout. Here is the "fix" ...

In viewDidDisappear:save the current scrollview contentOffsetin the property and reset it to zero:

- (void)viewDidDisappear:(BOOL)animated 
{
    [super viewDidDisappear:animated];

    self.previousContentOffset = self.scrollView.contentOffset;

    self.scrollView.contentOffset = CGPointZero;
}

viewWillAppear:, reset , . , :

- (void)viewWillAppear:(BOOL)animated 
{
    if (!CGPointEqualToPoint(self.previousContentOffset, CGPointZero))
    {
        dispatch_async(dispatch_get_main_queue(), ^{
            self.scrollView.contentOffset = self.previousContentOffset;
        });
    }
}
+3

All Articles