2013-07-20 17 views
20

Ich möchte Elemente in meinem UICollectionView animieren, um anzuzeigen, wie der Benutzer durch die Liste scrollt (ich verwende eine Unterklasse von UICollectionViewFlowLayout).UICollectionVIEW: Animiere Zellen beim Scrollen in

ich die Position im Layout Manager angeben, was würde Ich mag Lage sein, auch ein erstes transformieren und haben, dass zum richtigen Zeitpunkt in einer Animation angewandt (wenn die Zelle zuerst auf dem Bildschirm erscheint) zu tun ist, zu spezifizieren. Um den Effekt zu sehen, den ich meine, sieh dir die Google Plus App auf iOS an. Idealerweise eine andere Transformation, abhängig vom Ort der Zelle.

Ich kann nicht finden, einen Weg zu finden, wenn eine Zelle angezeigt wird (kein Äquivalent von willDisplayCell, wie es auf UITableView ist) oder irgendwelche Hinweise auf, wo dafür zu gehen.

Irgendwelche Vorschläge?

Sie können nur über die Animation in Google Plus in diesem Screenshot entziffern: Example in the Google Plus App

Auch auf dem iPad einen Blick auf iPhoto nehmen. Ich weiß nicht, ob sie eine UIcollectionView verwenden (wahrscheinlich nicht, wie es bei iOS5 funktioniert), aber das ist die Art, wenn ich nach einem Effekt suche, die Fotos scheinen von rechts hereinzufliegen.

+0

Hey haben Sie endete für die eine Antwort bekommen? Ich versuche, das gleiche Verhalten zu implementieren, wird Ihre Hilfe zu schätzen wissen. –

+0

Nein, tut mir leid - ich benutzte eine Standard-Scroll-Ansicht. – Marc

+0

@JackKapow, habe ich unten eine Antwort geschrieben, die nützlich sein könnte. – Cezar

Antwort

36

Sie können diesen Effekt unabhängig von einem benutzerdefinierten Layout erzielen.

soll, wird aus der Warteschlange entfernt innen collectionView:cellForItemAtIndexPath:

Wenn eine Zelle Der Code Animation geht, wird seine frame zu setzen, was in Ihrem Layout angegeben ist. Sie können es in einer temporären Variablen als letzte frame für die Zelle speichern. Sie können dann cell.frame auf eine Ausgangsposition außerhalb des Bildschirms einstellen und dann zur gewünschten Endposition animieren. Etwas entlang der Linien von:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { 

    UICollectionView *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath]; 

    CGRect finalCellFrame = cell.frame; 
    //check the scrolling direction to verify from which side of the screen the cell should come. 
    CGPoint translation = [collectionView.panGestureRecognizer translationInView:collectionView.superview]; 
    if (translation.x > 0) { 
     cell.frame = CGRectMake(finalCellFrame.origin.x - 1000, - 500.0f, 0, 0); 
    } else { 
     cell.frame = CGRectMake(finalCellFrame.origin.x + 1000, - 500.0f, 0, 0); 
    } 

    [UIView animateWithDuration:0.5f animations:^(void){ 
     cell.frame = finalCellFrame; 
    }]; 

    return cell; 
} 

Der obige Code wird animieren Zellen auf einer horizontalen UICollectionView, vom oberen Rand des Bildschirms kommt, und von beiden Seiten, abhängig von der Bewegungsrichtung. Sie können auch die aktuelle indexPath überprüfen, damit Zellen von verschiedenen Positionen in komplizierteren Layouts animiert werden, andere Eigenschaften zusammen mit dem Rahmen animieren oder eine Transformation anwenden.

+0

Hey! Vielen Dank ! Ich habe ein bisschen damit gespielt und jetzt sieht es gut aus! Ich werde Sie wissen lassen, wenn ich irgendwelche Probleme finde, Danke allot !!!! –

+0

Haben Sie eine Idee, wie Sie es nur einmal animieren können? Ich meine, wenn ich nur zum ersten Mal nach unten scrolle, möchte ich, dass es animiert - und dann möchte ich nur neue Zellen animieren (genau wie in Google +) –

+2

Ich weiß, was du meinst. In Google + wird wahrscheinlich animiert, wenn neuer Inhalt in die CollectionView-Datenquelle eingefügt wird. Um das erneute Animieren beim Scrollen zu verhindern, müssen Sie wahrscheinlich ein Array von Flags speichern und ihre Werte für jeden animierten indexPath festlegen. Wenn Sie eine Zelle für einen bestimmten Indexpfad aus der Warteschlange nehmen, überprüfen Sie das Array, um zu sehen, ob Sie animieren sollten. – Cezar

6

Sie müssen initialLayoutAttributesForAppearingItemAtIndexPath: in Ihrem Sammlungsansichtslayout überschreiben. Hier können Sie ein beliebiges Attribut für das Element des Layoutattributs (einschließlich der Transformation) festlegen, das nach dem Erscheinen der Zelle zu den tatsächlichen Attributen animiert wird.

Wenn das Standard-Layoutattribut-Objekt Ihnen nicht genügend Optionen bietet, können Sie es unterklassifizieren, zusätzliche Attribute hinzufügen und applyLayoutAttributes: in Ihrer Zelle überschreiben, um die zusätzlichen Eigenschaften aufzunehmen.

Dies funktioniert nur, wenn Sie der Sammlungsansicht Zellen hinzufügen.

Um Transformationen auf Zellen anzuwenden, während Sie in der Sammlungsansicht nach unten scrollen, würde ich sie entweder direkt auf die Zelle anwenden (unter cellForItem ...) oder in den Layoutattributen, vielleicht eine Eigenschaft namens initialTransform. Wenn Sie die Layoutattribute auf die Zelle anwenden, überprüfen Sie die initialTransform, wenden Sie sie an, legen Sie sie dann auf identity fest und lösen Sie eine Animation aus, um zur Identitätstransformation zu gelangen. Sie wird also nur angewendet, wenn die Zelle zum ersten Mal gescrollt wurde Bildschirm. Ich habe so etwas nicht implementiert, es ist nur eine Vermutung, wie ich es machen würde.

+0

Wenn ich hier einen Haltepunkt setze, wird er nur aufgerufen, wenn sich der Bildschirm dreht. Die Kopfzeilenkommentare scheinen dies ebenfalls zu verdeutlichen. Gibt es noch etwas, das ich konfigurieren muss? Ich untergliedere UICollectionViewFlowLayout. – Marc

+0

Es sollte beim Hinzufügen von Elementen zur Ansicht oder beim Scrollen aufgerufen werden. – jrturton

+2

Gemäß den Dokumenten wird diese Methode aufgerufen, wenn sich die Daten ändern, oder wenn die Sammlungsansicht neu gezeichnet werden muss, nicht beim Scrollen - es sei denn, ich mache etwas falsch? Können Sie bestätigen, dass dieser Rückruf beim Scrollen ausgelöst wird? Quote „** Wenn die Daten in der Sammlung Ansicht Änderungen und Artikel sind eingefügt oder gelöscht werden soll, fragt die Sammlungsansicht Objekt auf das Layout die Layoutinformationen zu aktualisieren. **“ Von http://developer.apple. com/library/ios/documentation/uikit/Referenz/UICollectionViewLayout_class/Reference/Reference.html – Marc

3

Wie Marc in einem Kommentar erwähnt, dass er am Ende eine Bildlaufansicht verwendet, möchte ich zeigen, wie man es mit einer Standardtabellenansicht macht. Es ist nicht der gleiche Effekt wie in Google +, aber könnte leicht angepasst werden.

-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static CGFloat duration = .5; 
    static NSUInteger xOffset = 50; 
    static NSUInteger yOffset = 200; 
    if(scrollDirection == STAScrollDirectionDown && lastAnimatedIndex < indexPath.row) 
    { 
     cell.frame = CGRectMake(cell.frame.origin.x - xOffset, cell.frame.origin.y+yOffset, cell.frame.size.width, cell.frame.size.height); 
     [UIView animateWithDuration:duration 
         animations:^{ 
      cell.frame = CGRectMake(cell.frame.origin.x + xOffset, cell.frame.origin.y - yOffset, cell.frame.size.width, cell.frame.size.height); 
     } completion:^(BOOL finished) { 
      lastAnimatedIndex = indexPath.row; 
     }]; 
    } 
} 

Kurz vor der Zelle angezeigt wird, wir einen Offset (und gegebenenfalls eine Rotation) zu jeder Zelle zugeordnet werden, und, als wir animieren es zurück auf die vorherigen Einstellungen.


ein wenig spannendes Beispiel:

-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    CATransform3D rotation = CATransform3DMakeRotation((90.0*M_PI)/180, .0, 0.5, 0.5); 
    cell.contentView.alpha = 0.8; 
    cell.contentView.layer.transform = rotation; 
    cell.contentView.layer.anchorPoint = CGPointMake(0, 0.5); 

    [UIView animateWithDuration:.5 
        animations:^{ 
         cell.contentView.layer.transform = CATransform3DIdentity; 
         cell.contentView.alpha = 1; 
         cell.contentView.layer.shadowOffset = CGSizeMake(0, 0); 
        } completion:^(BOOL finished) { 
        }]; 
} 
+0

Ich bin mir nicht bewusst, eine 'cellWillAppear' – vikingosegundo

+0

Sorry, ich meinte cellWillDisplay Ich habe nur den Namen mit ViewWillAppear verwechselt, überprüfen Sie dieses Bild: http://postimg.org/image/a2g02xgbl/ – Chlebta

+0

Erstellen Sie eine neue Frage, posten Sie Ihren Code, Beschreiben Sie, was Sie erreichen möchten und was Sie stattdessen sehen. – vikingosegundo

Verwandte Themen