iOS 7 UITableView 默认分隔符在重新排序后变得奇怪

标签 ios iphone objective-c uitableview

我在 iOS 7 中 UITableView 的默认分隔符有问题。

默认情况下,第一个和最后一个分隔符没有内嵌,其他分隔符有一点内嵌。原情况见下图:

Everything is OK

一切正常。第一个和最后一个分隔符遍布表格的整个宽度,而其他分隔符则稍小一些。现在我将表格 View 设置为 editing 并且我允许用户重新排序单元格。当用户这样做时,分隔符会弄乱并且无法正确显示。可以在下面的图片中看到这种情况:

enter image description here enter image description here

我真的需要重新加载数据才能解决此问题吗?还是 iOS 7 错误或我做错了什么?

如何解决这个问题?

编辑
添加了一些关于我的实现的信息。我在 - (BOOL)tableView:(UITableView *)tableView shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPathUITableViewCellEditingStyleNone 上返回 - (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/

相关文章:

ios - iBeacon 箭头旋转

ios - Apple Push Notification Service 发送重复通知

iphone - SectionHeader 打开/关闭动画

objective-c - 如何用 arg 写 block 。 Swift 闭包中的 "UnsafeMutablePointer<UnsafeMutablePointer<Float>>"

ios - 当我尝试从 Storyboard 中继续时,为什么我在这行代码中遇到段错误?

objective-c - 在 View 的不同位置随机生成动画

iphone - 简单 iPhone 应用程序启动时的 EXC_BAD_ACCESS

ios - 在导航 Controller 中嵌入 subview

objective-c - 如何创建 "Add to reading list"动画效果

ios - 防止 Xcode 从静态库中删除未使用的符号