Fri*_*Guy 6 iphone cocoa-touch objective-c uitableview
我是iPhone开发和编程的新手,最近完成了Stephen Kochan的Objective-C 2.0编程,以及Erica Sadun的iPhone Cookbook的部分内容.只是阅读本网站上已回答的问题对我有很大帮助,所以我非常感谢所有用户.现在我正在开发我的第一个iPhone应用程序,并且取得了很好的进展,除了一件令我难过的事情.
我在使用UITableView时遇到了一些麻烦.基本上,我有一个表,每个部分最多需要6行,没有最小值(除非删除1行部分的行,在这种情况下该部分与它一起).该表也可以由用户重新排序.当用户将一行拖动到已经具有最多6个分配行的部分时,我希望该部分的底部行向下排序,以便成为下一部分的顶行.
至于实现这个,我的第一个想法是调用一个方法tableView:moveRowAtIndexPath:toIndexPath:,它将遍历循环中的各个部分,确保它们都没有7行以上,根据需要调整数组,然后使用[myTable beginUpdates]块删除和插入所需的行.这就是所有看起来的样子(注意:我的数组结构是:Array(Table)> Arrays(Sections)> Dictionaries(Items)):
-(void) tableView: (UITableView *) tableView moveRowAtIndexPath: (NSIndexPath *) from toIndexPath: (NSIndexPath *) to
{
// Get the dictionary object for the icon.
NSMutableDictionary *theIcon = [[[TABLE_ARRAY_MACRO objectAtIndex: from.section] objectAtIndex: from.row] mutableCopy];
// Now remove it from the old position, and insert it in the new one.
[[TABLE_ARRAY_MACRO objectAtIndex: from.section] removeObjectAtIndex: from.row];
[[TABLE_ARRAY_MACRO objectAtIndex: to.section] insertObject: theIcon atIndex: to.row];
if ( [[TABLE_ARRAY_MACRO objectAtIndex: to.section] count] > 6 )
[self budgeRowsAtSection: to.section];
// Now we're done with the dictionary.
[theIcon release];
if ( PM_DEBUG_MODE )
NSLog(@"Pet moved!");
}
-(void) budgeRowsAtSection: (NSUInteger) section
{
if ( PM_DEBUG_MODE )
NSLog(@"Budging rows...");
// Set up an array to hold the index paths of the cells to move.
NSMutableArray *budgeFrom = [[NSMutableArray alloc] init];
NSMutableArray *budgeTo = [[NSMutableArray alloc] init];
// Start at the current section, and enumerate down to the nearest page with < 6 items.
int i = section;
while ( i < [TABLE_ARRAY_MACRO count] ) {
if ( PM_DEBUG_MODE )
NSLog(@"Attempting to budge rows in section %i!", i);
if ( [[TABLE_ARRAY_MACRO objectAtIndex: i] count] > 6 ) {
// Grab the last object, and move it to the beginning of the next array.
NSMutableDictionary *lastIcon = [[[PET_ICON_DATA objectAtIndex: i] lastObject] mutableCopy];
[[TABLE_ARRAY_MACRO objectAtIndex: i] removeLastObject];
[[TABLE_ARRAY_MACRO objectAtIndex: (i + 1)] insertObject: lastIcon atIndex: 0];
// Create an index path, and reflect the changes in the table.
[budgeFrom addObject: [NSIndexPath indexPathForRow: 6 inSection: i]];
[budgeTo addObject: [NSIndexPath indexPathForRow: 0 inSection: (i + 1)]];
// Now we're done with the icon.
[lastIcon release];
}
if ( PM_DEBUG_MODE )
NSLog(@"Rows budged for section %i!", i);
++i;
}
if ( PM_DEBUG_MODE )
NSLog(@"From cells: %@\nTo cells: %@", budgeFrom, budgeTo);
if ( PM_DEBUG_MODE )
NSLog(@"Data budged! Updating table...");
[editTable beginUpdates];
[editTable deleteRowsAtIndexPaths: budgeFrom withRowAnimation: UITableViewRowAnimationBottom];
[editTable insertRowsAtIndexPaths: budgeTo withRowAnimation: UITableViewRowAnimationTop];
[editTable endUpdates];
[budgeFrom release];
[budgeTo release];
if ( PM_DEBUG_MODE )
NSLog(@"Row budge done!");
}
Run Code Online (Sandbox Code Playgroud)
问题是,当我运行它时,它总是抛出一个异常; 它给了我Invalid update: number of rows in section after update must be equal to number of rows before update, + or - the number inserted or deleted (etc.),或者Attempted to create two animations for cell,取决于我正在尝试的调整.至于那些调整是什么,我也试过使用reloadSections:withRowAnimation:,当然还有一个简单的[editTable reloadData].我已经尝试在相关的TableView委托/数据源方法中调用此方法,包括在TableViews上的Apple指南中提到targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath:的有些神秘的willMoveToRowAtIndexPath:fromIndexPath:方法,但在其他地方不存在.
我搜遍了谷歌,这个网站以及Apple的文档以寻找任何解决方案,但无济于事.
所以,简单地说一下,最好的方法是什么?我有什么明显的东西可以忽略吗?或者我的实施概念从一开始就存在根本性的缺陷?
在此先感谢您的帮助!任何见解都会非常感激.
- Drew R. Hood
更新:根据Jordan对其答案的评论提出建议,我已经验证了对数据源的实际编辑正确进行.我现在Attempt to create two animations for cell在表编辑块执行时始终得到错误(通过常识和断点验证的时间).所以我在编辑块中做错了.目前的代码完全如上所示.想法?
所以,我终于解决了这个问题,并认为为了后代,我应该将我所做的事情发布在这里。实际上,这非常简单:我只是将表中行的实际插入和删除移至一个单独的方法,然后在延迟后调用该方法。从一开始就很清楚,乔丹帮助我确认,问题是在对表本身执行更新时发生的,而不是在实际更改数据的过程中发生的。所以这是实现这一目的的代码:
-(void) performBudges
{
if ( PM_DEBUG_MODE )
NSLog(@"Performing budge animations...");
[editTable beginUpdates];
[editTable deleteRowsAtIndexPaths: budgeFrom withRowAnimation: UITableViewRowAnimationRight];
[editTable insertRowsAtIndexPaths: budgeTo withRowAnimation: UITableViewRowAnimationRight];
[editTable endUpdates];
[editTable performSelector: @selector(reloadData) withObject: nil afterDelay: 0.5];
[reloadedSections release];
[budgeFrom release];
[budgeTo release];
if ( PM_DEBUG_MODE )
NSLog(@"Budges completed!");
}
Run Code Online (Sandbox Code Playgroud)
要执行此操作,我所要做的就是将此代码片段添加到我的moveRowAtIndexPath:方法中:
if ( [[PET_ICON_DATA objectAtIndex: to.section] count] > 6 ) {
[self budgeRowsAtSection: to.section];
[self performSelector: @selector(performBudges) withObject: nil afterDelay: 1.0];
}
Run Code Online (Sandbox Code Playgroud)
因此,我希望这对将来可能遇到此问题的任何人有所帮助。感谢乔丹和所有看到这个问题的人。:)
| 归档时间: |
|
| 查看次数: |
1234 次 |
| 最近记录: |