UICollectionView thay đổi dữ liệu hoạt ảnh


83

Trong Dự án của tôi, tôi sử dụng UICollectionView để hiển thị một lưới các biểu tượng.

Người dùng có thể thay đổi thứ tự bằng cách nhấp vào một điều khiển được phân đoạn gọi tìm nạp từ dữ liệu cốt lõi với NSSortDescriptor khác nhau.

Lượng dữ liệu luôn giống nhau, chỉ kết thúc ở các phần / hàng khác nhau:

- (IBAction)sortSegmentedControlChanged:(id)sender {

   _fetchedResultsController = nil;
   _fetchedResultsController = [self newFetchResultsControllerForSort];

   NSError *error;
   if (![self.fetchedResultsController performFetch:&error]) {
       NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
   }

   [self.collectionView reloadData];
}

Vấn đề là reloadData không làm động thay đổi, UICollectionView chỉ xuất hiện với dữ liệu mới.

Tôi có nên theo dõi ô indexPath nào trước và sau khi thay đổi và sử dụng [self.collectionView moveItemAtIndexPath: toIndexPath:] để thực hiện hoạt ảnh cho thay đổi hay có phương pháp nào tốt hơn không?

Tôi không tham gia nhiều vào collectionViews phân lớp nên mọi sự trợ giúp sẽ rất tuyệt ...

Cảm ơn, Bill.


Bạn đã thử gói reloadDatacuộc gọi đó trong một khối hoạt hình chưa?
simon

Câu trả lời:


71

reloadData không tạo hoạt ảnh, cũng như không làm như vậy một cách đáng tin cậy khi được đặt trong khối hoạt ảnh UIView. Nó muốn nằm trong một khối UICollecitonView PerformBatchUpdates, vì vậy hãy thử một cái gì đó giống như:

[self.collectionView performBatchUpdates:^{
    [self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:0]];
} completion:^(BOOL finished) {
    // do something on completion 
}];

5
vâng, điều đó có vẻ hiệu quả, nhưng chỉ khi bạn có lưu số phần ... nếu không, tôi đang nhận được "số phần không hợp lệ. Số phần có trong chế độ xem bộ sưu tập sau khi cập nhật (10) phải bằng số các phần có trong dạng xem bộ sưu tập trước khi cập nhật (16) ". Tôi phải chèn / xóa các phần theo cách thủ công ... dù sao cũng được chấp nhận! Cảm ơn.
Nimrod

1
Bằng cách "thủ công", ý bạn là thông qua lời gọi insertSection / moveSection: toSection / deleteSection của UICollectionView? Hay cái gì khác? (xin lỗi, cho đến nay việc sử dụng UICollectionView của tôi đã có một số phần tĩnh)
Stripes

1
vâng thông qua những phương pháp đó ... hơi khó để triển khai suy nghĩ, bạn phải nhớ các đường dẫn chỉ mục trước và sau khi cập nhật, hình ảnh những gì đã xóa đã chèn hoặc di chuyển ...
Nimrod7

12
Điều này không hoạt động cho chế độ xem bộ sưu tập một phần của tôi. Tôi không gặp lỗi, nhưng nó cũng không hoạt hình. Thay thế -reloadSections:làm cho nó hoạt động.
paulmelnikow

9
Câu trả lời này không chính xác, vì đối với trường hợp của tôi, việc đặt reloadData trong PerformBatchUpdates sẽ làm ứng dụng của tôi bị lỗi và cho biết số lượng ô không giống nhau trước và sau. sử dụng reloadSitions đã giải quyết được vấn đề của tôi. Tài liệu của Apple cũng cho biết không gọi tải lại Dữ liệu trong khối hoạt ảnh
Wingzero

145

Gói -reloadDatatrong -performBatchUpdates:dường như không gây ra một cái nhìn thu một phần để animate.

[self.collectionView performBatchUpdates:^{
    [self.collectionView reloadData];
} completion:nil];

Tuy nhiên, mã này hoạt động:

[self.collectionView performBatchUpdates:^{
    [self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:0]];
} completion:nil];

9
Lưu ý từ tài liệu: Bạn không nên gọi phương thức dữ liệu tải lại ở giữa các khối hoạt ảnh nơi các mục đang được chèn hoặc xóa. Việc chèn và xóa tự động khiến dữ liệu của bảng được cập nhật một cách thích hợp.
Raphael Oliveira

tôi nghĩ rằng đây phải là câu trả lời chính xác. bởi vì điều này đã làm việc cho tôi. tôi chỉ có 1 phần và đây không phải là câu trả lời chính xác.
Mahesh Agrawal

Không hoạt động nếu bạn cũng đang chèn. Sẽ ghi đè hoạt ảnh sắp xếp.
Andres Canella

3
Cần lưu ý rằng bạn không cần self.collectionView performBatchUpdatescuộc gọi được bao bọc xung quanh reloadSectionsđể có được hình ảnh động. Trên thực tế, performBatchUpdatescuộc gọi có thể gây ra sự cố chập chờn / thay đổi kích thước ô vô tình trong một số trường hợp.
Paul Popiel

1
Hoặc chỉ [self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:0]]; reloadSectionstrong chế độ xem bộ sưu tập hoặc chế độ xem bảng sẽ làm như vậy với hoạt ảnh.
bauerMusic

67

Đây là những gì tôi đã làm để tạo hoạt ảnh tải lại TẤT CẢ CÁC PHẦN:

[self.collectionView reloadSections:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, self.collectionView.numberOfSections)]];

Swift 3

let range = Range(uncheckedBounds: (0, collectionView.numberOfSections))
let indexSet = IndexSet(integersIn: range)
collectionView.reloadSections(indexSet)

8

Đối với người dùng Swift, nếu chế độ xem bộ sưu tập của bạn chỉ có một phần:

self.collectionView.performBatchUpdates({
                    let indexSet = IndexSet(integersIn: 0...0)
                    self.collectionView.reloadSections(indexSet)
                }, completion: nil)

Như đã thấy trên https://stackoverflow.com/a/42001389/4455570


3

Tải lại toàn bộ chế độ xem bộ sưu tập bên trong một performBatchUpdates:completion:khối sẽ tạo ra hoạt ảnh trục trặc cho tôi trên trình mô phỏng iOS 9. Nếu bạn có một khối cụ thể UICollectionViewCellbạn muốn xóa hoặc nếu bạn có đường dẫn chỉ mục của nó, bạn có thể gọi deleteItemsAtIndexPaths:khối đó. Bằng cách sử dụng deleteItemsAtIndexPaths:, nó tạo ra một hình ảnh động mượt mà và đẹp mắt.

UICollectionViewCell* cellToDelete = /* ... */;
NSIndexPath* indexPathToDelete = /* ... */;

[self.collectionView performBatchUpdates:^{
    [self.collectionView deleteItemsAtIndexPaths:@[[self.collectionView indexPathForCell:cell]]];
    // or...
    [self.collectionView deleteItemsAtIndexPaths:@[indexPath]];
} completion:nil];

1
Chỉ muốn đề cập đến một thứ đã giải quyết được vấn đề sự cố trong trường hợp của tôi, hãy cập nhật nguồn dữ liệu (tức là số phần / mục) trước khi gọi performanceUpdates trên chế độ xem bộ sưu tập.
ViruMax

Hoạt ảnh là từ các hoạt động khác; có, và chưa bao giờ DƯỚI BẤT KỲ KẾT THÚC NÀO là hoạt ảnh cho dữ liệu tải lại. insertItems chèn theo thứ tự tăng dần và được thực hiện SAU KHI cập nhật; deleteItems thì ngược lại.
James Bush

1

Văn bản trợ giúp cho biết:

Gọi phương thức này để tải lại tất cả các mục trong dạng xem bộ sưu tập. Điều này khiến chế độ xem bộ sưu tập loại bỏ mọi mục hiện đang hiển thị và hiển thị lại chúng. Để hiệu quả, chế độ xem bộ sưu tập chỉ hiển thị các ô và chế độ xem bổ sung có thể nhìn thấy. Nếu dữ liệu thu thập bị thu hẹp do tải lại, chế độ xem bộ sưu tập sẽ điều chỉnh độ lệch cuộn của nó cho phù hợp. Bạn không nên gọi phương thức này ở giữa các khối hoạt ảnh nơi các mục đang được chèn hoặc xóa. Việc chèn và xóa tự động khiến dữ liệu của bảng được cập nhật một cách thích hợp.

Tôi nghĩ phần quan trọng là "khiến chế độ xem bộ sưu tập loại bỏ bất kỳ mục nào hiện đang hiển thị". Nó sẽ làm sinh động chuyển động của các mục mà nó đã loại bỏ như thế nào?


Chính xác, nó không phải là. reloadData là một hoạt động kép, ít hoạt ảnh; đầu tiên đó là thao tác xóa, sau đó là thao tác chèn.
James Bush
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.