UITableViewCell 中的自定义 UISwitch
Posted
技术标签:
【中文标题】UITableViewCell 中的自定义 UISwitch【英文标题】:Custom UISwitch inside a UITableViewCell 【发布时间】:2015-01-02 16:32:13 【问题描述】:我已经实现了一个非常简单的自定义 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 的单元格内工作。只有单击似乎有效(请注意,我没有使用手势......但我之前列出的事件)但我无法“滑动”开关手柄。
我在tableView:cellForRowAtIndexPath
方法中实例化控制器,将控件添加为单元格contentView
的子视图:
[cell.contentView addSubview:customSwitch];
我认为这与 UITableView 是 UIScrollView 的事实有关,我认为触摸事件会以某种方式被它“偷走”。
// 编辑--------
这里是与 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 内工作?
【问题讨论】:
您是否考虑过使用点击和平移手势? @Wain 我更喜欢使用 Touch 事件。在这种情况下有什么不同吗? 查看类似***.com/questions/9350041/…的其他问题 @MatterGoal 这不是糟糕设计的好理由。如果由于某种原因,您突然需要比屏幕显示更多的单元格,则必须完全重构此代码。通过从一开始就做好架构,更容易避免(可能)难以捉摸的错误。 您没有分享tableviewCell的任何代码,请分享tableViewCellForIndexPath中的代码 【参考方案1】:您需要使用手势来实现自定义开关,而不是尝试直接处理事件。
手势识别器在后台工作以协调他们的事件处理,例如,这就是为什么 UIScrollView 可以在另一个 UIScrollView 内工作的原因。您需要 UITableView(实际上是 UIScrollView)的协调才能正确处理其内容中的滑动手势。
在网络上搜索 Hardy Macia 的 UICustomSwitch 示例代码,以获取在自定义控件中匹配 UISwitch 行为的良好示例。
【讨论】:
【参考方案2】:你错过了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];
【讨论】:
致投反对票的人:愿意解释投反对票的原因吗? 你确定需要这些函数吗?我可以让开关在牢房外毫无问题地工作。 也尝试在beginTrackingWithTouch
和continueTrackingWithTouch
中实现sendActionsForControlEvents:
。具体来说:分别是[self sendActionsForControlEvents: UIControlEventTouchDown];
和[self sendActionsForControlEvents: UIControlEventTouchDragInside]
。
@MatterGoal 我确实读过它。也许你忽略了我上面的评论。尝试在 YOUR beginTracking 和 continueTracking 方法中添加 [self sendActionsForControlEvents: UIControlEventTouchDown];
和 [self sendActionsForControlEvents: UIControlEventTouchDragInside]
。我在我的项目中实现了这些,它对我来说非常有效。
对不起,我完全忽略了你的评论以上是关于UITableViewCell 中的自定义 UISwitch的主要内容,如果未能解决你的问题,请参考以下文章
UITableViewCell 中的自定义 UISwitch
自定义 UITableViewCell 中的自定义 UIView