2013-02-13 8 views
27

Tworzę prosty UICollectionView z włączonym mechanizmem stronicowania i wszystko działa poprawnie. Chociaż podczas przewijania do ostatniej strony liczba komórek nie jest w pełni widoczna na ekranie, a na ostatniej stronie znajdują się komórki z poprzedniej strony.Jak rozwinąć zawartość UICollectionViewSize przy włączaniu stronicowania?

Jak rozwinąć contentSize z UICollectionView, aby ostatnia strona nie zawierała żadnych komórek z poprzedniej strony?

Przykładem here: the UICollectionView przewija poziomo 6 komórek, w ten sposób:

Strona 1: cell0 - cell1 - cell2 - cell3

Scroll: CELL2-CELL3-cell4-cell5 // Nie oczekuje: Jak zmienić: cell4 - komórka 5 na stronie2.

STRESZCZENIE:

Chcę ustawić

collectionView.contentSize = numberOfPage * collectionView.frame

NIE

collectionView.contentSize = numberOfCell * (cellFrame + spacing)

+0

To nie powinno się wydarzyć. Czy możesz wstawić fragment kodu, jeśli taki jest? – Swapnil

+0

Próbuję: [collectonView setContentSize] w viewDidLoad i viewDidAppear, ale nie działa, ponieważ contentSize będzie przepisać w źródle danych. –

Odpowiedz

32

Potrzebujesz podklasy UICollectionViewLayout i zastąpisz metodę collectionViewContentSize. Podklasowałem UICollectionViewFlowLayout, więc nie musiałbym ponownie pisać całego kodu układu.

buduję siatkę 4x4, więc moja metoda wygląda następująco:

- (CGSize)collectionViewContentSize 
{  
    NSInteger itemCount = [self.collectionView numberOfItemsInSection:0]; 
    NSInteger pages = ceil(itemCount/16.0); 

    return CGSizeMake(320 * pages, self.collectionView.frame.size.height); 
} 

marginesie, podczas korzystania niestandardowy układ, tracisz możliwość, aby ustawić niektóre właściwości wyświetlacza w Konstruktor interfejsów. Można je ustawić programowo w metodzie init niestandardowej podklasy UICollectionViewLayout. Oto mój odsyłające:

- (id)init 
{ 
    self = [super init]; 
    if (self) { 
     [self setup]; 
    } 

    return self; 
} 

- (id)initWithCoder:(NSCoder *)aDecoder 
{ 
    self = [super init]; 
    if (self) { 
     [self setup]; 
    } 

    return self; 
} 

- (void)setup 
{ 
    self.itemSize = CGSizeMake(65.0f, 65.0f); 
    self.minimumLineSpacing = 15; 
    self.sectionInset = UIEdgeInsetsMake(7.5f, 7.5f, 30.0f, 7.5f); 
    [self setScrollDirection:UICollectionViewScrollDirectionHorizontal]; 
} 
+0

Powiedziano mi, że tego rodzaju rzeczy mogą spowodować ogromny ślad pamięci, ponieważ cały widok kolekcji zostanie "pokazany", a ponowne wykorzystanie komórek nie będzie możliwe. Czy to prawda? –

+0

UICollectionView jest już podklasą UIScrollView i posiadanie contentSize jest dla niej naturalne, nie sądzę, abyś musiał się martwić o ponowne użycie komórek, ponieważ wszystkie komórki nigdy nie są widoczne. –

+0

'collectionView.collectionViewLayout.collectionViewContentSize()' jest tym, czego potrzebujesz. Jeśli nie jest poprawny, po prostu 'collectionView.layoutIfNeeded()' zanim otrzymasz contentSize. –

0

Można dostosować zawartość z viewDidLayoutSubviews: m etod. Ta metoda jest wywoływana, gdy widok kolekcji i wszystkie komórki są umieszczone w view, dzięki czemu można dostosować komórkę.

+0

Nie działa, cellForItemAtIndexPath również wywołuje podczas przewijania. –

0

Myślę, że trzeba podklasę UICollectionViewLayout i utworzyć niestandardowy układ, aby poradzić sobie z takimi problemami.

2

Na poziomej stronicowania

if(CollectionView.pagingEnabled) 
{ 

    int numberOfPages = floor(collectionView.contentSize.width/
         collectionView.frame.size.width) + 1; 
          CGFloat 
    float requierdWidth=self.collectionView.frame.size.width*numberOfPages; 

    self.Layout.footerReferenceSize=CGSizeMake(requierdWidth-self.collectionView.contentSize.width,0); 
} 
1

Odpowiedź działa dobrze, choć dla naszego kodu mieliśmy jedną sekcję na stronie. Oznaczało to, że przesłonięcie dla naszej klasy układu to tylko

-(CGSize) collectionViewContentSize { 
    return CGSizeMake(CGRectGetWidth(self.collectionView.frame) * 
       [self.collectionView numberOfSections], 
       CGRectGetHeight(self.collectionView.frame)) ; 
} 
0

Mam odpowiedź, która nie wymaga żadnej podklasy.

In -viewDidLoad, obliczyć liczbę przedmiotów na stronę i liczbę stron. Zapisz te wartości we właściwościach.

self.numberOfItemsPerPage = NumberOfRows * NumberOfColumns; 
    self.numberOfPages = ceilf((CGFloat)self.items.count/(CGFloat)self.numberOfItemsPerPage); 

Następnie w -collectionView: numberOfItemsInSection: po prostu położyć na niej:

return self.numberOfItemsPerPage * self.numberOfPages; 

Będziesz oczywiście mieć więcej komórek niż treści, prawda? Więc w -collectionView: cellForItemAtIndexPath: po prostu wrócić zero dla dodatkowych komórek:

if (indexPath.item > [self.items count] - 1) { 
    //We have no more items, so return nil. This is to trick it to display actual full pages. 
    return nil; 
    } 

Nie idziesz: pełny, przewijalną ostatnią stronę. Moim zdaniem, poziomy tryb przewijania powinien być domyślnie ustawiony.

+0

Całkiem pewien, że komórka nie może być pusta :(Próbowałem tego i otrzymałem ten błąd: '*** Kończenie aplikacji z powodu nieprzechwyconego wyjątku 'NSInternalInconsistencyException', powód: 'źródło danych widoku kolekcji nie zwrócił poprawnej komórki z -collectionView: cellForItemAtIndexPath: dla ścieżki indeksu ' – taber

Powiązane problemy