Domanda

Ho implementato un UISearchBar in una vista tabella e quasi tutto funziona tranne una piccola cosa: Quando inserisco il testo e quindi premere il pulsante di ricerca sulla tastiera, la tastiera va via, i risultati della ricerca sono gli unici elementi mostrati in la tavola, i soggiorni di testo nella UISearchBar, ma il pulsante annulla viene disattivato.

Ho cercato di ottenere la mia lista il più vicino alla funzionalità dell'app contatti Apple e quando si preme la ricerca in questo app, non disattiva il pulsante Annulla.

Quando ho guardato nel file di intestazione UISearchBar, ho notato una bandiera per autoDisableCancelButton sotto la _searchBarFlags struct, ma è privato.

C'è qualcosa che mi manca quando ho impostare l'UISearchBar?

È stato utile?

Soluzione

Ho trovato una soluzione. È possibile utilizzare questo per-ciclo per ciclo sopra le subviews della barra di ricerca e attivarlo quando si preme il pulsante di ricerca sulla tastiera.

for (UIView *possibleButton in searchBar.subviews)
{
    if ([possibleButton isKindOfClass:[UIButton class]])
    {
        UIButton *cancelButton = (UIButton*)possibleButton;
        cancelButton.enabled = YES;
        break;
    }
}

Altri suggerimenti

Ho dovuto modificare questo un po 'per ottenere il lavoro per me in iOS7

- (void)enableCancelButton:(UISearchBar *)searchBar
{
    for (UIView *view in searchBar.subviews)
    {
        for (id subview in view.subviews)
        {
            if ( [subview isKindOfClass:[UIButton class]] )
            {
                [subview setEnabled:YES];
                NSLog(@"enableCancelButton");
                return;
            }
        }
    }
}

Non c'è due modi per raggiungere questo obiettivo facilmente

- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar{
    //  The small and dirty
    [(UIButton*)[searchBar valueForKey:@"_cancelButton"] setEnabled:YES];

    // The long and safe
     UIButton *cancelButton = [searchBar valueForKey:@"_cancelButton"];
    if ([cancelButton respondsToSelector:@selector(setEnabled:)]) {
         cancelButton.enabled = YES;
    }
}

Si dovrebbe andare con la seconda, che non vada in crash l'applicazione se Apple cambierà in background.

A proposito ho provato da iOS 4,0-8,2 e nessun cambiamento, anche lo uso nel mio negozio di applicazioni approvate senza problemi.

Questo è ciò che ha reso al lavoro su iOS 6 per me:

searchBar.showsCancelButton = YES;
searchBar.showsScopeBar = YES;
[searchBar sizeToFit];
[searchBar setShowsCancelButton:YES animated:YES];

Ecco la mia soluzione, che funziona per tutte le situazioni in tutte le versioni di iOS.

IE, altre soluzioni non gestiscono quando la tastiera viene respinto perché l'utente ha trascinato una vista di scorrimento.

- (void)enableCancelButton:(UIView *)view {
    if ([view isKindOfClass:[UIButton class]]) {
        [(UIButton *)view setEnabled:YES];
    } else {
        for (UIView *subview in view.subviews) {
            [self enableCancelButton:subview];
        }
    }
}

// This will handle whenever the text field is resigned non-programatically
// (IE, because it's set to resign when the scroll view is dragged in your storyboard.)
- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar {
    [self performSelector:@selector(enableCancelButton:) withObject:searchBar afterDelay:0.001];
}

// Also follow up every [searchBar resignFirstResponder];
// with [self enableCancelButton:searchBar];

Nessuna delle risposte ha lavorato per me a tutti. Ho scelto come target iOS 7. Ma ho trovato una risposta.

Quello che sto cercando è qualcosa come l'applicazione Twitter per iOS. Se si fa clic sulla lente di ingrandimento nella scheda Timeline, il compare UISearchBar con il pulsante Annulla attivati, la proiezione tastiera e lo schermo recenti ricerche. Scorrere le ricerche recenti schermo e nasconde la tastiera ma mantiene il pulsante Annulla attivato.

Questo è il mio codice di lavoro:

UIView *searchBarSubview = self.searchBar.subviews[0];
NSArray *subviewCache = [searchBarSubview valueForKeyPath:@"subviewCache"];
if ([subviewCache[2] respondsToSelector:@selector(setEnabled:)]) {
    [subviewCache[2] setValue:@YES forKeyPath:@"enabled"];
}

Sono arrivato a questa soluzione impostando un punto di interruzione scrollViewWillBeginDragging: di mia vista tabella. Ho guardato nella mia UISearchBar e mostrato i subviews. Ha sempre e solo uno, che è di tipo UIView (il mio searchBarSubview variabile).

entrare descrizione dell

Poi, che UIView detiene una NSArray chiamato subviewCache e ho notato che l'ultimo elemento, che è il terzo, è di tipo UINavigationButton, non nella API pubblica. Così ho deciso di utilizzare valore-chiave di codifica, invece. Ho controllato se il UINavigationButton risponde a setEnabled:, e per fortuna, lo fa. Così ho impostato la proprietà di @YES. Scopre che che UINavigationButton è il pulsante Annulla.

Questo è destinato a rompere se Apple decide di cambiare l'implementazione di interiora di un UISearchBar, ma che diavolo. Si lavora per la società.

Come per la mia risposta qui , mettere questo nel vostro delegato Searchbar:

- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar
{   
    dispatch_async(dispatch_get_main_queue(), ^{
        __block __weak void (^weakEnsureCancelButtonRemainsEnabled)(UIView *);
        void (^ensureCancelButtonRemainsEnabled)(UIView *);
        weakEnsureCancelButtonRemainsEnabled = ensureCancelButtonRemainsEnabled = ^(UIView *view) {
            for (UIView *subview in view.subviews) {
                if ([subview isKindOfClass:[UIControl class]]) {
                    [(UIControl *)subview setEnabled:YES];
                }
                weakEnsureCancelButtonRemainsEnabled(subview);
            }
        };

        ensureCancelButtonRemainsEnabled(searchBar);
    });
}

Per MonoTouch o Xamarin iOS Ho la seguente C # soluzione di lavoro per iOS 7 e iOS 8:

foreach(UIView view in searchBar.Subviews)
{
    foreach(var subview in view.Subviews)
    {
        //Console.WriteLine(subview.GetType());
        if(subview.GetType() == typeof(UIButton))
        {
            if(subview.RespondsToSelector(new Selector("setEnabled:")))
            {
                UIButton cancelButton = (UIButton)subview;
                cancelButton.Enabled = true;
                Console.WriteLine("enabledCancelButton");
                return;
            }
        }
    }
}

Questa risposta si basa su una soluzione David Douglas .

Una risposta più completa:

  • dal iOS 7, v'è un ulteriore livello di subviews sotto la barra di ricerca
  • un buon posto per attivare il pulsante Annulla in searchBarTextDidEndEditing

.

extension MyController: UISearchBarDelegate {
  public func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
    DispatchQueue.main.async {
    // you need that since the disabling will
    // happen after searchBarTextDidEndEditing is called
      searchBar.subviews.forEach({ view in
        view.subviews.forEach({ subview in
          // ios 7+
          if let cancelButton = subview as? UIButton {
            cancelButton.isEnabled = true
            cancelButton.isUserInteractionEnabled = true
            return
          }
        })
        // ios 7-
        if let cancelButton = subview as? UIButton {
          cancelButton.isEnabled = true
          cancelButton.isUserInteractionEnabled = true
          return
        }
      })
    }
  }
}

Ecco una soluzione Swift 3 che fa uso di estensioni per ottenere il pulsante Annulla facilmente:

extension UISearchBar {
    var cancelButton: UIButton? {
        for subView1 in subviews {
            for subView2 in subView1.subviews {
                if let cancelButton = subView2 as? UIButton {
                    return cancelButton
                }
            }
        }
        return nil
    }
}

Ora, per l'utilizzo:

class MyTableViewController : UITableViewController, UISearchBarDelegate {

    var searchBar = UISearchBar()

    func viewDidLoad() {
        super.viewDidLoad()
        searchBar.delegate = self
        tableView.tableHeaderView = searchBar
    }

    func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
        DispatchQueue.main.async {
            if let cancelButton = searchBar.cancelButton {
                cancelButton.isEnabled = true
                cancelButton.isUserInteractionEnabled = true
            }
        }
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top