如何获得UITableViewCell移动开始和结束的通知?

Cor*_*ius 31 iphone uitableview drag ios

我的iOS应用程序中有一个UITableView会定期刷新.用户还可以随时移动tableview行(tableview始终处于编辑模式).

我想在用户开始拖动行时停止刷新计时器,并在删除行时再次启动它.

最后一部分应该很容易moveRowAtIndexPath,但如何获得有关拖动开始的通知?

mar*_*rux 40

您的UITableViewDelegate将收到以下通知以响应重新排序操作:

- (void)tableView:(UITableView *)tableView willBeginReorderingRowAtIndexPath:(NSIndexPath *)indexPath;
- (void)tableView:(UITableView *)tableView didEndReorderingRowAtIndexPath:(NSIndexPath *)indexPath;
- (void)tableView:(UITableView *)tableView didCancelReorderingRowAtIndexPath:(NSIndexPath *)indexPath;
Run Code Online (Sandbox Code Playgroud)

  • 对于任何想知道的人.它仍然在iOS 12中使用Swift 4调用,使用以下签名:`@objc public func tableView(_:UITableView,willBeginReorderingRowAtIndexPath indexPath:IndexPath)` (6认同)
  • 就像后续:我应该提到我使用这三种方法的应用程序刚被Apple批准,所以我们应该认为它们可以安全地用于改善用户体验. (3认同)
  • @mprudhom我收到了回调,但没有记录.您是否在生产应用程序中拥有这些委托方法?这被认为是私有API吗? (2认同)
  • 仍然在iOS 9.2和Swift 2中调用`func tableView(tableView:UITableView,didEndReorderingRowAtIndexPath indexPath:NSIndexPath)`.这样一个有用的方法,我想知道他们为什么不记录它. (2认同)

And*_*ese 9

我前段时间遇到了同样的问题但没有找到解决方案.虽然我开始回答并解释为什么不能这样做,但我实际上发现了它是如何完成的!:-)

简而言之:您必须创建一个自定义子类UITableViewCell.覆盖layoutSubviews以附加UILongPressGestureRecognizerUITableViewCellReorderControl.定义协议并使用委托来通知您想要拖动状态的任何人.

CustomTableViewCell.h:

#import <UIKit/UIKit.h>

@protocol CustomTableViewCellDelegate;

@interface CustomTableViewCell : UITableViewCell {
}

@property (nonatomic, assign) id <CustomTableViewCellDelegate> delegate;

@end

@protocol CustomTableViewCellDelegate
- (void)CustomTableViewCell:(CustomTableViewCell *)cell isDragging:(BOOL)value;
@end
Run Code Online (Sandbox Code Playgroud)

CustomTableViewCell.m:

#import "CustomTableViewCell.h"

@implementation CustomTableViewCell

@synthesize delegate = _delegate;

- (void)handleGesture:(UIGestureRecognizer *)gestureRecognizer {
    if (gestureRecognizer.state == UIGestureRecognizerStateBegan) {
        [_delegate CustomTableViewCell:self isDragging:YES];    // Dragging started
    } else if (gestureRecognizer.state == UIGestureRecognizerStateEnded) {
        [_delegate CustomTableViewCell:self isDragging:NO];     // Dragging ended
    }
}

- (void)layoutSubviews {
    [super layoutSubviews];

    for (UIView *view in self.subviews) {
        if ([NSStringFromClass ([view class]) rangeOfString:@"ReorderControl"].location != NSNotFound) {    // UITableViewCellReorderControl
            if (view.gestureRecognizers.count == 0) {
                UILongPressGestureRecognizer *gesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)];
                gesture.cancelsTouchesInView    = NO;
                gesture.minimumPressDuration    = 0.150;
                [view addGestureRecognizer:gesture];
            }
        }
    }
}

@end
Run Code Online (Sandbox Code Playgroud)

请注意,虽然此代码不使用任何私有API,但如果Apple更改其内部实现(即通过更改类名UITableViewCellReorderControl),它仍可能停止工作.

  • @Cornelius Apple在哪里添加并记录了新的委托方法?我在iOS 8上,他们仍然是私有API. (2认同)

Cha*_* SP 5

我刚刚发现了一个 hack,因为苹果会减少 alpha,我想我们可以使用它

@interface CustomTableViewCell () 
@property (nonatomic, assign) BOOL isDragging;
@end

-(void)draggingWillBegan
{
    //use a delegate method to inform tableview
}

-(void)draggingDidEnd
{
    //use a delegate method to inform tableview
}

- (void)layoutSubviews
{
    [super layoutSubviews];

    //Since apple wont provide en
    if(self.alpha <= 0.95 && !self.isDragging){
        self.isDragging = YES;
        [self draggingWillBegan];
    }

    if(self.alpha >= 0.95 && self.isDragging){
        self.isDragging = NO;
        [self draggingDidEnd];
    }
}
Run Code Online (Sandbox Code Playgroud)