2013-09-28 12 views
20

W aplikacji, która ma działać na iOS 6 i iOS 7, przycisk anulowania paska wyszukiwania osadzonego na pasku nawigacji nie jest już wyświetlany, jeśli aplikacja działa na iOS 7. na iOS 6 działa.iOS 7 nie pokazuje przycisku anulowania paska wyszukiwania w pasku nawigacji

Pasek wyszukiwania jest w widoku tytułowym pasku nawigacyjnym i przycisk anulować powinny być dostępne, jeśli pasek wyszukiwania staje się pierwszym responder:

iOS 7

enter image description here

iOS 6

enter image description here

w izolowanym testowym przypadku kod jest bardzo prosty:

@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 

Czy jest to celowe zmiany w iOS 7, że brakowało mi w dokumentacji? Jeśli tak, to co ma być alternatywą?

Jeśli nie, czy popełniłem błąd w moim kodzie?

+0

Czy ustawiłeś delegata dla UISearchBar? – ppaulojr

+2

Tak, ustawiłem delegata w konstruktorze interfejsów i 'searchBarTextDidBeginEditing:' jest wywoływany zgodnie z oczekiwaniami. W przeciwnym razie nie działałoby na iOS 6. – Codo

Odpowiedz

14

Wygląda na to, że robisz wszystko poprawnie, ale najwyraźniej Apple zmieniło wokół pewnych rzeczy w iOS 7. According to this SO question w iOS 7 przycisk Anuluj nie pojawia się na UISearchBar osadzony w UINavigationBar.

Według właściwości developer documentation właściwość showsCancelButton może mieć nieco inny efekt niż metoda setShowsCancelButton:Animated. Spróbuj to zrobić:

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

Nie jestem pewien, czy to będzie miało jakikolwiek wpływ. Można również spróbować umieszczenie kodu w inny sposób Delegat:

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

Można też do kasy z iOS 7 changelog. Wygląda na to, że Apple zmienił zachowanie lub /UISearchBar po dodaniu do UINavigationBar. Spójrz na ostatni punkt wypunktowania w sekcji UIKit (chociaż nie jest jasne, co dokładnie zostało zmienione).


Możesz również spróbować użyć urządzenia UISerachDisplayController. Co może być jeszcze łatwiejsze to osadzenie UISearchBar w nagłówku UITableView.

+1

"Właściwość showsCancelButton różni się od metody setShowsCancelButton: Animated" - gdzie to czytasz w dokumentacji? Ta metoda służy do ustawiania właściwości za pomocą animacji. – Bryan

+0

Dziękuję za wszystkie proponowane pomysły. Nie mogę potwierdzić, że 'showsCancelButton' i' setShowsCancelButton: animated: 'nie są powiązane. Jeśli użyję Twojego kodu, problem będzie występował w systemie iOS 7, a animacja na iOS 6 przestanie działać. Przeniesienie kodu na inne metody delegatów również nie miało żadnego efektu. Ostatni punkt wypunktowania w dzienniku zmian dla systemu iOS 7 to ulepszenie, o którym jestem świadomy, ale nie ma to wpływu na mój problem, ponieważ nie używam 'UISearchDisplayController'. – Codo

+0

Twoja najlepsza wskazówka była odniesieniem do innego pytania SO. W ten sposób pojawi się przycisk anulowania. Zmiana stylu paska wyszukiwania i odpowiednie ustawienie paska wyszukiwania będą wymagały dodatkowego wysiłku. Wygląda to tak, jakby pasek wyszukiwania celowo zachowywał się inaczej, jeśli jest osadzony w pasku nawigacji. Interesujące byłoby poznanie idei stojącej za tą zmianą. – Codo

1

Wygląda na to, że pomiędzy iOS6 i iOS7 zachodzi zmiana w tym, że zmiany w interfejsie użytkownika z metod xxxDidYYY czasami nie działają, i trzeba to zrobić w metodzie xxxWillYYY lub w kodzie wykonanym z głównej pętli zdarzeń (np. w bloku lub po krótkim opóźnieniu).

W twoim przypadku, spróbuj tego:

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

Próbowałem twój kod, ale nic nie zmienia. Nawet jeśli skonfiguruję pasek wyszukiwania tak, aby cały czas wyświetlał przycisk anulowania, nie będzie go pokazywał. Problem nie wydaje się być związany ze stosowanymi metodami delegowanymi. – Codo

2

iOS 7 jest inny z iOS 6 w pasku nawigacyjnym, więc jeśli chcesz pokazać UISearch poprzeczkę w pasku nawigacyjnym, możesz spróbować tego:

umieścić UISearchbar na UIView jak ten [self.searchView addSubview self.searchBar] i ustaw titleView w navigationbar do swojej searchView jak ten self.navagitioncontroller.navigationItem.titleView = self.searchView

Nadzieję, że pracuje dla Ciebie

2

Jeśli używasz UISearchBar z UISearchDisplayController, można po prostu ustawić przycisk Anuluj, aby pokazać, w „searchDisplayControllerWillBeginSearch” metody delegata, tak jak poniżej: (iOS 7 przetestowane)

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

Jeśli pasek UISearchB znajduje się na pasku nawigacji, przycisk anulowania nie jest wyświetlany. UISearchDisplayController nie pomaga tutaj. Jeśli UISearchBar jest umieszczany w nagłówku UITableView i używany w połączeniu z UISearchDisplayController, to przycisk anulowania jest pokazywany, ale nie reaguje na stuknięcia zdarzeń, jeśli widok przewijania UITableView nie znajduje się na samym szczycie. To trochę bałaganu. – Codo

12

mam rozwiązać ten problem prosta, po prostu dodając rightBarButtonItem :)

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

Ale na pewno trzeba sprawdzić, czy aktualna wersja iOS jest> = 7,0, inaczej dostaniesz dwa przyciski „Cancel” ..

BTW metoda ta pozwala do mieć przycisk "anuluj", który zawsze włączał

+1

Podoba mi się ta odpowiedź. Utrzymuje rzeczy proste i nie próbuje walczyć z wbudowanym zachowaniem i zapewnia pełną kontrolę. – zekel

+0

Prosty i elegancki. Ładne myślenie! – Aron

1

Moim zdaniem jest to błąd. Oto moje obejście. Nie jest doskonały, ale działa zarówno na iOS 6 & 7. Na iOS7 pole tekstowe paska wyszukiwania przesuwa się nad przyciskiem anulowania, gdy zanika, aw systemie iOS6 rozszerzenie szerokości pola tekstowego nie jest animowane.

@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

Istnieją dwie opcje:

  1. dodać pasek wyszukiwarki jak podrzędny do uiviewcontroller.view i ukryć pasek nawigacyjny, jeżeli potrzeby
  2. przycisk Dodaj anulować uiviewcontroller.navigationItem.rightBarButtonItem

Moja preferencja jest druga, ale wygląda bardziej naturalnie w porównaniu z pierwszą.

+0

Ponieważ miałem inne elementy przycisku paska nawigacji, które wymagały wyświetlania, wybrałem opcję 2. – DonnaLea

1

Naprawdę jest to błąd, który został naprawiony od wersji 7.1.

Powiązane problemy