2013-01-23 5 views
9

Używam UICollectionView do prezentacji siatki obrazów w aplikacji na iPhone'a (iOS6).Wyświetlanie obrazów w UICollectionView - jak uzyskać stały pionowy odstęp między obrazami?

Używam przewijania w pionie dla UICollectionView, a obrazy mają stałą szerokość i zmienną wysokość. Szerokość obrazów jest ustawiona tak, że na iPhonie wyświetla 3 kolumny obrazów. Działa to dobrze, a obrazy są wyświetlane w widoku siatki.

Jednakże, ponieważ moje obrazy mają różne wysokości, pionowy odstęp między obrazami w kolumnie zmienia i to nie wygląda bardzo dobrze, jak widać na poniższym obrazie (a makieta wykonana w HTML):

Image showing how the images are currently laid out

Zamiast tego chciałbym uzyskać bardziej płynny przepływ, w którym pionowe odstępy między obrazami w kolumnie są takie same. Poniższy makieta pokazuje, jak chciałbym go do pracy:

Example of how I would like the flow of images to work

jakieś pomysły jak rozwiązać ten problem?

Ponadto, jako pytanie dodatkowe, ktoś wie, jak rozwiązać ten sam problem, jeśli aplikacja nie została stworzona dla iOS6 (ponieważ UICollectionView jest dostępny tylko w systemie iOS6). Korzystając z komponentu innego producenta lub rozwiązując go za pomocą standardowych elementów sterujących systemu iOS.

Odpowiedz

8

Podklasa UICollectionViewFlowLayout i w tej klasie należy dodać te metody. (Uwaga ta zakłada orientację pionową, a pomija pierwszą linię, a jest to stałe 10 pikseli między nimi Zobacz:. how do you determine spacing between cells in UICollectionView flowLayout jeśli trzeba poziomą wersję

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect { 
NSArray* arr = [super layoutAttributesForElementsInRect:rect]; 
for (UICollectionViewLayoutAttributes* atts in arr) { 
    if (nil == atts.representedElementKind) { 
     NSIndexPath* ip = atts.indexPath; 
     atts.frame = [self layoutAttributesForItemAtIndexPath:ip].frame; 
    } 
} 
return arr; 
} 

- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath { 
UICollectionViewLayoutAttributes* atts = 
[super layoutAttributesForItemAtIndexPath:indexPath]; 

if (indexPath.item == 0 || indexPath.item == 1) // degenerate case 1, first item of section 
    return atts; 

NSIndexPath* ipPrev = 
[NSIndexPath indexPathForItem:indexPath.item-2 inSection:indexPath.section]; 

CGRect fPrev = [self layoutAttributesForItemAtIndexPath:ipPrev].frame; 
CGFloat rightPrev = fPrev.origin.y + fPrev.size.height + 10; 
if (atts.frame.origin.y <= rightPrev) // degenerate case 2, first item of line 
    return atts; 

CGRect f = atts.frame; 
f.origin.y = rightPrev; 
atts.frame = f; 
return atts; 
} 
+1

Dzięki za pomoc z tego dla innych, patrząc na to, rozwiązania odpowiedź pracuje w końcu skończyło się używając komponentu 3rd party zamiast https: //github.com/ptshih/PSCollectionView: To pozwoliło mi również celować w iOS5 – Jonas

+1

Rozumiałem, jak dawać odstępy, ale jak mogę ustawić rozmiar pojedynczej komórki w powyższym kod? – Satyam

+2

@Satyamsvv Zastosowanie metody delegat na UICollectionViewFlowLayout w swojej klasie ViewController (nie podklasa układ) - (CGSize) CollectionView: (UICollectionView *) CollectionView układ: (UICollectionViewLayout *) collectionViewLayout sizeForItemAtIndexPath: (NSIndexPath *) indexPath – nsuinteger

3

Dla Swift 3 tego dzieła kod dla mnie, !. włącznie przestrzeń pierwszej linii do góry ...

override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? { 
    let arr = super.layoutAttributesForElements(in: rect) 

    for atts:UICollectionViewLayoutAttributes in arr! { 
     if nil == atts.representedElementKind { 
      let ip = atts.indexPath 
      atts.frame = (self.layoutAttributesForItem(at: ip)?.frame)! 
     } 
    } 
    return arr 
} 

override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? { 
    let atts = super.layoutAttributesForItem(at: indexPath) 

    if indexPath.item == 0 || indexPath.item == 1 { 
     var frame = atts?.frame; 
     frame?.origin.y = sectionInset.top; 
     atts?.frame = frame!; 
     return atts 
    } 

    let ipPrev = IndexPath(item: indexPath.item - 2, section: indexPath.section) 

    let fPrev = self.layoutAttributesForItem(at: ipPrev)?.frame 

    let rightPrev = (fPrev?.origin.y)! + (fPrev?.size.height)! + 10 

    if (atts?.frame.origin.y)! <= rightPrev { 
     return atts 
    } 

    var f = atts?.frame 
    f?.origin.y = rightPrev 
    atts?.frame = f! 
    return atts 
} 
Powiązane problemy