我在 iOS 7 中 UITableView
的默认分隔符有问题。
默认情况下,第一个和最后一个分隔符没有内嵌,其他分隔符有一点内嵌。原情况见下图:
一切正常。第一个和最后一个分隔符遍布表格的整个宽度,而其他分隔符则稍小一些。现在我将表格 View 设置为 editing
并且我允许用户重新排序单元格。当用户这样做时,分隔符会弄乱并且无法正确显示。可以在下面的图片中看到这种情况:
我真的需要重新加载数据才能解决此问题吗?还是 iOS 7 错误或我做错了什么?
如何解决这个问题?
编辑
添加了一些关于我的实现的信息。我在 - (BOOL)tableView:(UITableView *)tableView shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath
和 UITableViewCellEditingStyleNone
上返回 - (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
。我的 - (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
是:
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = @"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell)
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
cell.shouldIndentWhileEditing = NO;
cell.textLabel.font = [UIFont someFont];
UIColor *color = [UIColor randomColor];
cell.textLabel.text = @"Some text";
CGRect rect = CGRectMake(0, 0, 15, 15);
UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0);
CGContextRef ctx = UIGraphicsGetCurrentContext();
[color set];
CGContextFillEllipseInRect(ctx, rect);
cell.imageView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return cell;
}
和
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath
{
if (sourceIndexPath.row == destinationIndexPath.row) return;
NSString *tmp = [itemOrder objectAtIndex:sourceIndexPath.row];
[itemOrder removeObjectAtIndex:sourceIndexPath.row];
[itemOrder insertObject:tmp atIndex:destinationIndexPath.row];
didReorder = YES;
}
最佳答案
这似乎是 iOS SDK 中的问题。解决它的一种方法是手动将正确的分隔符应用于所有单元格。不过,我个人更喜欢让系统来做。
如果您在重新排序后重新加载单元格,系统将应用正确的分隔符插入。因此,您只需确保在重新排序后重新加载相关单元格即可。
修复用户重新排序
有一个私有(private)方法tableView:didEndReorderingRowAtIndexPath:
在重新排序(动画)结束后调用 TableView 的委托(delegate)。在这种方法中,您应该重新加载单元格:
- (void)tableView:(UITableView *)tableView didEndReorderingRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:indexPath.section]
withRowAnimation:UITableViewRowAnimationNone];
}
此修复仅在行仅在一个部分内(而不是部分之间)移动时才有效。
(使用 reloadRowsAtIndexPaths:withRowAnimation:
方法只重新加载移动的单元格和旧位置的单元格会更有效。但是,您必须在移动单元格。这将更复杂地实现。对于小部分/简单单元格,重新加载整个部分可能会更容易一些。)
修复程序化移动
不幸的是,先前修复中使用的私有(private)委托(delegate)方法仅在用户重新排序后调用,而不是在以编程方式移动行(使用 moveRowAtIndexPath:toIndexPath:
)之后调用。因此,我们必须为此使用另一个修复程序。
自 TableView internally use CALayer
animations ,我们可以使用 CATransaction
来了解动画何时结束。 (为此,您确实需要将 QuartzCore.framework
添加到您的项目中。)我的修复如下所示:
UITableView+NicelyMoves.h
#import <UIKit/UIKit.h>
@interface UITableView (NicelyMoves)
- (void)nicelyMoveRowAtIndexPath:(NSIndexPath *)indexPath
toIndexPath:(NSIndexPath *)newIndexPath;
@end
UITableView+NicelyMoves.m
#import <QuartzCore/QuartzCore.h>
#import "UITableView+NicelyMoves.h"
@implementation UITableView (NicelyMoves)
- (void)nicelyMoveRowAtIndexPath:(NSIndexPath *)indexPath
toIndexPath:(NSIndexPath *)newIndexPath
{
[CATransaction begin];
[CATransaction setCompletionBlock:^{
// This is executed after the animations have finished
[self reloadRowsAtIndexPaths:@[indexPath, newIndexPath]
withRowAnimation:UITableViewRowAnimationNone];
}];
[self moveRowAtIndexPath:indexPath toIndexPath:newIndexPath];
[CATransaction commit];
}
@end
用法
现在,您应该使用自定义方法 nicelyMoveRowAtIndexPath:toIndexPath:
,而不是使用 moveRowAtIndexPath:toIndexPath:
。例如,您可以这样做:
#import "UITableView+NicelyMoves.h"
@implementation YourTableViewController
- (void)moveTheRow
{
// Move row 0 to 2 in section 0
NSIndexPath *from = [NSIndexPath indexPathForRow:0 inSection:0];
NSIndexPath *to = [NSIndexPath indexPathForRow:2 inSection:0];
[self.tableView nicelyMoveRowAtIndexPath:from toIndexPath:to];
}
@end
关于iOS 7 UITableView 默认分隔符在重新排序后变得奇怪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21764857/