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
只有两个视图,即
- UITableViewCellContentView
- UITableViewCellSeparatorView
如何在 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 5
和 iOS 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
}
}
}
}
使用自定义 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
只有两个视图,即
- UITableViewCellContentView
- UITableViewCellSeparatorView
如何在 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 5
和 iOS 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
}
}
}
}