2012-11-07 40 views
66

Trong Dự án của tôi, tôi sử dụng UICollectionView để hiển thị lưới các biểu tượng.UICollectionXem thay đổi dữ liệu animate

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

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

- (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 sinh động sự thay đổi, UICollectionView chỉ bật với các dữ liệu mới .

Tôi có nên theo dõi trong đó indexPath một ô 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 hoặc có phương pháp tốt hơn không?

tôi đã không nhận được nhiều thành collectionViews subclassing vì vậy bất kỳ trợ giúp sẽ là tuyệt vời ...

Cảm ơn, Bill.

+0

Các bạn đã thử gói rằng 'reloadData' gọi trong một khối hoạt hình? – simon

Trả lời

58

tải lạiData không hoạt ảnh, cũng không đáng tin cậy khi thực hiện trong khối hoạt ảnh UIView. Nó muốn trở thành trong một khối UICollecitonView performBatchUpdates, vì vậy hãy thử một cái gì đó giống như hơn:

[self.collectionView performBatchUpdates:^{ 
    [self.collectionView reloadData]; 
} completion:^(BOOL finished) {}]; 
+4

yep, có vẻ như hoạt động, nhưng chỉ khi bạn có lưu số phần ... nếu không tôi nhận được "số lượng phần không hợp lệ. Số lượng phần chứa trong chế độ xem bộ sưu tập sau khi cập nhật (10) phải bằng với số các phần chứa trong giao diện bộ sưu tập trước khi cập nhật (16) ". Tôi phải tự chèn/xóa các phần ... dù sao cũng được chấp nhận! Cảm ơn. – Nimrod7

+1

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

+1

có thông qua các phương pháp đó ... bit của nó phức tạp để thực hiện suy nghĩ, bạn phải nhớ các đường dẫn trước và sau khi cập nhật, hình con số được chèn vào, hoặc di chuyển ... – Nimrod7

130

Bao bì -reloadData trong -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]; 
+8

Lưu ý từ tài liệu: Bạn không nên gọi lại phương thức dữ liệu ở giữa các khối hoạt ảnh nơi các mục đượ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. –

+0

tôi nghĩ rằng đây sẽ là câu trả lời đúng. bởi vì điều này làm việc cho tôi. tôi chỉ có 1 phần và điều này không hoạt động đúng. –

+0

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

2

Sự giúp đỡ đoạn Kinh thánh nói:

Gọi phương pháp này để tải lại tất cả các mục trong giao diện bộ sưu tập. Điều này làm cho chế độ xem bộ sưu tập loại bỏ mọi mục hiện có thể xem và hiển thị lại chúng. Để đạt hiệu quả, chế độ xem bộ sưu tập chỉ hiển thị các ô đó và chế độ xem bổ sung hiển thị. Nếu dữ liệu thu thập thu nhỏ do tải lại, chế độ xem bộ sưu tập sẽ điều chỉnh độ lệch cuộn tương ứng. 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 làm cho 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ỏ mọi mục hiện có thể nhìn thấy". Làm thế nào là nó sẽ animate sự chuyển động của các mặt hàng nó đã bị loại bỏ?

47

Đây là những gì tôi đã làm để animate 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) 
2

Nếu bạn muốn kiểm soát nhiều hơn và tùy biến tính năng kiểm tra this, nó có chứa một giải thích rất chi tiết về các cách khác nhau của hoạt ảnh UICollectionViewCell.

4

Tải lại toàn bộ chế độ xem bộ sưu tập bên trong khối performBatchUpdates:completion: có hoạt ảnh không ổn định đối với tôi trên trình mô phỏng iOS 9. Nếu bạn có UICollectionViewCell cụ thể bạn muốn xóa hoặc nếu bạn có đường dẫn chỉ mục, bạn có thể gọi deleteItemsAtIndexPaths: trong khối đó. Bằng cách sử dụng deleteItemsAtIndexPaths:, nó hoạt động trơn tru 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 điều đã giải quyết được sự cố trong trường hợp của tôi, cập nhật nguồn dữ liệu (ví dụ:mục/mục đếm) trước khi gọi performUpdates trên chế độ xem bộ sưu tập. – ViruMax

-2

Đối với người dùng nhanh chóng này đi kèm tiện dụng -

collectionView.performBatchUpdates({ 

      self.collectionView.reloadSections(NSIndexSet(index: index)) 

      }, completion: nil) 
1

Đối với người dùng Swift, nếu collectionview 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

Các vấn đề liên quan