2014-04-26 19 views
8

Próbuję dodać wyszukiwanie do mojego UITableViewController przez UISearchDisplayController, ale widzę bardzo dziwne usterki animacji, gdy wyszukiwanie zaczyna się i kończy.iOS 7 UISearchDisplayController Trzaskanie animacji

Na iPhonie animacja na pasku nawigacyjnym działa dobrze. Jednak po zakończeniu wyszukiwania pasek nawigacyjny pozostaje w tyle za paskiem wyszukiwania podczas animacji. Spowoduje to wyświetlenie białego paska między paskiem nawigacji a paskiem wyszukiwania. Na iPadzie animacje są całkowicie pomieszane.

iPhone video

i

iPad video

Jak pokazują powyższe wideo, aplikacje free nie cierpią z powodu tych trzasków animacji. Czy ktokolwiek ma jakieś pomysły, co powoduje problemy?

Tworzę UISearchDisplayController z następującym wewnątrz kontrolera widoku "Master".

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    UISearchBar* searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 44.0)]; 
    searchBar.delegate = self; 
    self.tableView.tableHeaderView = searchBar; 

    self.searchController = [[UISearchDisplayController alloc] initWithSearchBar:searchBar contentsController:self]; 
    self.searchController.delegate = self; 
    self.searchController.searchResultsDataSource = self; 
    self.searchController.searchResultsDelegate = self; 
} 

Próbowałem też robi to za pomocą obrazkowa ale występują usterki sama animacja.

+0

Czy dzieje się to również na rzeczywistym urządzeniu? – Mario

+0

Nie używam UISearchDisplayController w moim kodzie z powodu tego rodzaju problemu, a także słabej możliwości dostosowywania przy wyświetlaniu wyników w Popover. Zobacz ten wpis na blogu. Może pomóc w naprawieniu tego zachowania: http://petersteinberger.com/blog/2013/fixing-uisearchdisplaycontroller-on-ios-7/ – Cezar

+0

@Mario tak, dzieje się to na urządzeniu. – Rick

Odpowiedz

1

rozwiązanie dla non-półprzezroczystego paska nawigacyjnego (mniej kodu, mniej uniwersalności)

biały glitch widzisz to tableview na kolor tła, który jest widoczny przez szczelinę między paska nawigacyjnego i searchbar. Luka jest zdecydowanie niedopatrzenie dewelopera Apple.

więc rozwiązanie wygląda tak:

- (void) searchDisplayControllerWillEndSearch:(UISearchDisplayController *)controller 
{ 
    UIView *topTableViewBG = [[UIView alloc] initWithFrame:CGRectMake(0, -64, CGRectGetWidth(self.tableView.bounds), 64)]; 
    topTableViewBG.backgroundColor = self.navigationController.navigationBar.backgroundColor; 
    topTableViewBG.tag = 1234567; 
    [self.tableView insertSubview:topTableViewBG belowSubview:self.tableView.tableHeaderView]; 
} 
- (void)searchDisplayControllerDidEndSearch:(UISearchDisplayController *)controller 
{ 
    [[self.tableView viewWithTag:1234567] removeFromSuperview]; 
} 

tu dodać własny widok tuż pod paskiem wyszukiwania. Zdarza się to tuż przed przejściem do normalnego VC. Widok jest umiejscowiony w specjalnym punkcie, tak aby pokrywał lukę między paskiem nawigacyjnym a paskiem wyszukiwania. Po zakończeniu przejścia usuwam niestandardowy widok.

UPDATE: Roztwór uniwersalny (dodatkowy kod bardziej uniwersalności)

Rozwiązanie powyższe jest dobra tylko wtedy, gdy nie jest przezroczyste navbar. W przypadku półprzezroczystego navbara istnieje wyzwanie, aby znaleźć właściwy kolor dla naszego widoku "gap-stopper". Ale gdy tylko będziemy mogli zmienić kolor paska wyszukiwania, możemy użyć koloru paska wyszukiwania dla gap-stopper.

Pozwala wprowadzić pewne zmiany do naszego kodu

Po pierwsze, musimy non-półprzezroczysty searchbar, więc ustawić obraz tła do paska wyszukiwania:

UISearchBar *searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)]; 
[searchBar setBackgroundImage:[UIImage pixelImageWithColor:SEARCHBAR_GRAY_COLOR] forBarPosition:UIBarPositionAny barMetrics:UIBarMetricsDefault]; 
searchBar.delegate = self; 
self.tableView.tableHeaderView = searchBar; 

Oto metoda kategoria UIImage, który został użyty powyżej :

+ (UIImage *)pixelImageWithColor:(UIColor *)color { 
    CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB(); 
    CGContextRef ctx = CGBitmapContextCreate (NULL, 1, 1, 8, 0, cs, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrderDefault); 
    CGColorSpaceRelease (cs); 

    CGContextSetFillColorWithColor (ctx, color.CGColor); 
    CGContextFillRect (ctx, CGRectMake (0.0f, 0.0f, 1.0f, 1.0f)); 
    CGImageRef cgImage = CGBitmapContextCreateImage (ctx); 
    CGContextRelease (ctx); 

    UIImage *result = [UIImage imageWithCGImage:cgImage]; 
    CGImageRelease (cgImage); 
    return result; 
} 

Następnie zmieniamy searchDisplayControllerWillEndSearch metody:

- (void) searchDisplayControllerWillEndSearch:(UISearchDisplayController *)controller 
{ 
    UIView *topTableViewBG = [[UIView alloc] initWithFrame:CGRectMake(0, -64, CGRectGetWidth(self.tableView.bounds), 64)]; 
    topTableViewBG.backgroundColor = SEARCHBAR_GRAY_COLOR; 
    topTableViewBG.tag = 1234567; 
    [self.tableView insertSubview:topTableViewBG belowSubview:self.tableView.tableHeaderView]; 
} 

i wreszcie metoda searchDisplayControllerDidEndSearch pozostaje niezmieniona:

- (void)searchDisplayControllerDidEndSearch:(UISearchDisplayController *)controller 
{ 
    [[self.tableView viewWithTag:1234567] removeFromSuperview]; 
} 

Szczerze to rozwiązanie jest bardziej uniwersalny i wygląda o wiele ładniej niż jednego mam opisanego w pierwszej części odpowiedzi.

+1

To pomaga, ale nie naprawia go całkowicie. Kolor tła paska nawigacyjnego ustawia się za pomocą '-barTintColor', który jest dość trudny do dopasowania przy użyciu półprzezroczystego paska. Nie działa również, jeśli używasz obrazu tła. FWIW, wygląda na to, że został naprawiony w iOS 8. – Rick

+0

@Rick Mam zaktualizowaną odpowiedź na przezroczystą obudowę typu navbars –

1

znaleźć najlepsze rozwiązanie dla mnie, to wygląda dokładnie tak, jak trzeba, używam Swift ale jeśli trzeba można łatwo przetłumaczyć go do Objective-C

self.edgesForExtendedLayout = .None 

let barBacgroundView = UIView(frame: CGRectMake(0, 0, self.view.frame.size.width, 64)) 
barBacgroundView.backgroundColor = self.tableView.backgroundColor 
UIApplication.sharedApplication().delegate!.window!!.insertSubview(barBacgroundView, atIndex: 0) 

wstawić ten kod w viewDidLoad() i to jest to. Mam nadzieję, że to pomaga :)