iOS10:UITableViewCell的删除按钮自定义高度

iOS 10: UITableViewCell's delete button custom height

使用自定义 UITableViewCell,我正在尝试更改 tableViewCell 的删除按钮的高度。我已经在 SO 上尝试了所有可用的解决方案。

每个人都提到在 customTableViewCell class 中我们需要覆盖 layoutSubviews 方法并迭代 self.subViews 以找到一个子视图,它应该等于 UITableViewCellDeleteConfirmationView 或在其他 iOS 版本中它是 UITableViewCellDeleteConfirmationControl 所以我使用了以下代码:

- (void)layoutSubviews
{
    [super layoutSubviews];

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationBeginsFromCurrentState:YES];
    [UIView setAnimationDuration:0.0f];

    for (UIView *subView in self.subviews) {
        NSLog(@"subview: %@", self.subviews);
        if([NSStringFromClass([subView class]) rangeOfString:@"Delete"].location != NSNotFound) {
            CGRect newFrame = subView.frame;
            newFrame.size.height = 87;
            subView.frame = newFrame;
        }
    }

    [UIView commitAnimations];
}

但是self.subView只有两个视图,即

如何在 iOS 10+ 中获取 tableViewCell 的删除按钮视图?

编辑

这是我的视图层次结构:

致所有正在为同样的问题而苦苦挣扎的人。

iOS10+ 中,UITableView 的删除按钮的视图层次结构已更改。现在它属于 UITableView - UISwipeActionPullView - UISwipeActionStandardButton

所以现在我们不需要覆盖自定义 UITableViewCell 的 layoutSubviews 方法,而是需要迭代 UITableView 子视图以获得 UISwipeActionStandardButton。我发现 tableView 的 willBeginEditingRowAtIndexPath 委托是一个合适的地方,

- (void)tableView:(UITableView *)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath
{
    for (UIView *subview in tableView.subviews) {
        if ([NSStringFromClass([subview class]) isEqualToString:@"UISwipeActionPullView"]) {
            if ([NSStringFromClass([subview.subviews[0] class]) isEqualToString:@"UISwipeActionStandardButton"]) {
                CGRect newFrame = subview.subviews[0].frame;
                newFrame.size.height = 72;
                subview.subviews[0].frame = newFrame;

                //Other changes on this view can also be applied like
                subview.subviews[0].backgroundColor = [UIColor redColor];
                subview.subviews[0].layer.cornerRadius = 12;
                subview.subviews[0].layer.masksToBounds = YES;
            }
        }
    }
}

相同的代码,但适用于 Swift 5iOS 12+

 func tableView(_ tableView: UITableView, willBeginEditingRowAt indexPath: IndexPath) {
        for subview in tableView.subviews {
            if NSStringFromClass(type(of: subview)) == "UISwipeActionPullView",
                let button = subview.subviews.first,
                NSStringFromClass(type(of: button)) == "UISwipeActionStandardButton" {

                button.backgroundColor = .red
                button.layer.cornerRadius = 8
                button.layer.masksToBounds = true
                (button as? UIButton)?.contentHorizontalAlignment = .center
                (button as? UIButton)?.contentVerticalAlignment = .center
                (button as? UIButton)?.titleEdgeInsets = UIEdgeInsets(top: 6, left: 0, bottom: 0, right: 0)
                button.superview?.backgroundColor = UIColor(white: 0.97, alpha: 1)
                button.superview?.layoutIfNeeded()
            }
        }
    }

对于IOS 13,位置再次发生变化,不在table视图中,它再次在_UITableViewCellSwipeContainerView 中。因此你应该遍历它作为 well.Take 看下面

   ([NSStringFromClass([subview class]) 
    isEqualToString:@"_UITableViewCellSwipeContainerView"]){

            for (UIView *deleteButtonSubview in subview.subviews){

                if ([NSStringFromClass([deleteButtonSubview class])
                     isEqualToString:@"UISwipeActionPullView"]) {



                    if ([NSStringFromClass([deleteButtonSubview.subviews[0] class]) isEqualToString:@"UISwipeActionStandardButton"]) {

                       //do what you want
                    }
                }

            }
        }

Swift 5,这适用于 iOS12、iOS13 和 iOS14

  func tableView(_ tableView: UITableView, willBeginEditingRowAt indexPath: IndexPath) {
    // for iOS13, iOS14
    if let swipeContainerView = tableView.subviews.first(where: { String(describing: type(of: [=10=])) == "_UITableViewCellSwipeContainerView" }) {
      if let swipeActionPullView = swipeContainerView.subviews.first, String(describing: type(of: swipeActionPullView)) == "UISwipeActionPullView" {
        swipeActionPullView.frame.size.height -= 10
      }
    }

    // for iOS12
    tableView.subviews.forEach { subview in
      if String(describing: type(of: subview)) == "UISwipeActionPullView" {
        subview.frame.size.height -= 10
      }
    }
  }
 func tableView(_ tableView: UITableView, willBeginEditingRowAt indexPath: IndexPath) {
    tableView.subviews.forEach { subview in
        if String(describing: type(of: subview)) == "_UITableViewCellSwipeContainerView" {
            if let swipeActionPullView = subview.subviews.first, String(describing: type(of: swipeActionPullView)) == "UISwipeActionPullView" {
                swipeActionPullView.frame.size.height -= 16
            }
        }
    }
}