iOS 11 UISearchController in Navigation Bar with UIRefreshControl causes layout glitch
Asked Answered
S

2

13

I am trying to use UIRefreshControl on a table view together with the new searchController API on navigationItem.
Now when I set hidesSearchBarWhenScrolling the "pull down to refresh" animation is not showing anymore and the refresh control just pops in at a certain point.

enter image description here

It appears to be a bug in UIKit (...same procedure as every year). Did anyone find a solution for this one?

To reproduce the issue add this to a fresh iOS 11 "master/detail" sample project:

- (void)viewDidLoad {
    // [setup code here]

    self.refreshControl = [UIRefreshControl new];
    self.navigationItem.searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
    self.navigationItem.hidesSearchBarWhenScrolling = NO; // <-- setting this causes jumpy UI
}
Serviceman answered 10/11, 2017 at 14:31 Comment(0)
E
4

I just experienced the same problem. It definitely looks like a bug in UIKit. It would definitely be something filing a radar would be worth.

I found a very hacky way to mitigate it though:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    //Fixes a bug in UIKit where the refresh control is broken when `hidesSearchBarWhenScrolling` is NO.
    if (@available(iOS 11.0, *)) {
        self.navigationItem.hidesSearchBarWhenScrolling = scrollView.contentOffset.y < -scrollView.adjustedContentInset.top;
    }
}

Basically what's happening here is that whenever the scroll view scrolls past the top (where the refresh control would become visible), this bit of code will turn hidesSearchBarWhenScrolling back to YES. Once the user scrolls back down again, it will be set back to NO and the search bar will continue to remain visible.

Hopefully Apple will fix this in a future iOS version, but for current shipping versions, this will probably have to do.

Evin answered 30/12, 2017 at 3:44 Comment(0)
P
0

You need to set your Table View's top constraint to the Superview, not SafeArea.

tableView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
Pageboy answered 6/8, 2023 at 17:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.