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 行为的一个很好的例子。
我实现了一个非常简单的自定义 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 行为的一个很好的例子。