【问题标题】:iOS 10: UITableViewCell's delete button custom heightiOS 10:UITableViewCell 的删除按钮自定义高度
【发布时间】:2018-03-02 11:10:19
【问题描述】:

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

大家都提到,在 customTableViewCell 类中,我们需要重写 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只有两个视图,即

  • UITableViewCellContentView
  • UITableViewCellSeparatorView

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

编辑

这是我的视图层次结构:

【问题讨论】:

  • 尝试访问UITableViewCellContentView的子视图。虽然我强烈建议不要更改删除按钮的高度
  • @Malik 已经尝试过了,UITableViewCellContentView 只包含一个子视图,即 UIView。
  • 可能是该 uiview 的子视图。获取层次结构的最快方法是在调试时使用Debug->View Debugging->Capture View Hierarchy。在那里您可以看到完整的层次结构并更好地了解如何导航到按钮
  • 请看我更新的答案。
  • 捕获层次结构时删除按钮是否可见?您需要打开应用程序,滑动以显示删除按钮,然后捕获层次结构。如果在列表中找不到删除按钮,请通过旋转捕获的视图在图形视图中找到它。找到后,单击删除按钮,它会自动在左侧面板中突出显示它

标签: objective-c uitableview ios10


【解决方案1】:

适用于所有遇到同样问题的人。

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

所以现在我们需要迭代 UITableView 子视图来获取 UISwipeActionStandardButton,而不是重写自定义 UITableViewCell 的 layoutSubviews 方法。而且我发现 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;
            }
        }
    }
}

【讨论】:

  • 这是迄今为止我在这个主题上看到的最清晰的答案之一。但是,如果有人在 IOS 13 中遇到同样的问题,我在下面写了一个修复程序
【解决方案2】:

相同的代码,但适用于 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()
            }
        }
    }

【讨论】:

    【解决方案3】:

    对于 IOS 13,位置再次发生变化,而不是在表格视图中,它再次在 _UITableViewCellSwipeContainerView 中。因此,您也应该遍历它。看看下面

       ([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
                        }
                    }
    
                }
            }
    

    【讨论】:

      【解决方案4】:

      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: $0)) == "_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
            }
          }
        }
      

      【讨论】:

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