2012-11-06 28 views
7

Tôi hiện đang triển khai khôi phục/khôi phục trạng thái tự động trong ứng dụng chỉ dành cho iOS6.Cuộc gọi lạ đến modelIdentifierForElementAtIndexPath: inView: (UIDataSourceModelAssociation)

Đối với một sự phục hồi của một cái nhìn bảng, tôi đã thêm giao thức UIDataSourceModelAssociation để điều khiển xem bảng của tôi và thực hiện

- (NSString *)modelIdentifierForElementAtIndexPath:(NSIndexPath *)idx inView:(UIView *)view

- (NSIndexPath *)indexPathForElementWithModelIdentifier:(NSString *)identifier inView:(UIView *)view

Khi nhấn nút home, các phương pháp bảo quản nhà nước, bao gồm modelIdentifierForElementAtIndexPath:iView:, được gọi là dự kiến ​​và trả lại chuỗi định danh hợp lệ cho các đường dẫn chỉ mục đã cho.

Khi giết ứng dụng và khởi chạy lại, khôi phục trạng thái hoạt động nhiều hơn hoặc ít hơn. I E. ứng dụng sẽ mở lại chế độ xem bảng chính xác. Tuy nhiên, chế độ xem bảng luôn được cuộn lên trên cùng, ngay cả khi nó được cuộn đến vị trí khác trước đó.

Dưới đây là việc triển khai các phương pháp UIDataSourceModelAssociation trong bộ điều khiển chế độ xem bảng của tôi. Không có gì lạ mắt xảy ra ở đó (các NdlFriend::accountUid tài sản trả về một chuỗi định danh duy nhất cho một kỷ lục NdlFriend nhất định):

#pragma mark - UIDataSourceModelAssociation 
- (NSString *)modelIdentifierForElementAtIndexPath:(NSIndexPath *)idx inView:(UIView *)view 
{ 
    NSString* identifier = nil; 
    NSArray* content = self.contentArray; 

    // Sometimes idx might be nil... 
    if(idx && idx.row<content.count) 
    { 
     NdlFriend* friend = content[idx.row]; 
     identifier=friend.accountUid; 
    } 
    return identifier; 
} 

- (NSIndexPath *)indexPathForElementWithModelIdentifier:(NSString *)identifier inView:(UIView *)view 
{ 
    NSIndexPath * indexPath=nil; 
    NSArray* content = self.contentArray; 
    NSInteger count = content.count; 
    for(NSInteger i=0;i<count;i++) 
    { 
     NdlFriend* friend = content[i]; 
     if([identifier isEqualToString:friend.accountUid]) 
     { 
      indexPath = [NSIndexPath indexPathForRow:i inSection:0]; 
      break; 
     } 
    } 
    return indexPath; 
} 

tôi đặt chia điểm trong cả hai phương pháp.

Để kiểm tra các phương pháp, tôi đã mở chế độ xem bảng và cuộn xuống một chút. Sau đó, khi nhấn nút trang chủ:

  • modelIdentifierForElementAtIndexPath:inView: được gọi một lần, với đường dẫn chỉ mục của hàng hiển thị hàng đầu. Phương thức trả về giá trị đúng cho hàng này.

Cho đến nay rất tốt.

Sau đó, tôi dừng và khởi chạy lại ứng dụng. Dưới đây là những gì xảy ra (tôi đặc biệt là bối rối bởi các điểm break hit đầu tiên):

  • modelIdentifierForElementAtIndexPath:inView: được gọi là, với nil như con đường index (lập luận xem có chứa con trỏ đúng đắn về xem bảng).
  • indexPathForElementWithModelIdentifier:inView: được gọi bằng chuỗi số nhận dạng hợp lệ (và đường dẫn chỉ mục hợp lệ được phương thức trả về).
  • indexPathForElementWithModelIdentifier:inView: được gọi lại (với cùng chuỗi nhận dạng).
  • Chế độ xem bảng được làm mới, nhưng được cuộn lên trên cùng.

Có ai biết, tại sao việc khôi phục vị trí cuộn không thành công? Có thể cuộc gọi của modelIdentifierForElementAtIndexPath:inView: với nil vì indexPath có liên quan đến nó (hoặc là hành vi bình thường này).

+1

Trong khi khôi phục vị trí cuộn xem bảng (chủ yếu) hoạt động ngay trong iOS 9, hành vi bị hỏng được mô tả trong câu hỏi có 'modelIdentifierForElementAtIndexPath: inView:' _gets được gọi, với nil dưới dạng chỉ mục path_ đôi khi xảy ra khi chế độ xem bảng trống khôi phục, dẫn đến một ngoại lệ _bad access_. Một cách giải quyết khác là thay đổi chữ ký phương thức để chấp nhận một nillable 'NSIndexPath!' Và bảo vệ chống lại 'nil' (bằng cách trả về' nil'), mặc dù nó ** sẽ không bao giờ xảy ra **! (Ngoài ra, để tránh cảnh báo, trả về 'nil' nếu' numberOfRowsInSection (0) 'là số không cũng hoạt động.) – penfold

Trả lời

0

Tôi không nghĩ rằng sự cố bạn đang gặp phải khi đặt lại vị trí cuộn của chế độ xem bảng phải làm với các phương thức UIDataSourceModelAssociation.

Tôi tin rằng có lỗi với bộ điều khiển chế độ xem bảng được nhúng trong bộ điều khiển điều hướng khiến cho nó đặt lại vị trí cuộn sau khi khôi phục. Theo tôi hiểu, nếu các ô trong chế độ xem bảng của bạn không sắp xếp lại, bạn không cần phải triển khai các phương thức UIDataSourceModelAssociation và bạn sẽ nhận được vị trí cuộn "miễn phí" (nghĩa là bạn đã chọn tham gia bảo quản trạng thái và đặt ID khôi phục). Tôi thực sự không thể xác nhận điều này một cách rõ ràng từ tài liệu, ngoại trừ để chỉ ra rằng UITableView xuống từ UIScrollView, lưu vị trí cuộn của nó. Tôi đã thử nghiệm rằng nếu bạn đặt bộ điều khiển xem bảng là bộ điều khiển gốc hoặc nhúng bộ điều khiển chế độ xem bảng trong bộ điều khiển thanh tab, thì vị trí cuộn được khôi phục.

Tôi đã gửi báo cáo lỗi, bạn cũng nên làm vậy, nếu bạn chưa có.

1

Có một lỗi trong iOS 6 về khôi phục trạng thái của Bảng Lần trong điều khiển Navigation.

Bạn có thể xem radar mở ở đây: rdar://13438788

Như bạn có thể thấy, đó là một bản sao, vì vậy Apple là ý thức về điều này.

Ngoài ra, hãy xem liên kết tiếp theo này, người đã đăng radar mở cũng đã đăng blog này, nó có các giải pháp được đề xuất mà các kỹ sư của Apple đã nói với anh ấy.

Nó làm cho việc bảo tồn/phục hồi nhà nước đối với tôi không phải là một tính năng thú vị để thực hiện, mặc dù hãy nhớ, điều này là dành cho người dùng của bạn! Vì vậy, bạn chỉ nên làm việc này.

Lưu ý có 2 cách giải quyết, một cách để xem thông tin chế độ xem của bảng để khôi phục (ví dụ như cuộn cuộn) và một cách giải quyết khác cho việc sử dụng khi triển khai UIDataSourceModelAssociation là trường hợp của bạn.

http://useyourloaf.com/blog/2013/04/07/bug-table-view-state-not-restored-when-embedded-in-navigation-controller.html

0

Hãy chắc chắn rằng bạn không thực hiện một không đồng bộ lấy về dữ liệu của bạn. Nếu bạn đang tìm nạp dữ liệu của mình từ viewDidLoad, hãy đảm bảo rằng bạn sử dụng cuộc gọi [myManagedObjectContext performBlockAndWait:^{}] thay vì một [myManagedObjectContext performBlock:^{}].

Có thể là bạn có điều kiện chủng tộc nơi self.contentArray trống khi indexPathForElementWithModelIdentifier được gọi.

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