2013-09-28 47 views
20

In un'app che deve essere eseguita su iOS 6 e iOS 7, il pulsante di annullamento della barra di ricerca incorporata nella barra di navigazione non viene più visualizzato se l'app è eseguito su iOS 7. Su iOS 6, funziona.iOS 7 non mostra il pulsante Annulla della barra di ricerca nella barra di navigazione

La barra di ricerca è nella visualizzazione del titolo della barra di navigazione e il pulsante di annullamento deve essere visualizzato se la barra di ricerca diventa il primo soccorritore:

iOS 7

enter image description here

iOS 6

enter image description here

In un banco di prova isolato, il codice è molto semplice:

@interface MyViewController : UITableViewController<UISearchBarDelegate> 

@property (nonatomic) IBOutlet UISearchBar* searchBar; 

@end 


@implementation MyViewController 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    self.navigationItem.titleView = self.searchBar; 
} 

- (void) searchBarTextDidBeginEditing: (UISearchBar*) searchBar { 
    [searchBar setShowsCancelButton: YES animated: YES]; 
} 

@end 

Si tratta di un cambiamento intenzionale in iOS 7 che ho perso nella documentazione? Se sì, quale dovrebbe essere l'alternativa?

In caso contrario, ho fatto un errore nel mio codice?

+0

Hai impostato il delegato per UISearchBar? – ppaulojr

+2

Sì, ho impostato il delegato in Interface Builder e 'searchBarTextDidBeginEditing:' viene chiamato come previsto. Altrimenti non funzionerebbe su iOS 6. – Codo

risposta

14

Sembra che si sta facendo tutto correttamente, ma a quanto pare Apple ha cambiato alcune cose in giro in iOS 7. According to this SO question in iOS 7 il pulsante di annullamento non viene visualizzato su un UISearchBar incorporato in un UINavigationBar.

In base allo developer documentation, la proprietà showsCancelButton potrebbe avere un effetto leggermente diverso rispetto al metodo setShowsCancelButton:Animated. Prova a fare questo:

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

Non sono sicuro se ciò avrà alcun impatto. Si potrebbe anche provare a mettere il codice in un metodo delegato diversa:

- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar; // return NO to not become first responder 
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar; // called when text starts editing 

Si consiglia inoltre di checkout il iOS 7 changelog. Sembra che Apple abbia cambiato il comportamento o un UISearchDisplayController/UISearchBar quando aggiunto a un UINavigationBar. Dai un'occhiata all'ultimo punto elenco sotto la sezione UIKit (anche se non è chiaro esattamente cosa è stato cambiato).


Si potrebbe anche voler provare a utilizzare uno UISerachDisplayController. Quello che potrebbe essere ancora più semplice è incorporare UISearchBar nell'intestazione di UITableView.

+1

"la proprietà showsCancelButton è diversa da setShowsCancelButton: Metodo animato" - dove lo leggi nei documenti? Il metodo è un modo per impostare la proprietà con l'animazione. – Bryan

+0

Grazie per tutte le idee proposte. Non riesco a confermare che 'showsCancelButton' e' setShowsCancelButton: animated: 'non siano correlati. Se utilizzo il tuo codice, il problema persiste su iOS 7 e l'animazione su iOS 6 non funziona più. Spostare il codice su un diverso metodo delegato non ha avuto alcun effetto. L'ultimo punto elenco nel changelog di iOS 7 è un miglioramento di cui sono a conoscenza, ma non influenza il mio problema poiché non sto utilizzando 'UISearchDisplayController'. – Codo

+0

Il tuo suggerimento migliore era il riferimento all'altra domanda SO. In questo modo, viene visualizzato il pulsante Annulla. Tuttavia, lo stile della barra di ricerca cambia e il corretto dimensionamento della barra di ricerca richiederà un ulteriore sforzo. Sembra infatti che la barra di ricerca si comporti volutamente in modo diverso se è incorporata in una barra di navigazione. Sarebbe interessante apprendere l'idea alla base di questo cambiamento. – Codo

1

Sembra esserci un cambiamento tra iOS6 e iOS7 in quanto le modifiche all'interfaccia utente dai metodi xxxDidYYY a volte non funzionano e devi farlo nel metodo xxxWillYYY o in qualche codice eseguito dal ciclo eventi principale (ad es. in un blocco o dopo un breve ritardo).

Nel vostro caso, provate questo:

- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar 
{ 
    searchBar.showsCancelButton = YES; 
    return YES; 
} 
+1

Ho provato il tuo codice ma non cambia nulla. Anche se configuro la barra di ricerca per visualizzare il pulsante Annulla in ogni momento, non lo mostrerà. Quindi il problema non sembra essere correlato ai metodi dei delegati utilizzati. – Codo

2

iOS 7 è diverso con iOS 6 nella barra di navigazione, quindi se si desidera mostrare bar UISearch nella barra di navigazione, si può provare questo:

mettere il vostro UISearchBar su un UIView come questo [self.searchView addSubview self.searchBar], e impostare titleView del navigationbar al SearchView come questo self.navagitioncontroller.navigationItem.titleView = self.searchView

Spero che funziona per voi

2

Se si utilizza l'UISearchBar con un'UISearchDisplayController, si può semplicemente impostare il pulsante Annulla per mostrare, nel metodo delegato "searchDisplayControllerWillBeginSearch", in questo modo: (iOS 7 testato)

-(void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller{ 
    controller.searchBar.showsCancelButton = YES; 
} 
+0

Se UISearchBar si trova nella barra di navigazione, il pulsante Annulla non viene visualizzato. UISearchDisplayController non aiuta qui. Se UISearchBar viene inserito nell'intestazione di UITableView e utilizzato in combinazione con UISearchDisplayController, viene visualizzato il pulsante Annulla, ma non reagisce per toccare gli eventi se la vista di scorrimento di UITableView non è posizionata in alto. È un po 'un casino. – Codo

12

Ho risolto questo problema semplice, basta con l'aggiunta di rightBarButtonItem :)

self.navigationItem.titleView = self.searchBar; 
self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"Cancel", nil) style:UIBarButtonItemStylePlain target:self action:@selector(didClickCancelButton:)] autorelease]; 

Ma sicuro che controlla se la corrente versione iOS è> = 7.0, altrimenti otterrete due pulsanti "annulla" ..

BTW Questo metodo permette tu a avere il pulsante "Annulla" che ha sempre abilitato

+1

Mi piace questa risposta. Mantiene le cose semplici e non tenta di combattere il comportamento integrato e ti dà il controllo completo. – zekel

+0

Semplice ed elegante. Bel pensiero! – Aron

1

A mio parere questo è un bug. Ecco la mia soluzione. Non è perfetto, ma funziona su iOS 6 & 7. Su iOS7 il campo di testo della barra di ricerca scorre sul pulsante Annulla mentre è in dissolvenza e su iOS6 l'espansione della larghezza del campo di testo non è animata.

@interface FTViewController() 
@property(nonatomic, strong) UISearchBar *searchBar; 
@end 

@implementation FTViewController 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    self.searchBar = [[UISearchBar alloc] init]; 
    self.searchBar.delegate = self; 

    if (NSFoundationVersionNumber <= NSFoundationVersionNumber_iOS_6_1) { 
     // iOS 6.1 and older (only tested on 6.1) 
     [self.searchBar sizeToFit]; 
     self.searchBar.backgroundImage = nil; 
    } 

    self.navigationItem.titleView = self.searchBar; 
} 

-(void)cancelBarButtonItemClicked:(id)sender 
{ 
    [self searchBarCancelButtonClicked:self.searchBar]; 
} 

-(void)searchBarCancelButtonClicked:(UISearchBar *)searchBar 
{ 
    [searchBar resignFirstResponder]; 
    [self.navigationItem setRightBarButtonItem:nil animated:YES]; 
} 

-(BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar 
{ 
    UIBarButtonItem *cancelBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancelBarButtonItemClicked:)]; 
    [self.navigationItem setRightBarButtonItem:cancelBtn animated:YES]; 

    return YES; 
} 
@end 
1

ci sono due opzioni:

  1. aggiungere una barra di ricerca come una visualizzazione secondaria per uiviewcontroller.view e nascondere una barra di navigazione se i bisogni
  2. Aggiungi un pulsante di annullamento per uiviewcontroller.navigationItem.rightBarButtonItem

la mia preferenza è la seconda, ma sembra più nativa con la prima.

+0

Perché avevo altri elementi del pulsante della barra di navigazione che dovevano essere visualizzati, sono andato con l'opzione 2. – DonnaLea

1

Si tratta di un bug corretto a partire da 7.1.

Problemi correlati