webentwicklung-frage-antwort-db.com.de

iOS8 Die Abbrechen-Schaltfläche in der Suchleiste in UISearchController kann nicht ausgeblendet werden

Mein Ziel ist es zu verhindern, dass die Schaltfläche "Abbrechen" in einer Suchleiste in einem UISearchController angezeigt wird. Ich begann mit Apples Table Search mit UISearchController-Beispielcode und versteckte die Schaltfläche "Abbrechen", wie im nachstehenden Code-Ausschnitt gezeigt. Wenn der Benutzer jedoch auf das Textfeld tippt, wird die Schaltfläche Abbrechen weiterhin angezeigt. Irgendeine Hilfe?

override func viewDidLoad() {
    super.viewDidLoad()

    resultsTableController = ResultsTableController()

    searchController = UISearchController(searchResultsController: resultsTableController)
    searchController.searchResultsUpdater = self
    searchController.searchBar.sizeToFit()
    tableView.tableHeaderView = searchController.searchBar

    searchController.searchBar.delegate = self

    //Hide cancel button - added by me
    searchController.searchBar.showsCancelButton = false

    ...
21
dguastaf

Ich denke, dass es drei Möglichkeiten gibt, dies zu erreichen:

  1. Überschreiben Sie searchDisplayControllerDidBeginSearch und verwenden Sie den folgenden Code:

searchController.searchBar.showsCancelButton = false

  1. Unterklasse UISearchBar und überschreiben Sie die layoutSubviews, um diese var zu ändern, wenn das System versucht, sie zu zeichnen.

  2. Registrieren Sie sich für die Tastaturbenachrichtigung UIKeyboardWillShowNotification und wenden Sie den Code unter Punkt 1 an.

Natürlich können Sie Ihre Suchleiste immer implementieren.

17
nunofmendes

Verwenden Sie für iOS 8 und UISearchController diese Delegatmethode aus UISearchControllerDelegate:

func didPresentSearchController(searchController: UISearchController) {
  searchController.searchBar.showsCancelButton = false
}

Vergessen Sie nicht, sich als Delegierter festzulegen: searchController.delegate = self

17
Andrew Robinson

Einfach Unterklasse UISearchController & UISearchBar.

class NoCancelButtonSearchController: UISearchController {
    let noCancelButtonSearchBar = NoCancelButtonSearchBar()
    override var searchBar: UISearchBar { return noCancelButtonSearchBar }
}

class NoCancelButtonSearchBar: UISearchBar {
    override func setShowsCancelButton(_ showsCancelButton: Bool, animated: Bool) { /* void */ }
}
10
ma11hew28

Das folgende github-Projekt umfasst UISearchBar, die als Lösung 2 präsentiert wird:

https://github.com/mechaman/CustomSearchControllerSwift

Darüber hinaus gibt es UISearchController als Unterklassen ab, damit die Suchleiste an anderen Stellen als dem tableView-Header platziert werden kann!

Hoffe das hilft.

3
user2253546

Dies war die einfachste Lösung, die ich in Swift finden konnte.

Benutzerdefinierter Suchcontroller:

class CustomSearchController: UISearchController {

    var _searchBar: CustomSearchBar

    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
        self._searchBar = CustomSearchBar()
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
    }

    override init(searchResultsController: UIViewController?) {
        self._searchBar = CustomSearchBar()
        super.init(searchResultsController: searchResultsController)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override var searchBar: UISearchBar {
        return self._searchBar
    }
}

Benutzerdefinierte Suchleiste:

class CustomSearchBar: UISearchBar {
    override func setShowsCancelButton(showsCancelButton: Bool, animated: Bool) {
        // do nothing
    }
}

Das wichtigste Element dabei war, das _searchBar-Objekt nur einmal in init zu erstellen, anstatt es innerhalb der gespeicherten Eigenschaft zu erstellen.

2
Eric Conner

Unterklassen Sie einfach Ihren UISearchController ein und gehen Sie folgendermaßen vor: 

class CustomSearchController: UISearchController {

   override func viewDidLayoutSubviews() {
       super.viewDidLayoutSubviews()
       searchBar.showsCancelButton = false
   }
}

Dies war die einfachste Lösung, mit der ich das Problem des blinkenden Abbruchtasters lösen konnte.

2
mc_plectrum

TL; DR : Die Unterklasse UISearchBar und das Überschreiben von setShowsCancelButton: und setShowsCancelButton:animated: verbirgt die Schaltfläche "Abbrechen".

LÖSUNG

Ich setze active auf NO, wenn die Suchleiste nicht der erste Responder ist (Tastatur ist nicht aktiv und wird angezeigt), da dies tatsächlich ein cancel -Befehl ist.

FJSearchBar

Die Markierung von searchController.searchBar.showsCancelButton = NO scheint in iOS 8 nicht zu funktionieren. Ich habe iOS 9 nicht getestet.

FJSearchBar.h

Leer, aber der Vollständigkeit halber hier platziert.

@import UIKit;

@interface FJSearchBar : UISearchBar

@end

FJSearchBar.m

#import "FJSearchBar.h"

@implementation FJSearchBar

- (void)setShowsCancelButton:(BOOL)showsCancelButton {
    // do nothing
}

- (void)setShowsCancelButton:(BOOL)showsCancelButton animated:(BOOL)animated {
    // do nothing
}

@end

FJSearchController

Hier möchten Sie die wirklichen Änderungen vornehmen. Ich teile die UISearchBarDelegate in ihre eigene Kategorie ein, denn IMHO machen die Kategorien die Klassen sauberer und einfacher zu pflegen. Wenn Sie den Delegaten innerhalb der Hauptklassenschnittstelleimplementierung behalten möchten, können Sie dies gerne tun.

FJSearchController.h

@import UIKit;

@interface FJSearchController : UISearchController

@end

@interface FJSearchController (UISearchBarDelegate) <UISearchBarDelegate>

@end

FJSearchController.m

#import "FJSearchController.h"
#import "FJSearchBar.h"

@implementation FJSearchController {
@private
    FJSearchBar *_searchBar;
    BOOL _clearedOutside;
}

- (UISearchBar *)searchBar {
    if (_searchBar == nil) {
        // if you're not hiding the cancel button, simply uncomment the line below and delete the FJSearchBar alloc/init
        // _searchBar = [[UISearchBar alloc] init];
        _searchBar = [[FJSearchBar alloc] init];
        _searchBar.delegate = self;
    }
    return _searchBar;
}

@end

@implementation FJSearchController (UISearchBarDelegate)

- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar {
    // if we cleared from outside then we should not allow any new editing
    BOOL shouldAllowEditing = !_clearedOutside;
    _clearedOutside = NO;
    return shouldAllowEditing;
}

- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
    // hide the keyboard since the user will no longer add any more input
    [searchBar resignFirstResponder];
}

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
    if (![searchBar isFirstResponder]) {
        // the user cleared the search while not in typing mode, so we should deactivate searching
        self.active = NO;
        _clearedOutside = YES;
        return;
    }
    // update the search results
    [self.searchResultsUpdater updateSearchResultsForSearchController:self];
}

@end

Einige Punkte zu beachten:

  1. Ich habe die Suchleiste und die BOOL als private Variablen anstelle von Eigenschaften angegeben, da
    • Sie sind leichter als private Immobilien.
    • Sie müssen von der Außenwelt nicht gesehen oder modifiziert werden.
  2. Wir prüfen, ob die searchBar der erste Responder ist. Ist dies nicht der Fall, wird der Such-Controller deaktiviert, da der Text leer ist und wir nicht mehr suchen. Wenn Sie/- wirklich sicher sein möchten, können Sie auch searchText.length == 0 sicherstellen.
  3. searchBar:textDidChange: wird vor searchBarShouldBeginEditing: aufgerufen. Deshalb haben wir es in dieser Reihenfolge behandelt.
  4. Ich aktualisiere die Suchergebnisse jedes Mal, wenn sich der Text ändert, Sie können jedoch [self.searchResultsUpdater updateSearchResultsForSearchController:self]; nach searchBarSearchButtonClicked: verschieben, wenn die Suche nur ausgeführt werden soll, nachdem der Benutzer die Taste Search gedrückt hat.
1
mikeho

Verwenden Sie UISearchControllerDelegate.

func willPresentSearchController(_ searchController: UISearchController) {

        searchController.searchBar.setValue("", forKey:"_cancelButtonText")
    }
0
A.G

Swift:

Folgendes funktionierte für mich, hinzugefügt unter viewDidLoad, weil ich diese Schaltfläche nie wollte:

let searchBarStyle = searchBar.value(forKey: "searchField") as? UITextField
searchBarStyle?.clearButtonMode = .never

Stellen Sie sicher, dass Sie die ID für die Suchleiste im Storyboard angeben  enter image description here

0
CristianMoisei