UITableViewCell 中的自定义 UISwitch

Custom UISwitch inside a UITableViewCell

我实现了一个非常简单的自定义 UISwitch,它使用如下触摸事件:

- (BOOL)beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
- (BOOL)continueTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
- (void)endTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event

我可以毫无问题地在我的视图中使用此控件。 Control 模拟 UISwitch,因此它可以通过拖动或点击来更改值。

我的问题是我无法让此控件在 UITableView 的单元格内工作。只有单击似乎有效(请注意,我没有使用手势...而是我之前列出的事件)但我不能 "swipe" 开关手柄。

我在 tableView:cellForRowAtIndexPath 方法中实例化控制器,将控件添加为单元格的子视图 contentView:

[cell.contentView addSubview:customSwitch];

我想这与 UITableView 是一个 UIScrollView 这一事实有关,我认为触摸事件以某种方式得到 "stolen"。

// 编辑--------------------

这里是与Touch事件相关的代码。

- (BOOL)beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
{
    [super beginTrackingWithTouch:touch withEvent:event];

    self.dragged = NO;

    return YES;
}

- (BOOL)continueTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
{
    if (!self.enabled) {
        return NO;
    }

    [super continueTrackingWithTouch:touch withEvent:event];
    self.dragged = YES;
    CGPoint touchPoint = [touch locationInView:self];

    float centerPoint = FIXED_WIDTH / 2.0;

    [self centerOn:(touchPoint.x > centerPoint) animated:YES completion:nil];

    return YES;
}

- (void)endTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
{
    [super endTrackingWithTouch:touch withEvent:event];

    CGPoint touchPoint = [touch locationInView:self];

    BOOL currentOn = self.on;
    BOOL nextOn;

    if (self.dragged) {
        float centerPoint = FIXED_WIDTH / 2.0;
        nextOn = (touchPoint.x > centerPoint);

        [self setOn:nextOn animated:NO];
    }else{
        nextOn = !self.on;
        [self setOn:nextOn animated:YES];
    }
    self.dragged = NO;

    if (currentOn != nextOn) {
        [self sendActionsForControlEvents:UIControlEventValueChanged];
    }
}

如何在不干扰 UIScrollView/UITableView 的情况下使控件在 Cell 内工作?

你错过了touchesBegan:touchesMoved:吗?

- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{
    [super touchesBegan:touches withEvent:event];

    // Get the only touch (multipleTouchEnabled is NO)
    UITouch* touch = [touches anyObject];

    // Track the touch
    [self beginTrackingWithTouch:touch withEvent:event];
}

- (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
{
    [super touchesMoved:touches withEvent:event];

    // Get the only touch (multipleTouchEnabled is NO)
    UITouch* touch = [touches anyObject];

    // Track the touch
    [self continueTrackingWithTouch:touch withEvent:event];
}

您需要使用手势来实现您的自定义开关,而不是尝试直接处理事件。

手势识别器在幕后工作以协调其事件处理,例如,这就是为什么一个 UIScrollView 可以在另一个 UIScrollView 内部工作。您需要协调 UITableView(实际上是 UIScrollView)以正确处理其内容中的滑动手势。

在网络上搜索 Hardy Macia 的 UICustomSwitch 示例代码,了解在自定义控件中匹配 UISwitch 行为的一个很好的例子。