【问题标题】:UITableViewCell delete button gets covered upUITableViewCell 删除按钮被掩盖
【发布时间】:2013-09-27 03:17:55
【问题描述】:

更新:

感谢“Evgeny S”提供的信息,我能够确定覆盖删除按钮的是单元格背景。我在单元格初始化的开头调用了以下函数:

- (void) setupGradientsWithHeight:(int) the_height
{
    CAGradientLayer* gradient = [CAGradientLayer layer];

    gradient.frame  = CGRectMake(self.bounds.origin.x,
                                 self.bounds.origin.y,
                                 self.bounds.size.width,
                                 the_height);

    gradient.colors = [NSArray arrayWithObjects:
                       (id)[UIColor colorWithRed:218.0f/255.0f
                                           green:218.0f/255.0f
                                            blue:220.0f/255.0f
                                           alpha:1.0].CGColor,
                       (id)[UIColor colorWithRed:180.0f/255.0f
                                           green:180.0f/255.0f
                                            blue:184.0f/255.0f
                                           alpha:1.0].CGColor,nil];

    UIView* bgview = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1, 1)];

    [bgview.layer addSublayer:gradient];
    [self setBackgroundView:bgview];
}

通过不添加背景视图来解决问题。但是,我想知道如何在保留每个单元格的渐变背景的同时解决它?

可能会发生两种情况之一。当删除按钮出现时,背景视图要么被移动然后返回——要么它的大小被减小然后返回。 我尝试弄乱渐变框架的宽度组件“self.bounds.size.width”,但我仍然看不到这会如何影响事情,因为这个函数只在单元初始化时调用一次。

原帖:

我在 iOS6 SDK 下的 Xcode4 中创建了一个应用程序 - 但在新环境(Xcode5 和 iOS7 SDK)中加载内容后,我遇到了问题。请注意,我已经解决了进行转换时出现的所有构建错误和警告。

我有一个包含一些单元格的表格视图。进入编辑模式后,如果单击红色切换按钮启动单元格的删除模式 - 动画开始并出现“删除”按钮 - 但只是短暂的,然后突然重新隐藏。

我应该注意的另一件奇怪的事情是,即使删除按钮被遮住 - 您仍然可以单击它应该在的位置并删除单元格。

我已尝试尽可能多地删除我的“自定义代码”,我已删除已覆盖的函数并尝试将其恢复到原始状态 - 但无济于事。

有一次我在输出日志中看到一条奇怪的消息: “当我们已经有一个单元格时,尝试设置滑动以删除单元格……这似乎不太好”。由于某种原因,该消息出现的时间更长,我似乎不记得当时我在做什么。

关于可能导致此问题的任何想法或建议?

http://www.youtube.com/watch?v=vCAGzSaOwp4

【问题讨论】:

  • 没有自定义单元格的实现细节,真的很难猜到问题...
  • iOS 7.0.3 已修复此问题。
  • 我在 iOS 7.0.4 中继续遇到这个问题。

标签: uitableview ios7 xcode5


【解决方案1】:

我通过找到删除按钮视图并将其置于前面来解决此问题。我是在 UITableViewCell 子类的 layoutSubviews 中完成的。

这里有一小段代码可以让你知道如何做:

- (void)layoutSubviews
{
    [super layoutSubviews];

    for (UIView *subview in self.subviews) {

        for (UIView *subview2 in subview.subviews) {

            if ([NSStringFromClass([subview2 class]) isEqualToString:@"UITableViewCellDeleteConfirmationView"]) { // move delete confirmation view

            [subview bringSubviewToFront:subview2];

        }
    }
}

【讨论】:

  • 我试过了,我知道代码正在运行,但我的删除按钮仍然消失。
【解决方案2】:

这是 iOS 7 中无数的错误之一。

由于某种原因,iOS 将 backgroundView 移动到删除按钮上。 您可以通过继承您的 backgroundView 并实现派生视图的 setFrame 函数来解决此问题,如下所示:

- (void)setFrame:(CGRect)frame
{
    if ([[[UIDevice currentDevice] systemVersion] compare:@"7.0" options:NSNumericSearch] != NSOrderedAscending) {
        // background view covers delete button on iOS 7 !?!
        [super setFrame:CGRectMake(0, frame.origin.y, frame.size.width, frame.size.height)];
    } else {
        [super setFrame:frame];
    }
}

附带说明:您可以通过在派生视图中子类化和实现 layerClass 来避免需要单独的子层:

+ (Class)layerClass
{
    return [CAGradientLayer class];
}

【讨论】:

  • 很好的解决方案。这是防止重新覆盖删除按钮的方法。在 iOS6 中,我曾经将左侧的删除控件从 (-) 更改为 (I),但现在行滑动。有没有一种简单的方法可以在 iOS7 中保留 iO6 方式,还是我只需要接受我的行的一部分在滑动时会被隐藏。
  • 你能不能简单解释一下。如何对自定义单元格和默认单元格中的背景视图进行子类化。
【解决方案3】:
- (void)layoutSubviews
{
    [super layoutSubviews];
    [self sendSubviewToBack:self.contentView];
}

【讨论】:

  • 不幸的是,这对我不起作用,使用自定义格式的单元格这使我的单元格上的文本不可见。 -rrh
【解决方案4】:

我遇到了一个问题,我的 UITableView 处于编辑模式,删除 2-3 行后,我收到消息“尝试设置滑动以删除单元格,而我们已经有一个单元格......这似乎不太好”记录,然后除一个单元格之外的所有单元格上的用户交互被禁用。

我解决了这个问题

[myTableView setEditing:NO animated:NO];
[myTableView setEditing:YES animated:NO];

每次删除后。

这个解决方法在我的情况下有效。

【讨论】:

    【解决方案5】:

    您可以使用 colorWithPatternImage,但对我来说使用 self.layer.content 更容易。 例如:

    cell.layer.contents = (id)[UIImage imageNamed:@"singleRow.png"].CGImage;
    

    这样图像就不会被拉伸,也不必是精确的尺寸。 这样删除按钮就不会被单元格背景图像覆盖。 顺便说一句:这些自定义渐变背景似乎与 iOS 7 的基本外观不匹配,您认为这可能是不批准该应用的理由吗?

    【讨论】:

      【解决方案6】:

      我遇到了类似的问题,并且有一个解决方法,将“删除”按钮放在我的单元格内容之上,但动画有点难看。完成后,该按钮可见并执行正确的操作。

      创建 UITableViewCell 的自定义子类并添加以下代码:

      -(void)didTransitionToState:(UITableViewCellStateMask)state
      {
          if (state & UITableViewCellStateShowingDeleteConfirmationMask ) {
              [self sendSubviewToBack:self.contentView];
      
          }
      
          [super didTransitionToState:state];
      }
      

      将不胜感激对这种方法或其他指针的改进。

      【讨论】:

        【解决方案7】:

        清洁剂,通用解决方案

        假设一个仅限 iOS7 的应用程序,使用类似于上面 chris 发布的技术,我相信这里的方法:https://stackoverflow.com/a/19416870/535054 会更干净。

        在这种方法中,您不需要对 backgroundView 进行子类化,因为不同的单元格可能会有所不同。

        将代码放在我上面链接到的答案中,在自定义表格单元格层次结构的根目录中,以及所有表格单元格(从它继承的)中,只要他们使用 backgroundView 就可以得到修复selectedBackgroundView 属性。

        【讨论】:

        【解决方案8】:

        更新到 XCode 5.0.1 后我仍然看到这个问题,但我使用了不同的解决方法,即使用名为 changeTitle 的布尔值在 willBeginEditingRowAtIndexPath 中设置为 NO,在 editingStyleForRowAtIndexPath 中设置为 YES如果我们不在行删除模式。

        然后我使用该变量在titleForDeleteConfirmationButtonForRowAtIndexPath 中用一些额外的空格填充按钮标题。

        -(NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath {
            if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0 && changeTitle) {
                return @"        Delete";
            }
            return @"Delete";
        }
        

        它对我有用,但主要缺点是确认区域比您想象的要宽,因此可能会无意删除。

        【讨论】:

          【解决方案9】:

          您可以通过为 uitableview 设置所需的背景并设置 cell.backgroudColor = [UIColor clearColor];cell.contentView.backgroundColor = [UIColor clearColor]; 来避免此问题

          【讨论】:

          • 这让我朝着正确的方向前进,谢谢。我已经更新了我的答案以包含可疑代码。对新细节有任何见解吗?
          • 我替换了这段代码: UIView *view = [[UIView alloc] initWithFrame:self.frame]; view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"cell_background_normal.png"]]; self.backgroundView = 视图;使用以下代码: [self setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@"cell_background_normal.png"]]];在自定义我的自定义单元格时,就成功了。
          • 我仍然不确定如何在我的代码中使用它,因为我有一个需要添加的 CAGradientLayer。无论哪种方式,我都放弃了渐变,因为当我删除它时,删除按钮是可见的,并且单元格的纯白色外观与 iOS7 的设计模式相匹配。感谢您的帮助!
          【解决方案10】:

          如果您在 iOS 6 SDK 中启动项目并使用情节提要,这可能是约束问题。尝试删除所有单元格约束并回退到建议。这可以解决删除按钮的问题。我在两个不同的项目中遇到了这样的问题,并且按照描述的方式解决了。

          【讨论】:

            【解决方案11】:

            还有一种解决方法:

            - (void) layoutSubviews {
                [super layoutSubviews];
            
                if ([ [ [UIDevice currentDevice] systemVersion] compare: @"7.0" options: NSNumericSearch] != NSOrderedAscending) {
                    if (iOS7 == YES) {
                        self.backgroundView.frame = CGRectMake(0, self.backgroundView.frame.origin.y,
                                                               self.backgroundView.frame.size.width, self.backgroundView.frame.size.height);
                }
            }
            

            【讨论】:

              【解决方案12】:

              这是一种更好的方法,只需确保您将 UITableviewController 子类化以获得更好的性能并添加此代码

              - (void)setEditing:(BOOL)editing animated:(BOOL)animated {
              
              [super setEditing:editing animated:animated];
              
              CGRect frame = self.tableView.frame;
              
              if(editing){
                  [self.tableView setFrame:CGRectMake(0, frame.origin.y, frame.size.width, frame.size.height)];
                  //other codes to run if needed
              }else{
                  [self.tableView setFrame:frame];
                  //other codes to run if needed
              }
              

              }

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2012-05-24
                • 1970-01-01
                相关资源
                最近更新 更多