Pokaż pasek wyszukiwania na pasku nawigacji bez przewijania w systemie iOS 11

80

Dołączam UISearchController do navigationItem.searchControllerwłaściwości UITableViewController na iOS 11. To działa dobrze: mogę używać ładnego paska wyszukiwania w stylu iOS 11.

Chciałbym jednak, aby pasek wyszukiwania był widoczny po uruchomieniu. Domyślnie użytkownik musi przewinąć w górę w widoku tabeli, aby zobaczyć pasek wyszukiwania. Czy ktoś wie, jak to jest możliwe?

wprowadź opis obrazu tutaj wprowadź opis obrazu tutaj

Po lewej: sytuacja domyślna po uruchomieniu. Po prawej: widoczny pasek wyszukiwania (przez przewijanie w górę). Chciałbym, aby pasek wyszukiwania był widoczny po uruchomieniu, jak na prawym zrzucie ekranu.

Odkryłem już, że pasek wyszukiwania można uczynić widocznym, ustawiając właściwość hidesSearchBarWhenScrollingmojego elementu nawigacyjnego na false. Jednak powoduje to, że pasek wyszukiwania jest zawsze widoczny - nawet podczas przewijania w dół - co nie jest tym, czego chcę.

Jonathan
źródło
w którym dodałeś kodhidesSearchBarWhenScrolling
Anbu.Karthik
1
a co z ustawieniem go jako s firstResponder?
Milan Nosáľ
2
Wybrana poniżej odpowiedź działa dla mnie podczas ładowania, ale chciałbym również ponownie wyświetlić kontroler wyszukiwania podczas programowego przewijania do góry za pomocą scrollView.setContentOffset(_:animated). Czy ktoś ma sugestie?
Justin Vallely
@Jonathan hidesSearchBarWhenScrolling = falseumieszcza pasek wyszukiwania nad dużym tytułem w iOS 13. Masz pomysł, czy mogę to jakoś zaktualizować?
Bonnke

Odpowiedzi:

187

Poniższe elementy sprawiają, że pasek wyszukiwania jest najpierw widoczny, a następnie pozwala go ukryć podczas przewijania:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    if #available(iOS 11.0, *) {
        navigationItem.hidesSearchBarWhenScrolling = false
    }
}

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    if #available(iOS 11.0, *) {
        navigationItem.hidesSearchBarWhenScrolling = true
    }
}

Użycie isActivenie zrobiło tego, co chciałem, powoduje, że pasek wyszukiwania jest aktywny (pokazuje przycisk anulowania itp.), Gdy wszystko, czego chcę, to aby był widoczny.

Jordan Wood
źródło
Dzięki, pracował dla mnie. Ciekawe rozwiązanie :)
Mikrasya
9
To rozwiązanie działa, ale są efekty uboczne, jeśli wyświetlasz również pasek nawigacji, jeśli był wcześniej ukryty (tj. Wsuwasz ten widok z paskiem wyszukiwania na stos nawigacji). Pasek wyszukiwania będzie wyglądał statycznie na miejscu, gdy pasek nawigacji będzie animowany. Wygląda okropnie :(
Matthew Crenshaw,
12
Nie, jeśli viewDidLoadzamiast tego wstawisz pierwszą częśćviewWillAppear
Marc-Alexandre Bérubé
1
Czy ktoś mógłby wyjaśnić, dlaczego to działa i dlaczego searchController.searchBar.isHidden = falsew viewDidLoad nie działa? To drugie wydaje mi się o wiele bardziej logiczne
pho_pho
5
Powoduje to wizualny błąd w iOS 13 podczas powrotu z ekranu podrzędnego.
nemissm
5

Możesz ustawić właściwość isActivena truepo dodaniu searchController do navigationItem.

Takie jak to:

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    searchController.isActive = true
}
txaidw
źródło
Brak metody ustawiającej „setIsActive:”
Nikolay Krasnov
Masz rację, @NikolayKrasnov. isActivejest wartością logiczną tylko do odczytu. Zamiast tego będziesz chciał użyć searchController.active = true.
Mark Jeschke
2

U mnie zadziałało po dodaniu następujących linii w viewDidLoad()metodzie:

navigationController?.navigationBar.prefersLargeTitles = true
navigationController!.navigationBar.sizeToFit()
rohit
źródło
0

Na iOS 13 odpowiedź @Jordan Wood nie zadziałała. Zamiast tego zrobiłem:

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    UIView.performWithoutAnimation {
        searchController.isActive = true
        searchController.isActive = false
    }
}
GaétanZ
źródło