Pertanyaan Durasi Animasi untuk UICollectionView selectItemAtIndexPath: animated: scrollPosition:


Saya telah mencoba untuk mengatur durasi (dengan metode normal yang akan saya coba) untuk menetapkan durasi animasi untuk UICollectionView's selectItemAtIndexPath:animated:scrollPosition: metode (atau scrollToItemAtIndexPath:atScrollPosition:animated: metode). Saya sudah mencoba [UIView setAnimationDuration], dan saya sudah mencoba membungkusnya dalam CATransaction. Saya tidak berhasil hingga saat ini dalam mengubah durasi animasi tersebut (walaupun saya akui saya bisa membuat kesalahan dalam logika ini).

Pikiran?

MEMPERBARUI: 

Saya telah mencoba banyak pendekatan di sini. Solusi terdekat adalah melakukan apa yang biasanya kita lakukan UIScrollView animasi (dengan mengatur animasi: argumen ke NO dan membungkusnya dalam UIView blok animasi). Ini bekerja baik-baik saja untuk scrollview. Namun, sekrup ini dengan UICollectionView proses pembuatan untuk beberapa alasan.

Saya telah menyertakan contoh di bawah ini menggunakan dua pendekatan. Setiap pendekatan mengasumsikan bahwa Anda memiliki 4 bagian dengan 4 item di setiap bagian. Selain itu, animasi menganggap Anda bergerak dari 0,0 hingga 3,3.

Menggunakan Animasi Default

Bagian dari masalah di sini tentu saja tampaknya terkait UICollectionView. Jika Anda mengambil pendekatan berikut (menggunakan opsi animasi default) - semuanya berfungsi dengan baik:

[self.collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:3 inSection:3]
                                atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally
                                        animated:YES];

Ketika ini sedang dieksekusi, setiap sel di antara sel-sel yang terlihat saat ini dan sel tujuan dibuat. Saya telah menyertakan penebangan di collectionView:cellForItemAtIndexPath: metode:

2013-05-18 09:33:24.366 DEF-CV-Testing[75463:c07] Transition
Cell Created for Index Path: <NSIndexPath 0x8913f40> 2 indexes [0, 1]
Cell Created for Index Path: <NSIndexPath 0x75112e0> 2 indexes [0, 2]
Cell Created for Index Path: <NSIndexPath 0xfe1a6c0> 2 indexes [0, 3]
Cell Created for Index Path: <NSIndexPath 0x89159e0> 2 indexes [1, 0]
Cell Created for Index Path: <NSIndexPath 0x8a10e70> 2 indexes [1, 1]
Cell Created for Index Path: <NSIndexPath 0x7510d90> 2 indexes [1, 2]
Cell Created for Index Path: <NSIndexPath 0x75112a0> 2 indexes [1, 3]
Cell Created for Index Path: <NSIndexPath 0x8915a00> 2 indexes [2, 0]
Cell Created for Index Path: <NSIndexPath 0x75111c0> 2 indexes [2, 1]
Cell Created for Index Path: <NSIndexPath 0xfe17f30> 2 indexes [2, 2]
Cell Created for Index Path: <NSIndexPath 0xfe190c0> 2 indexes [2, 3]
Cell Created for Index Path: <NSIndexPath 0xfe16920> 2 indexes [3, 0]
Cell Created for Index Path: <NSIndexPath 0x75112a0> 2 indexes [3, 1]
Cell Created for Index Path: <NSIndexPath 0xfe1a4f0> 2 indexes [3, 2]
Cell Created for Index Path: <NSIndexPath 0x75142d0> 2 indexes [3, 3]

Menggunakan Animasi Kustom

Saat membungkus scrollToItemAtIndexPath: metode dalam UIView blok animasi, item tidak dibuat dengan benar. Lihat contoh kode di sini:

[UIView animateWithDuration:5.0 delay:0.0 options:0 animations:^{
    [self.collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:3 inSection:3]
                                atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally
                                        animated:NO];
} completion:^(BOOL finished) {
    NSLog(@"Completed");
}];

Sel yang terlihat saat ini menghilang dan hanya satu tujuan yang dibuat. Saya telah menyertakan pencatatan yang sama di collectionView:cellForItemAtIndexPath: metode:

Transition
Cell Created for Index Path: <NSIndexPath 0x71702f0> 2 indexes [3, 3]
Completed

32
2018-05-16 20:58


asal


Jawaban:


Saya memiliki masalah serupa dengan UITableView yang saya pecahkan dengan kode berikut:

[CATransaction begin];
[CATransaction setCompletionBlock:onCompletion];
[CATransaction setAnimationDuration:duration];

[self.collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:3 inSection:3]
                            atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally
                                    animated:YES];

[CATransaction commit];

Tentunya, Anda tidak bisa memanggilnya animated:NO karena kode animasi di dalam metode itu penting. Menggunakan sebuah CATransaction untuk membungkus animasi yang berhasil untuk saya.


5
2018-05-22 13:56



Bagi saya ini berhasil. Jelas itu membutuhkan beberapa penyesuaian (untuk memiliki waktu yang lebih akurat dan membuatnya bergulir mundur, dari bawah ke atas. Sekarang hanya mendukung gulir vertikal dari atas ke bawah)

Hubungi sesuatu seperti ini:

[self scrollToIndexPath:[NSIndexPath indexPathForItem:40 inSection:0] withAnimationDuration:3.0f];

dan ini kodenya

-(void)scrollToIndexPath:(NSIndexPath *)path withAnimationDuration:(float)duration
{
    NSIndexPath *firstCell = [[self.collectionView indexPathsForVisibleItems] objectAtIndex:0];
    UICollectionViewLayoutAttributes *attributesForFirstCell = [self.collectionView layoutAttributesForItemAtIndexPath:firstCell];
    CGRect firstCellRect = attributesForFirstCell.frame;
    CGPoint startPoint = firstCellRect.origin;

    NSIndexPath *destinationCell = path;
    UICollectionViewLayoutAttributes *attributesForDestCell = [self.collectionView layoutAttributesForItemAtIndexPath:destinationCell];
    CGRect destCellRect = attributesForDestCell.frame;
    CGPoint destPoint = destCellRect.origin;

    self.destination = destPoint;

    float delta = destPoint.y - startPoint.y;

    float cycle = (delta / (50*duration));
    self.pass = (int)cycle + 1;

    self.myTimer = [NSTimer scheduledTimerWithTimeInterval:0.02 target:self selector:@selector(scrollView) userInfo:nil repeats:YES];
}



- (void) scrollView {

    float w = self.pass;

    CGPoint scrollPoint = self.collectionView.contentOffset;
    scrollPoint.y = scrollPoint.y + w;

    if (scrollPoint.y >= self.destination.y)
        [self.myTimer invalidate];
    [self.collectionView setContentOffset: scrollPoint animated: NO];
}

0
2018-05-25 18:35



Bagaimana jika Anda memasukkan beberapa kode scrollViewDidScroll: ?

Saya memiliki masalah serupa yang saya atasi dengan menelepon selectItemAtIndexPath:animated:scrollPosition lalu menggunakan scrollViewDidScroll: untuk menjalankan apa yang biasanya saya jalankan dalam blok penyelesaian.

Tentu saja Anda mungkin harus melacak a BOOL atau dua untuk memutuskan apakah Anda perlu melakukan apa pun scrollViewDidScroll:.


0
2017-07-23 11:46



Anda dapat melakukan ini dengan bersih dengan AnimationEngine Perpustakaan. Ini membungkus a CADisplayLink dalam sintaks animasi berbasis blok. Saya memposting jawaban sini dengan contoh kode yang menjiwai contentOffset. Anda hanya perlu melakukan konversi dari indexPath ke contentOffset.


0
2018-06-25 22:37



Saya menemukan cara untuk menggulir secara manual dan sepenuhnya melewati self.collectionView scrollToItemAtIndexPath ..

Saya juga mencoba menggunakan blok penyelesaian untuk mengulang melalui bagian yang berbeda, tetapi ini menghasilkan pengalaman tersentak.

Perhatikan bahwa contoh ini menggulir secara vertikal - Anda harus dapat mengubah ini untuk menggulir secara horizontal. Anda juga mungkin harus menyesuaikan offset sehingga scrolling berhenti di lokasi yang diinginkan. Sekali lagi, saya terkejut bahwa API tidak menawarkan cara untuk mengendalikan kecepatan.

-(void)scrollMethod {

    // Find the point where scrolling should stop.
    UICollectionViewLayoutAttributes *attr = [self.collectionView layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForItem:3 inSection:3]];

    CGRect cellRect = attr.frame;

    self.source = self.collectionView.frame.origin;
    self.destination = cellRect.origin;
    self.myTimer = [NSTimer scheduledTimerWithTimeInterval:0.001 target:self selector:@selector(scrollOn) userInfo:nil repeats:YES];

}

-(void)scrollOn {
    self.collectionView.contentOffset = self.source;
    // If we have crossed where we need to be, quit the timer
    if ( self.source.y > self.destination.y)
        [self.myTimer invalidate];

    self.source = CGPointMake(self.source.x, self.source.y+1);
}

-1
2018-05-20 17:33



Solusi yang sebenarnya adalah Anda perlu melakukan scrollToItemAtIndexPath ini dalam antrian utama. sehingga hanya Anda yang bisa mendapatkan kerja aktualnya.

Kode contoh:

 dispatch_async(dispatch_get_main_queue(), ^{

    [collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:YES];

});


-2
2018-02-10 05:51