2009-09-26 20 views
19

Tôi đang cố gắng làm cho chế độ xem bảng của mình nhớ vị trí cuối cùng của nó, để sau khi ứng dụng được chạy lại, nó sẽ cuộn đến vị trí đó. để làm điều này, theo phương pháp viewWillDisappear: của tôi, tôi nhận được số hàng có thể nhìn thấy đầu tiên và lưu nó vào NSUserDefaults. sau đó trong viewDidAppear của tôi, tôi cố gắng cuộn đến hàng đó bằng cách gửi scrollToRowAtIndexPath đến chế độ xem bảng. Tuy nhiên tôi nhận được một NSRangeException:UITableView scrollToRowAtIndexPath

*** Terminating app due to uncaught exception 'NSRangeException', reason: '-[UITableView scrollToRowAtIndexPath:atScrollPosition:animated:]: section (0) beyond bounds (0).

bất kỳ sự giúp đỡ đánh giá cao. Đây là mã:

- (void)viewDidAppear:(BOOL)animated 
{ 
    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; 

    if ([userDefaults valueForKey:@"content_row"] != nil) 
    { 
     int rowToHighlight = [[userDefaults valueForKey:@"content_row"] intValue]; 
     NSIndexPath * ndxPath= [NSIndexPath indexPathForRow:rowToHighlight inSection:0]; 
     [contentTableView scrollToRowAtIndexPath:ndxPath atScrollPosition:UITableViewScrollPositionTop animated:YES]; 
    } 
} 

-(void) viewWillDisappear:(BOOL)animated 
{ 
    NSIndexPath *selectedRowPath = [[contentTableView indexPathsForVisibleRows] objectAtIndex:0]; 
    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; 
    [userDefaults setInteger:selectedRowPath.row forKey:@"content_row"]; 
} 
+0

Bạn có thể đăng bit mã để tạo scrollToRowAtIndexPath và NSIndexPath không? – probablyCorey

Trả lời

52

Tải lại bảngXem dữ liệu trước khi gọi scrollToRowAtIndexPath.

[contentTableView reloadData]; 
+4

Điều này không hiệu quả đối với tôi khi dữ liệu chưa được tải (sử dụng bộ điều khiển kết quả tìm nạp). Giải pháp của tôi là kiểm tra 'tableView.numberOfRowsInSection (0)> 0' trước. – SimplGy

+0

hoặc nếu trên một chủ đề khác, hãy thử điều này. '[tblView performSelectorOnMainThread: @selector (reloadData) withObject: nil waitUntilDone: YES]' – matrixugly

8

Có thể nội dungTableTable chưa tải xong dữ liệu.

+1

Làm cách nào để nhận thông báo khi hoàn tất? –

+2

Xin lỗi, tôi nghĩ scrollToRowAtIndexPath đã được gọi trong viewDidLoad. Tôi có các cuộc gọi tương tự trong viewDidAppear nhưng thay vì quay trở lại một số hàng đã lưu, tôi trở về một giá trị khóa đã lưu được lưu trong didSelectRowAtIndexPath. Trước khi gọi scrollToRowAtIndexPath, tôi tìm thấy hàng của giá trị khóa đó trong nguồn dữ liệu hiện đang được nạp. – DyingCactus

+0

Ngọt ngào! Điều này thực sự đã giúp các bánh răng của tôi quay đúng hướng. Tôi xây dựng trong một câu trả lời riêng biệt. – matrixugly

0

Tôi muốn xây dựng câu trả lời của DyingCactus. Tôi là một nhà phát triển iOS khá mới và tình hình của tôi là một chút khác nhau, nhưng như ông nói

"Có thể là các contentTableView vẫn chưa hoàn tất tải dữ liệu"

Trong khi câu trả lời đã được ngắn gọn, nó đã biến bánh xe của tôi và nó đã được chính xác những gì đã xảy ra cho tôi.

Cài đặt của tôi

  • UITableView là trên ViewController "A"
  • Ứng dụng của tôi trình bày một ViewController mới "B"
  • On ViewController "B", một nút được nhấn vào, sau đó dữ liệu được thêm vào nguồn dữ liệu cho UITableView.
  • Từ handler bấm vào nút B, [tableView reloadData] được gọi
  • Từ handler bấm vào nút B, [tableView selectRowAtIndexPath:idxPath animated:false scrollPosition:UITableViewScrollPositionTop]; được gọi
  • ViewController "B" là bị sa thải và "A" được trình bày lại (hiển thị các UITableView cập nhật)

giải pháp

  • vấn đề đầu tiên mà tôi đã phải sửa chữa là để gọi reloadData trên luồng chính như vậy

    [tblView performSelectorOnMainThread: @selector (reloadData) withObject: nil waitUntilDone: false];

  • Vấn đề cuối cùng là thay đổi waitUntilDone thành đúng (DUH!)

Yeah, vì vậy rõ ràng đối với tôi, những contentTableView đã không thực hiện tải dữ liệu vì gọi reloadData của tôi đang được chạy trên các chủ đề chính không rõ ràng thiết lập để chặn cho đến khi chọn được thực hiện.

Hy vọng điều này sẽ giúp ai đó.

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