2009-12-10 44 views
5

Tôi có một số quy tắc khá phức tạp để di chuyển các hàng xung quanh trong một UITableView. Có một số phần và hàng không xác định trên mỗi phần và dựa trên các quy tắc khác nhau, các hàng có thể được di chuyển trong hoặc giữa các phần của người dùng đến các vị trí cụ thể khác.Đâm trong khi cố di chuyển các hàng của UITableView

Tất cả dữ liệu đang cập nhật và mọi thứ đều hoạt động. Nhưng đôi khi, sau khi di chuyển một hàng, ứng dụng sẽ giả ra và đột nhiên sẽ có một không gian trống, nơi một hàng sẽ được hiển thị.

Tôi đang sử dụng:

   - (NSIndexPath *)tableView:(UITableView *)tableView 
targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath 

để xác định nơi người dùng được phép kéo các hàng dựa trên nơi các tế bào là. 98% thời gian hoạt động. Nhưng trong một số trường hợp, khi người dùng chỉ được phép kéo giữa các phần (không thể sắp xếp lại các hàng trong phần), lỗi này xuất hiện, sau đó ứng dụng gặp sự cố sau khi cuộn qua khu vực không có hàng.

Trường hợp ngoại lệ ném là khá vô dụng:

Chấm dứt ứng dụng do ngoại lệ còn tự do 'NSRangeException', lý do: '*** - [NSCFArray objectAtIndex:]: chỉ mục (6) vượt quá giới hạn (6)

Không có mã nào của tôi ở trên ngăn xếp. Phương pháp UITableView cụ thể cuối cùng là

-[UITableView(UITableViewInternal) _visibleCellForGlobalRow:]

Có ai nhìn thấy vấn đề này xảy ra trước? Ý tưởng nào?

+0

Bạn đã bao giờ giải quyết Ed này? Không có câu trả lời nào được đánh dấu đúng và tôi cũng thấy các vấn đề tương tự. – coneybeare

+0

Không, tôi chưa bao giờ giải quyết vấn đề này. Tôi đã phải nới lỏng các quy tắc quản lý nơi một hàng có thể được kéo đến để nó sẽ không xảy ra –

+0

Bạn đang làm bất kỳ loại hoạt động tải lại (chẳng hạn như reloadData, reloadSections, hoặc reloadRowsAtIndexPath) trong phương thức moveRowAtIndexPath của bạn? Tôi đã có cùng một loại vấn đề, và tôi đã cố gắng để tải lại trong một performSelector chậm như đề xuất của Tom S. dưới đây, và nó dường như làm việc, ngoại trừ tôi đặt sự chậm trễ ở 1 giây để giữ cho iPhone 3.x, 4 .x, và mô phỏng hạnh phúc. Đó là một chút hackish để chắc chắn. –

Trả lời

0

Tôi chưa truy cập vấn đề này trong một thời gian ngắn. Giải pháp mà tôi đưa ra là loại bỏ các quy tắc phức tạp. Bạn không chắc chắn lý do tại sao họ cho phép sử dụng các quy tắc phức tạp nếu nó bị hỏng ứng dụng khi sử dụng chúng. Bạn không chắc chắn nếu điều này là cố định trong phiên bản mới nhất của hệ điều hành hay không.

1

Dường như một cái gì đó ở đâu đó đang yêu cầu phần tử 6 từ mảng chỉ có các phần tử tại chỉ mục 0-5 (nghĩa là 6 phần tử).

này thường xảy ra khi mã cố gắng để làm:

NSUInteger index = [somearray count]; 
id obj = [somearray objectAtIndex:index]; 

count là ranh giới trên và mảng bắt đầu từ 0 yếu tố cuối cùng là tại count - 1.

Điều này có thể không trực tiếp trong mã của bạn nhưng bạn có thể đang hạn chế thứ gì đó đối với một số thành phần và sau đó yêu cầu một yếu tố cuối cùng.

+0

Lưu ý rằng người ta nên sử dụng 'NSUInteger' cho kết quả của' count', vì sợ rằng nó bị cắt bớt (đặc biệt là khi di chuyển mã tới Mac, trong đó 'NSUInteger', ngày càng thường lớn hơn' int'). Nó cũng quan trọng để giữ cho nó unsigned để so sánh với giá trị này không bao giờ tiêu cực luôn luôn có ý nghĩa. –

+0

Đúng, tôi chỉ đang lười biếng ... – stefanB

+0

Tôi biết vấn đề cơ bản, nhưng mã đó đang truy cập vào mảng là sâu bên trong khuôn khổ. Như tôi đã nói, hoàn toàn không có mã của riêng tôi trên ngăn xếp tại thời điểm xảy ra sự cố. Tại cơ sở của nó, nó có vẻ giống như một lỗi trong đối tượng UITableView. –

1

Tôi đã gặp lỗi tương tự với việc xóa mà tôi không thể tìm ra trong một thời gian - nhưng tôi đặt [tableView beginUpdates][tableView endUpdates] xung quanh mã và nó đã sửa mọi thứ. Có thể là nguồn dữ liệu của bạn không cập nhật trước khi nó cố gắng vẽ lại và những phương pháp đó sẽ ngăn chặn điều đó (đáng để bắn, dù sao).

+0

Đã xong, thực sự. –

1

Bạn đang cập nhật mô hình dữ liệu của bạn cho bảng trong targetIndexPathForMoveFromRowAtIndexPath

Hoặc trong phương pháp DataSource đại biểu: tableView:moveRowAtIndexPath:toIndexPath:?

Taken từ bàn xem Hướng dẫn Lập trình cho iPhone OS, dưới ô trong bảng sắp xếp lại:

Quan điểm bảng gửi tableView: moveRowAtIndexPath: toIndexPath: đến nguồn dữ liệu của nó (nếu nó thực hiện sự phương pháp).Trong phương pháp này, nguồn dữ liệu cập nhật mảng mô hình dữ liệu đó là nguồn mục cho chế độ xem bảng , di chuyển mục đến một vị trí khác nhau trong mảng.

Và đối với các phương pháp đại biểu, có chép rằng:

Mỗi lần hàng kéo đã qua một điểm đến , xem bảng gửi tableView: targetIndexPathForMoveFromRowAtIndexPath: toProposedIndexPath: để đại biểu của nó (nếu nó thực hiện phương pháp ). Trong phương thức này, đại biểu có thể từ chối đích hiện tại cho hàng đã kéo và chỉ định một thay thế thay thế.

tableView:targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath: là để xác định liệu một di dời được cho phép, nhưng những thay đổi thực tế để mô hình dữ liệu của bạn nên diễn ra trong tableView:moveRowAtIndexPath:toIndexPath:

Có lẽ đây là những gì bạn đang làm, nhưng tôi không thể nói chỉ từ thông tin bạn đã cung cấp.

+0

Không, tôi đang cập nhật nó theo phương pháp moveRowAtIndexPath –

2

Tôi vừa đạt được những gì tôi tin là cùng một vấn đề trong ứng dụng của mình.

Tình huống là tôi có hai phần bảng. Các mục có thể được kéo vào trong và giữa các phần. Người dùng có thể kéo các ô vào bất kỳ hàng nào trong phần đầu tiên, nhưng trong phần thứ hai các mục được sắp xếp, vì vậy đối với bất kỳ ô nào, chỉ có một hàng hợp lệ.

Nếu tôi cuộn chế độ xem sao cho phần dưới cùng của phần 1 và phần trên cùng của phần 2 hiển thị, hãy lấy một mục trong phần 1 sắp xếp ở cuối phần 2 và kéo nó vào phần đầu của phần 2 , phương thức tableView:targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath: của tôi được gọi và tôi trả về đúng vị trí đích, là một vài hàng bên dưới cuối màn hình. Trong giao diện người dùng, bạn có thể thấy ô trống được tạo ở cuối màn hình, không phải là hàng đích chính xác.

Khi bạn buông bỏ ô, ô không có thật được tạo ở cuối màn hình (ở giữa phần 2) vẫn ở đó! tableView:cellForRowAtIndexPath: thậm chí không bao giờ được gọi cho nó. Ngay sau khi bạn cố gắng làm bất cứ điều gì với tế bào đó, bạn sụp đổ.

Giải pháp đầu tiên của tôi là chỉ cần gọi [tableView reloadData] ở cuối tableView:moveRowAtIndexPath:toIndexPath:. Nhưng điều đó gây ra một vụ tai nạn, vì vậy thay vào đó tôi gọi nó gián tiếp sau một sự chậm trễ. Nhưng sau đó có lỗi khác: sau khi cuộc gọi lại tải lại bị trễ, tableView:moveRowAtIndexPath:toIndexPath: được gọi lại với yêu cầu không có thật để di chuyển một mục qua cuối phần đầu tiên đến cùng vị trí đó. Vì vậy, tôi đã phải thêm mã để bỏ qua các yêu cầu không có yêu cầu.

Vì vậy, đây là các mã:

- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)pathSrc toIndexPath:(NSIndexPath *)pathDst 
{ 
    // APPLE_BUG: after doing the delayed table reload (see below), we get a bogus 
    // request to move a nonexistant cell to its current location 
    if (pathSrc.row == pathDst.row && pathSrc.section == pathDst.section) 
    return; 

    // update your data model to reflect the move... 

    // APPLE_BUG: if you move a cell to a row that's off-screen (because the destination 
    // has been modified), the bogus cell gets created and eventually will cause a crash 
    [self performSelector:@selector(delayedReloadData:) withObject:tableView afterDelay:0]; 
} 

- (void)delayedReloadData:(UITableView *)tableView 
{ 
    Assert(tableView == self.tableView); 
    [tableView reloadData]; 
} 

Lưu ý rằng vẫn có một lỗi UI. Trên màn hình, ô được kéo sẽ được chuyển thành ô trống không có thật. Khi kết thúc hoạt ảnh, ô trống sẽ được vẽ lại với dữ liệu chính xác cho hàng đó, nhưng người dùng quan sát sẽ nhận thấy ô được kéo hoạt ảnh đến vị trí sai rồi ngay lập tức biến thành một ô khác.

Đây chắc chắn là giao diện người dùng ngốc nghếch.Tôi đã xem xét việc cuộn hàng đích thích hợp lên màn hình, nhưng nếu tôi làm điều đó, nó sẽ lấp đầy màn hình bằng phần hai và sau đó bất kỳ nỗ lực nào để kéo trở lại phần một sẽ liên tục bị ngăn cản bởi tính năng tự động kiểm tra (hiện đang gây phiền nhiễu) của tôi. Tôi có thể phải thay đổi giao diện người dùng, nhưng điều đó sẽ yêu cầu một số thay đổi phức tạp và khó chịu đối với mô hình dữ liệu của tôi.

+0

Tôi vui vì ít nhất một người khác đã có cùng trải nghiệm với tôi! –

0

Tôi chỉ tình cờ chứng kiến ​​vấn đề này. Tuy nhiên, phiên bản tai nạn của tôi dường như xảy ra trên thiết bị iOS 3.0 mà tôi đang cố gắng hỗ trợ và tôi chỉ có hai hàng trong bảng mà tôi đang cố gắng sắp xếp lại. Tôi chạy lại ứng dụng với cùng mã trên một thiết bị khác có iOS 4.0 và lỗi đó dường như đã được sửa.

Tôi vẫn đang nghiên cứu điều này, nhưng hiện tại, tôi đang vô hiệu hóa việc di chuyển các hàng trên thiết bị có iOS 3.0 cho đến khi tìm thấy sửa chữa.

1

Đây Cityarray là một mảng ...

id obj =[Cityarray objectatindex:sourceindexpath.row]; 
     [Cityarray removeObjectatindex:(sourceindexpath.row)]; 
     [Cityarray insertObject:obj atindex:destinationindexpath.row]; 
Các vấn đề liên quan