如何在左侧对UITableViewCell进行重新排序控制?

Hoa*_* Ha 19 custom-controls uitableview ios

我正在做一个新闻阅读器应用程序,我希望用户可以选择显示/隐藏新闻类别(如热门新闻,商业,技术,体育等),并重新排序他们像Android中的BBC新闻应用程序.

见下图: 在此输入图像描述

我的问题是:

  • 如何在单元格的左侧进行重新排序控制?(其默认位置在编辑模式下位于单元格的右侧)
  • 我有复选框自定义控件,如何把它放在单元格的右侧?

预先感谢!!!

Luk*_*ert 38

回答[如果您没有使用任何配件(详细信息披露,&c)]

(0)我假设您已设置好表格,&c.

(1)此解决方案仅在表格单元格始终可拖动时才有效.将viewDidLoad中的这个添加到Table View Controller .m文件中.

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self setEditing:YES];
}
Run Code Online (Sandbox Code Playgroud)

(2)为了使你可以重新排序你的单元格,添加cell.showsReorderControl = YES;到你的tableView:cellForRowAtIndexPath:.

(3)确保你有tableView:canMoveRowAtIndexPath:和tableView:moveRowAtIndexPath:toIndexPath:方法.

- (BOOL)tableView:(UITableView *)tableview canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
    return YES; 
}

- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
}
Run Code Online (Sandbox Code Playgroud)

(4)因为你想要左边的重新排序控件,我们必须通常删除那里的删除圈,tableView:editingStyleForRowAtIndexPath:方法就是这样做的.

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return UITableViewCellEditingStyleNone;
}
Run Code Online (Sandbox Code Playgroud)

(5)最后一步,魔术发生的地方 - 添加tableView:willDisplayCell:forRowAtIndexPath:方法,搜索单元格的子视图,将其缩小到私有UITableViewCellReorderControl,最后覆盖它.

- (void) tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    for(UIView* view in cell.subviews)
    {
        if([[[view class] description] isEqualToString:@"UITableViewCellReorderControl"])
        {
            // Creates a new subview the size of the entire cell
            UIView *movedReorderControl = [[UIView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetMaxX(view.frame), CGRectGetMaxY(view.frame))];
            // Adds the reorder control view to our new subview
            [movedReorderControl addSubview:view];
            // Adds our new subview to the cell
            [cell addSubview:movedReorderControl];
            // CGStuff to move it to the left
            CGSize moveLeft = CGSizeMake(movedReorderControl.frame.size.width - view.frame.size.width, movedReorderControl.frame.size.height - view.frame.size.height);
            CGAffineTransform transform = CGAffineTransformIdentity;
            transform = CGAffineTransformTranslate(transform, -moveLeft.width, -moveLeft.height);
            // Performs the transform
            [movedReorderControl setTransform:transform];
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我花了将近十个小时的时间试图找出配件的解决方案,而我无法做到.我需要更多的经验和知识.简单地对披露按钮上的重新排序控件做同样的事情是行不通的.所以我希望现在能有效; 如果我将来弄清楚,我一定会更新这个.

嗨Hoang Van Ha,这是我的第一个答案,我一个月前才开始学习Objective-C,所以我还是一个菜鸟.

我一直试图用我的应用程序做同样的事情,并一直在寻找数小时如何做到这一点.就此而言,Apple的文档并没有太大帮助.当人们简单地链接到文档时,我发现它非常令人沮丧.我想对他们大喊大叫.我希望我的回答对你有帮助.

b2Cloud有很多赞誉,因为我使用了本文中的一些代码并根据我的答案进行了调整.

  • 你知道如何让整个单元格成为重新排序控件,这样你就不必抓住小图标吗? (3认同)
  • 我将指出@David引发的问题也会导致多个UIView被添加到单元格中.每次滚动TableView时都会发生这种情况.这是由于创建了不再使用但仍然无处不在的视图而导致的内存泄漏.我已经将子单元子类化了,所以我添加了一个属性来跟踪创建的视图并在willDisplayCell中重用它. (2认同)

hpi*_*que 24

我建议使用over 并实现自己的重新排序逻辑UITableViewCellReorderControl,不是寻找非公共API并且可能在将来发生变化.UILongPressGestureRecognizerUITableView

我解决了一般情况(响应对单元的任何部分的长按)HPReorderTableView,直接替换UITableView.它可以很容易地修改,以通过实现以触摸响应于细胞的特定部分,例如gestureRecognizer:shouldReceiveTouch:所述的reorderGestureRecognizer委托.

  • 请注意,这个家伙有23.7k的声誉.其他答案是拙劣的,将来会再次咬你.另外请记住,Apple有一个很好的理由发布UI指南并尝试坚持使用它们 - 用户期望在右侧实现此控制. (5认同)

Moh*_*deh 13

现在,iOS 9及更高版本的解决方案更加简单

tableView.semanticContentAttribute = .forceRightToLeft
Run Code Online (Sandbox Code Playgroud)

编辑:

正如罗兰所提到的,你应该注意到"如果你通过leadingtrailing锚定对齐你的细胞的子视图而不是leftright,这个设置将翻转一切."