2013-05-06 10 views
7

Ho un'app per iPad in cui sto utilizzando un UICollectionView e ogni UICollectionViewCell contiene solo un singolo UIImage. Attualmente sto visualizzando per 9 UIImages (3 righe * 3 colonne) per pagina, ho diverse pagine.zoom intero UICollectionView

Mi piacerebbe usare Gancellazione Gesto per ingrandire l'intero UICollectionView per aumentare/diminuire il numero di righe/colonne visualizzate per pagina e il migliore sarebbe avere una bella animazione di zoom durante il gesto di pizzicamento!

Attualmente, ho aggiunto un pizzico sul mio UICollectionView. Colgo l'evento Pinch Gesture per calcolare il numero di righe/colonne utilizzando il fattore di scala, se è cambiato, allora aggiorno la piena UICollectionView utilizzando:

[_theCollectionView performBatchUpdates:^{ 
    [_theCollectionView deleteSections:[NSIndexSet indexSetWithIndex:0]]; 
    [_theCollectionView insertSections:[NSIndexSet indexSetWithIndex:0]]; 
} completion:nil]; 

Funziona, ma non ho animazioni fluide durante la transizione.

Qualche idea? UICollectionView eredita da UIScrollView, esiste la possibilità di riutilizzare la funzione di gesture di pizzicamento di UIScrollView per raggiungere il mio obiettivo?

risposta

0

Ci scusiamo per la mia domanda da 2 centesimi, ho trovato la soluzione, molto semplice.

Nel mio PinchGesture callback ho appena fatto la seguente:

void (^animateChangeWidth)() = ^() { 
    _theFlowLayout.itemSize = cellSize; 
}; 

[UIView transitionWithView:self.theCollectionView 
        duration:0.1f 
        options:UIViewAnimationOptionCurveLinear 
       animations:animateChangeWidth 
       completion:nil]; 

Tutte le cellule del mio UICollectionView sono cambiati con successo e con una bella transition.

+4

Questo non è il modo corretto per gestire il ridimensionamento, in pratica si sta costringendo a ridisegnare l'intera collectionView, quando tale funzione è già supportata dall'inflazione del layout '[collectionView.collectionViewLayout invalidateLayout]'. Ho lasciato una risposta con una spiegazione e un esempio più approfonditi. – Can

+0

Per favore, puoi aggiungere ulteriori dettagli al riguardo? – sebastien

25

Suppongo che tu stia utilizzando l'UICollectionViewDelegateFlowLayout predefinito, giusto? Quindi assicurati di rispondere di conseguenza ai metodi delegati e, quando si verifica il gesto di pizzicare, semplicemente invalida il layout.

Per esempio, se voglio regolare le dimensioni di ogni elemento, mentre pizzicando:

@interface ViewController() <UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout> 

@property (nonatomic,assign) CGFloat scale; 
@property (nonatomic,weak) IBOutlet UICollectionView *collectionView; 

@end 

@implementation ViewController 
- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    self.scale = 1.0; 

    [self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"cell"]; 

    UIPinchGestureRecognizer *gesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(didReceivePinchGesture:)]; 
    [self.collectionView addGestureRecognizer:gesture]; 

} 

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath 
{ 
    return CGSizeMake(50*self.scale, 50*self.scale); 
} 

- (void)didReceivePinchGesture:(UIPinchGestureRecognizer*)gesture 
{ 
    static CGFloat scaleStart; 

    if (gesture.state == UIGestureRecognizerStateBegan) 
    { 
     scaleStart = self.scale; 
    } 
    else if (gesture.state == UIGestureRecognizerStateChanged) 
    { 
     self.scale = scaleStart * gesture.scale; 
     [self.collectionView.collectionViewLayout invalidateLayout]; 
    } 
} 

La proprietà self.scale è solo per lo spettacolo, è possibile applicare questo stesso concetto a qualsiasi altro attributo, questo doesn' t richiedono un beginUpdates/endUpdates perché l'utente stesso sta portando i tempi della scala.

Here's a running project, nel caso in cui si voglia vederlo in azione.

+0

+1 Grazie! Hai controllato la tua demo ed è davvero utile. Puoi guidare su come possiamo mostrare queste transizioni con una bella animazione ... Sono un novizio di UICollectionView. – Yogi

+1

Ottima risposta, curioso di sapere se cosa fare se il layout è più "fisso" e si desidera ingrandire/ridurre e spostarsi (non spostare gli elementi). Pensa ad una mappa, ad esempio se gli oggetti sulla mappa sono UICollectionCells e le piastrelle potrebbero essere viste riutilizzabili o simili. – MobileVet

+1

@MobileVet Per la mia tesi ho scritto un UICollectionViewLayout personalizzato che crea qualcosa come una mappa, ed è del tutto possibile. Se si rendono le dimensioni del contenuto che il layout della vista dell'insieme risulta più grande con un fattore di scala, è possibile avere sia lo zoom che il panning. – Can