6

Tôi đang cố gắng tìm cách tốt nhất để xử lý khôi phục trạng thái cho UICollectionView có các yếu tố có thể di chuyển xung quanh. Mục tiêu của tôi là đảm bảo rằng mục được xem lần cuối trong chế độ xem bộ sưu tập vẫn hiển thị khi khởi động lại ứng dụng, ngay cả khi các mục đã di chuyển xung quanh. Ví dụ: mục A nằm trong ô tại chỉ mục 3 khi ứng dụng bị giết và khi ứng dụng khởi động lại nếu mô hình cho biết mục A sẽ được hiển thị ở chỉ mục 4, tôi muốn chế độ xem bộ sưu tập khởi tạo bù đắp cho ô tại chỉ mục 4.Khôi phục trạng thái UICollectionView: tùy chỉnh vị trí cuộn

tôi nghĩ rằng việc thực hiện các giao thức UIDataSourceModelAssociation trong lớp UICollectionViewDataSource tôi sẽ chăm sóc này cho tôi, như documentation trạng thái:

[UITableView và UICollectionView] lớp học sử dụng các phương pháp của giao thức này để đảm bảo rằng các đối tượng dữ liệu giống nhau (và không chỉ các chỉ mục hàng tương tự) được cuộn vào chế độ xem và được chọn.

Tuy nhiên, những gì tôi đã quan sát thấy là thực hiện giao thức này không ảnh hưởng đến đúng indexPath của chọn tế bào trong phục hồi (mà không phải là quan trọng đối với ứng dụng của tôi), nhưng nó không ảnh hưởng đến vị trí cuộn. Vị trí cuộn (contentOffset của chế độ xem bộ sưu tập) luôn được khôi phục chính xác nơi ứng dụng bị giết và không bị ảnh hưởng bởi UICollectionViewDataSource.

Tôi có giải pháp thay thế giống như thế này. Về cơ bản nó giống như mô hình giao thức xác nhận mô hình, nhưng tôi phải làm theo cách thủ công:

override func encodeRestorableStateWithCoder(coder: NSCoder) { 
    let identifier = determineIdOfCurrentlyVisibleCell() 
    coder.encodeObject(identifier, forKey: "visibleCellIdentifier") 
} 

override func decodeRestorableStateWithCoder(coder: NSCoder) { 
    if let identifier = coder.decodeObjectForKey("visibleCellIdentifier") as? String { 
     if let indexPath = model.indexPathForIdentifier(identifier) { 
      collectionView.scrollToItemAtIndexPath(indexPath, atScrollPosition: .CenteredVertically, animated: false) 
     } 
    } 
} 

Tôi hiểu nhầm cách sử dụng UIDataSourceModelAssociation? Có lỗi không? Có cách nào thanh lịch hoặc chính xác hơn để làm việc này không?

+0

Như tôi đã có thể nhìn thấy 'indexPathForElementWithModelIdentifier: inView: 'thiết kế để làm điều tương tự. Nó hoạt động? – orkenstein

+0

@orkenstein Tôi đã thử sử dụng nó, nhưng nó không hoạt động. Xem OP của tôi: "triển khai thực hiện giao thức này không ảnh hưởng đúng đến indexPath của các ô đã chọn trong quá trình khôi phục (điều này không quan trọng đối với ứng dụng của tôi), nhưng nó không ảnh hưởng đến vị trí cuộn." –

Trả lời

5

Như bạn đã chỉ ra, UIDataSourceModelAssociation dường như không hoạt động với khôi phục bù đắp hiển thị của UICollectionView, nhưng chỉ cho các mục đã chọn. Tôi đã thử đặt các điểm ngắt trên cả hai số modelIdentifierForElementAtIndexPathindexPathForElementWithModelIdentifier và nhận thấy chúng chỉ được gọi sau khi tôi chọn một ô. Nếu tôi xóa các ô đã chọn trong bộ sưu tập của mình trước khi tạo nền ứng dụng thì modelIdentifierForElementAtIndexPath sẽ không được gọi, nhưng khi tôi đã đặt ít nhất một ô như đã chọn. Ít nhất tôi có thể xác minh rằng bạn không phải là người duy nhất nhìn thấy hành vi này.

Tôi nghĩ vì tính chất khác nhau của UICollectionView, có thể không đơn giản để tạo hành vi cuộn các ô hiển thị đến đúng điểm, nhưng điều này rõ ràng không được phản ánh trong tài liệu của Apple. Mã hóa định danh theo cách thủ công cho ô hiển thị đầu tiên cho bố cục của bạn phải là một lựa chọn tốt. Những gì tôi đang làm là gói cuộn nhìn bộ sưu tập của bù đắp trong một NSValue và khôi phục lại rằng:

var collectionView: UICollectionView? 

// ... 

override func encodeRestorableStateWithCoder(coder: NSCoder) { 
    if let view = collectionView, offsetValue = NSValue(CGPoint: view.contentOffset) { 
     coder.encodeObject(offsetValue, forKey: CollectionViewContentOffsetKey) 
    } 

    super.encodeRestorableStateWithCoder(coder) 
} 

override func decodeRestorableStateWithCoder(coder: NSCoder) { 
    if let offsetValue = coder.decodeObjectForKey(CollectionViewContentOffsetKey) as? NSValue { 
     collectionView?.setContentOffset(offsetValue.CGPointValue(), animated: false) 
    } 

    super.decodeRestorableStateWithCoder(coder) 
} 
+1

Phân tích tốt. Có nghĩa với tôi. –

+0

Điều này làm việc, nhưng đã được khôi phục lại bù đắp hơi ở một nơi sai - probs một cái gì đó sai với các tính toán navigationBar. – soprof

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