2013-01-23 16 views
7

TleiOS 6.0: UICollectionView nie przestrzega clipsToBounds z pagingEnabled

ja wdrożenie UICollectionView (po raz pierwszy) w celu uzyskania paged poziomego przewijania widoku płytek. Chciałbym, aby każda płytka była wyświetlana w środku kadru z jej siostrzanymi kaflami częściowo widocznymi po lewej i prawej stronie (coś w rodzaju selektora stron w aplikacji Safari). Jestem zainteresowany użyciem UICollectionView, aby skorzystać z wbudowanego usuwania komórek i wolałbym nie używać obróconego UITableView.

Issue

Problem mam ze znalezieniem jest to, że podczas korzystania pagingEnabled = YES i clipsToBounds = NO The UICollectionView usuwa komórki poza ramy collectionView (nie są one w tablicy visibleCells) tak szybko jak stronicowania jest kompletna. Czy ktokolwiek może doradzić, jak uzyskać efekt wyświetlania podglądu płytek siostrzanych przy zachowaniu tej podstawowej konfiguracji? Czy podchodzę do tego niepoprawnie?

ekranu

startowe start przewijanie scrolling Koniec end

przewijanie ekran jest dokładnie poprawne. Ale na początku i na końcu chcę, żeby zielony był widoczny na niebieskich marginesach.

Oto co jest w moim AppDelegate.m (kredyt do tutsplus.com dla podstawowej konfiguracji tutaj):

#import "AppDelegate.h" 

@interface ViewController : UICollectionViewController 
@end 

@implementation ViewController 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    [self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"ID"]; 
    [self.view setBackgroundColor:[UIColor blueColor]]; 
    // pad the collection view by 20 px 
    UIEdgeInsets padding = UIEdgeInsetsMake(20.0, 20.0, 20.0, 20.0); 
    [self.collectionView setFrame:UIEdgeInsetsInsetRect(self.view.frame, padding)]; 
    // set pagingEnabled and clipsToBounds off 
    [self.collectionView setPagingEnabled:YES]; 
    [self.collectionView setClipsToBounds:NO]; 
} 

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section 
{ 
    return 5; 
} 

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath 
{ 
    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"ID" forIndexPath:indexPath]; 
    UILabel *label = [[UILabel alloc] initWithFrame:cell.bounds]; 
    label.textAlignment = NSTextAlignmentCenter; 
    label.text = [NSString stringWithFormat:@"%d", indexPath.row]; 
    [label setBackgroundColor:[UIColor greenColor]]; 
    [cell.contentView addSubview:label]; 
    return cell; 
} 
@end 

@implementation AppDelegate 
{ 
    ViewController *vc; 
} 

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{ 
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 
    // setup the UICollectionViewFlowLayout 
    UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init]; 
    layout.itemSize = CGSizeMake(280, 280); 
    layout.minimumInteritemSpacing = 0; 
    layout.minimumLineSpacing = 0; 
    layout.scrollDirection = UICollectionViewScrollDirectionHorizontal; 
    // add a custom UICollectionViewController to the window 
    vc = [[ViewController alloc] initWithCollectionViewLayout:layout]; 
    self.window.rootViewController = vc; 
    self.window.backgroundColor = [UIColor yellowColor]; 
    [self.window makeKeyAndVisible]; 
    return YES; 
} 
@end 

Odpowiedz

9

Okazało się, że rozwiązanie jest dość proste. Musiałem tylko pokryć komórki UICollectionViewCell przez wystarczającą liczbę pikseli, aby były nadal wyświetlane w ramce kolekcjiView po zakończeniu przewijania stronicowanego. Kod dowiemy się z było

layout.itemSize = CGSizeMake(300, 300); 
layout.minimumLineSpacing = -20.0; 

I podklasy z UICollectionViewFlowLayout i overrode sposób (CGSize)collectionViewContentSize zwracania nie nakładającego wielkości komórek.

+0

Odkryliśmy, że działa to dopóki nie masz 6 lub więcej komórek, w którym to momencie komórki zaczynają znikać, nawet jeśli znajdują się wewnątrz ramki widoku. Dzieje się tak, gdy dana komórka * znajduje się * za * obydwoma komórkami sąsiednimi (tutaj przestaliśmy badać). –

+0

Nie mogę wykonać tej pracy na iOS 8, w nowych rozmiarach iPhone'a i obsługując funkcję Autolayout. –

0

Nie jestem ekspertem w CollectionView, ale może to być ewentualnie zrobić z tej linii w cellForItemAtIndexPath:

[cell.contentView addSubview:label]; 

Za każdym razem, gdy jest wywoływana, do komórki dodaje się inny widok podzbioru etykiet. Albo sprawdź istniejącą etykietę lub podklasę UICollectionViewCell?

+0

Dzięki! Wypowiadanie, że nie wpływa to w ogóle na obszar obcinania, więc nie rozwiązuje podstawowego problemu, ale dobre złapanie. –

2

Dziękujemy za napiwek dotyczący stosowania ujemnego minimumLineSpacing. Stworzyłem aplikację testera, która używa komórki widoku kolekcji załadowanej z pliku XIB. Komórka ma przezroczyste tło i "wewnętrzny" widok zawartości komórki.

W ten sposób niestandardowy układ przepływu nie jest konieczny.

https://github.com/j4johnfox/CollectionViewTester

0

Będziemy chcieli również zastąpić -pointInside:withEvent: gestów przewijania, aby umożliwić rozpoczęcie poza ramy widzenia zbiórki. Robię to za pomocą właściwości UIEdgeInsets w mojej kolekcji widoku podklasy:

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event { 
    CGRect extendedBounds = UIEdgeInsetsInsetRect(self.bounds, self.touchAreaInsets); 

    return CGRectContainsPoint(extendedBounds, point); 
} 

Jeśli nie potrzebują bezpieczeństwa App Store można przesłonić _visibleBounds aby uniknąć negatywnych hacki rozstaw

- (CGRect)_visibleBounds { 
    return UIEdgeInsetsInsetRect(self.bounds, self.touchAreaInsets); 
} 

jeśli jesteś Nie za bardzo naciskasz na rozmiar kodu i potrzebujesz bezpieczeństwa w App Store, możesz również podklasę PSTCollectionView i ewentualnie zastąpić visibleBoundRects dla tego samego efektu.

Powiązane problemy