2010-05-12 12 views
11

Dodałem UITableView jako subview do niestandardowej klasy UIView, nad którą pracuję. Zauważyłem jednak, że za każdym razem, gdy przewijam stół, wywołuje on mój layout layoutSubviews. Jestem prawie pewien, że jest to widok UIScroll, który dziedziczy po stole, który faktycznie to robi, ale chciał wiedzieć, czy istnieje sposób wyłączenia tej funkcji, a jeśli nie, dlaczego tak się dzieje? Nie rozumiem, dlaczego podczas przewijania przewijania potrzebuje on swojego superwizja do układu swoich podobrazów.UIScrollview wywoływanie układu superviewsOdblanie podczas przewijania?

Kod:

@implementation CustomView 
- (id)initWithFrame:(CGRect)frame { 
    if ((self = [super initWithFrame:frame])) { 
     self.clipsToBounds = YES; 

     UITableView *tableView = [[UITableView alloc] initWithFrame:CGRectMake(0.0, 15.0, 436.0, 132.0) style:UITableViewStylePlain]; 
     tableView.dataSource = self; 
     tableView.delegate = self; 
     tableView.separatorStyle = UITableViewCellSeparatorStyleNone; 
     tableView.backgroundColor = [UIColor clearColor]; 
     tableView.showsVerticalScrollIndicator = NO; 
     tableView.contentInset = UIEdgeInsetsMake(kRowHeight, 0.0, kRowHeight, 0.0); 
     tableView.tag = componentIndex; 

     [self addSubview:tableView]; 
     [tableView release]; 
    } 
    return self; 
} 
- (void)layoutSubviews { 
    // This is called everytime I scroll the tableview 
} 

@end 

+0

Ale powiedz mi, dlaczego to zrobiłeś tak Czemu dodanie widok tabeli do widoku niestandardowego? – Manjunath

+0

Długa historia, tworzę niestandardowy PickerView, który pozwala na wielokrotny wybór i ma inny rozmiar niż standardowy. Zasadniczo wyświetla tło PickerView przekształcone z przezroczystą tabelą na górze – marchinram

+0

Czy spojrzałeś na to? Facet wydaje się mieć przeciwny problem, w tym layoucie nie jest wywoływany. Wspomniał także o poprawce, która, jeśli ją odwrócisz, może ci się przydać. :) http://stackoverflow.com/questions/728372/when-is-layoutsubviews-called – Kalle

Odpowiedz

2

Tak, UIScrollView wykonuje wywołania layoutsubviews za każdym razem, gdy przewija. Mógłbym przysiąc, że to było gdzieś w dokumentacji, ale chyba nie.

W każdym razie, dominującą ideą jest to, że UIScrollView powinien układać swoje elementy tak, aby widoki, które obecnie nie są widoczne, nie powinny być ułożone. Gdy użytkownicy przewijają widok przewijania, powinni w razie potrzeby dodawać i usuwać subviews. Zgaduję, że to jest to, czego używają TableViews do zakolejkowania komórek tabeli, które się ukrywają.

Czy jest jakikolwiek powód, dla którego należy zwrócić uwagę na wywołanie layoutsubviews?

+0

nie, uruchamiałem tam kod, którego nie powinienem był uruchamiać, to ma sens, że układa subviews, gdy zmiana pozycji w przewijanym wierszu – marchinram

+2

Masz rację, ale prawdziwy problem jest to, że przewijanie widoku przewijania uruchamia 'layoutSubviews' również w jego * widoku *, co może być zarówno kosztowne, jak i niepotrzebne. Podejrzewam, że jest to efekt uboczny zmiany granic widoku przewijania, ale równie dobrze może to być tylko błąd. – Costique

0

Nie jestem pewien, rozumiem Twojego problemu poprawnie, ale podczas przewijania tableview usuwa komórki nie pokazane z pamięci i ładuje je ponownie, gdy są przewijane z powrotem do widoczności (komórki są przydzielane na żądanie, tylko te widoczne), w efekcie robiąc to, co wydaje się opisywać.

1

Co najmniej UITableView wydaje układowi swój widok. Takie zachowanie może być problematyczne, gdy masz metodę layoutSubviews, która może być droga (np. Jeśli wywołasz JavaScript).

Szybka korekta dodaje pośredni wydział, który zapobiega wyświetlaniu podglądu przewijania przez widok przewijania. Zamiast tego utworzy układ pośredni.

To może być nieco niedoskonały, ale to powinno działać w większości przypadków:

Załóżmy UIView * intermediateView jest definiowana jako zmiennej instancji:

-(id) initWithFrame:(CGRect)frame 
{ 
    self = [super initWithFrame: frame]; 
    if (self) 
    { 
     UIScrollView * theScrollView; // = your scroll view or table view 
     intermediateView = [[[UIView alloc] initWithFrame:CGRectZero] autorelease]; 
     // Ensures your intermediate view will resize its subviews. 
     intermediateView.autoresizesSubviews = YES; 

     // Ensure when the intermediate view is resized that the scroll view 
     // is given identical height and width. 
     theScrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | 
             UIViewAutoresizingFlexibleHeight; 
     [intermediateView addSubview: theScrollView]; 

     // Ensure the frame of the scroll view is exactly the bounds of your 
     // intermediate view. 
     theScrollView.frame = bottomContainerView.bounds; 
     [self addSubview: intermediateView]; 
    } 
    return self; 
} 

-(void) layoutSubviews 
{ 
    intermediateView.frame = CGRectMake(0, 50, 42, 42); // replace with your logic 
}