进入编辑模式时动画自定义绘制的UITableViewCell

Ada*_*der 49 iphone cocoa-touch objective-c ios

背景

首先,非常感谢atebits为他们提供的信息丰富的博客文章使用UITableView快速滚动Tweetie.这篇文章详细解释了开发人员如何从Tweetie中的UITableViews中尽可能多地挤出滚动性能.

目标

从博客文章(原创)(我的github repo)链接的源代码开始:

  1. 允许使用这些自定义单元格的UITableView切换到编辑模式,从而公开用于从表格中删除项目的UI.(github提交)

  2. 当删除控件从左侧滑入时,将单元格的文本移到一边.这是完整的,尽管文本在没有动画的情况下来回跳跃.(github提交)

  3. 将动画应用于上面目标2中的文本移动,以获得流畅的用户体验.这是我陷入困境的一步.

问题

引入此动画以完成目标3的最佳方法是什么?如果可以通过保持逻辑不受上次提交的方式完成,那将是很好的,因为我希望只选择移动视图的冲突部分,而任何非冲突部分(例如右对齐文本)留在同一个地方或移动不同数量的像素.如果无法实现上述目的,则撤消上次提交并将其替换为将整个视图向右滑动的选项也是一种可行的解决方案.

我感谢任何人都可以提供的任何帮助,从快速指针和想法一直到代码片段或github提交.当然,如果您愿意,欢迎您来我的回购.我将继续参与这个问题,以确保任何成功的解决方案都致力于github,并在此完整记录.非常感谢你花时间陪伴!

更新了想法

自从我的第一篇文章以来,我一直在考虑这个问题,并意识到在视图中相对于其他文本项移动一些文本项可以撤消原始博客文章中解决的一些原始性能目标.所以在这一点上,我正在考虑一个解决方案,其中整个单个子视图动画到其新位置可能是最好的.

其次,如果以这种方式完成,则可能存在子视图具有自定义颜色或渐变背景的实例.希望这可以通过以下方式完成:在正常位置,背景向左侧看不见,以便当视图向右滑动时,自定义背景在整个单元格中仍然可见.

Ada*_*der 24

感谢Craig的答案指出了我正确的方向,我有一个解决方案.我还原了我的提交,它根据编辑模式移动了文本位置,并将其替换为一个新的解决方案,可以在调用layoutSubviews时将整个内容视图设置为正确的位置,从而在切换到编辑模式时生成自动动画:

- (void)layoutSubviews
{
    CGRect b = [self bounds];
    b.size.height -= 1; // leave room for the separator line
    b.size.width += 30; // allow extra width to slide for editing
    b.origin.x -= (self.editing) ? 0 : 30; // start 30px left unless editing
    [contentView setFrame:b];
    [super layoutSubviews];
}
Run Code Online (Sandbox Code Playgroud)

通过这样做,我能够删除在ABTableViewCell.m中找到的setFrame:override,因为它以前的逻辑加上我的添加现在可以在layoutSubviews中找到.

我在单元格上设置了浅灰色背景,以验证自定义背景是否正常工作,而不允许我们在它后面移动时看到它背后,它似乎工作得很好.

再次感谢Craig和其他任何研究过此事的人.

GitHub提交此解决方案:( 链接)


Cra*_*tis 10

你现在如何移动文本?或者更具体地说,你在哪个UITableViewCell方法中执行移动?

根据我的经验,覆盖layoutSubviews方法和设置框架将自动包装在动画中.

例如:

- (void)layoutSubviews {
    if (self.editing) {
        [titleLabel setFrame:CGRectMake(62, 6, 170, 24)];
    }
    else {
        [titleLabel setFrame:CGRectMake(30, 6, 200, 24)];
    }
    [super layoutSubviews];
}
Run Code Online (Sandbox Code Playgroud)


UIB*_*der 9

要完全控制自定义单元格中的编辑,您应该覆盖UITableViewCell子类中的willTransitionToState方法并检查状态掩码

- (void)willTransitionToState:(UITableViewCellStateMask)state
{
    NSString *logStr = @"Invoked";
    if ((state & UITableViewCellStateShowingEditControlMask)
        != 0) {
        // you need to move the controls in left
        logStr = [NSString stringWithFormat:@"%@
                  %@",logStr,@"UITableViewCellStateShowingEditControlMask"];
    }
    if ((state & UITableViewCellStateShowingDeleteConfirmationMask)
        != 0) {
        // you need to hide the controls for the delete button
        logStr = [NSString stringWithFormat:@"%@
                  %@",logStr,@"UITableViewCellStateShowingDeleteConfirmationMask"];
    }
    NSLog(@"%@",logStr);
    [super willTransitionToState:state];
}
Run Code Online (Sandbox Code Playgroud)

你也可以覆盖layoutSubviews

- (void)layoutSubviews {
    // default place for label
    CGRect alarmTimeRect = CGRectMake(37, 7, 75, 30);
    if (self.editing && !self.showingDeleteConfirmation) {
        // move rect in left
        alarmTimeRect = CGRectMake(77, 7, 75, 30);
    }
    [alarmTimeLabel setFrame:alarmTimeRect];
    [super layoutSubviews];
}
Run Code Online (Sandbox Code Playgroud)


小智 8

要处理滑动:(self.editing &&!self.showingDeleteConfirmation)