如何将触摸从 UITextView 传递到 UITableViewCell
Posted
技术标签:
【中文标题】如何将触摸从 UITextView 传递到 UITableViewCell【英文标题】:How to pass touch from a UITextView to a UITableViewCell 【发布时间】:2010-03-19 14:55:36 【问题描述】:我在自定义 UITableViewCell 中有一个 UITextView。 textview 可以正常工作(滚动、显示文本等),但我需要用户能够点击表格单元格并转到另一个屏幕。现在,如果您点击表格单元格的边缘(即在 UItextView 之外),则会正确调用下一个视图。但很明显,在 uitextview 内部,触摸被捕获而不是转发到表格单元格。
我发现一篇文章谈到了继承 UITextView 以转发触摸。我没有运气就试过了。实现如下。我想知道是否可能a)我的textview的超级不是uitableviewcell,因此我需要以其他方式传递触摸或b)如果超级是uitableviewcell,如果我需要传递其他东西?任何帮助将不胜感激。
#import "ScrollableTextView.h"
@implementation ScrollableTextView
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
if (parentScrollView)
[parentScrollView touchesBegan:touches withEvent:event];
[super touchesBegan:touches withEvent:event];
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
if (parentScrollView)
[parentScrollView touchesCancelled:touches withEvent:event];
[super touchesCancelled:touches withEvent:event];
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
if (parentScrollView)
[parentScrollView touchesEnded:touches withEvent:event];
[super touchesEnded:touches withEvent:event];
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
if (parentScrollView)
[parentScrollView touchesMoved:touches withEvent:event];
[super touchesMoved:touches withEvent:event];
- (BOOL)canBecomeFirstResponder
return YES;
@end
【问题讨论】:
我使用这个答案找到了一个现代解决方案:***.com/a/41884532/4991890 【参考方案1】:试试[theTextView setUserInteractionEnabled:NO];
如果用户需要能够编辑TextView的内容,那么你可能在这里遇到了设计问题。
斯威夫特 3:theTextView.isUserInteractionEnabled = false
故事板:勾选“启用用户交互”复选框。
【讨论】:
这可能有点老了,但我遇到了同样的问题,这条线解决了它。谢谢:) 非常感谢!顺便说一句,如果有人喜欢在 Interface Builder 中进行设置:在检查器中打开 UITextView 的属性窗格,滚动到“视图”窗格所在的底部,然后取消选中“启用用户交互”。 我遇到的问题是我希望用户能够触摸电话号码,但我也需要继续。我仍在寻找两者兼得的方法。如果有人有任何建议,请告诉我。如果我发现我会在这里发布。 @DirectX 你找到解决方案了吗? @DirectX 为什么电话号码在可编辑字段中?也许把它放在UILabel
,接受触摸,做你需要做的事情,然后将触摸转发给响应者链中的下一个响应者。如果不是这种情况,请在此处打开一个新问题。【参考方案2】:
我知道这个问题在 5 年前就已经被问过了,但是对于某些应用程序来说,仍然非常需要这种行为才能拥有带有 UIDataDetectors 的可点击单元格。
这是我为适应 UITableView 中的这种特殊行为而编写的 UITextView 子类
-(id) initWithFrame:(CGRect)frame
self = [super initWithFrame:frame];
if (self)
self.delegate = self;
return self;
- (BOOL)canBecomeFirstResponder
return NO;
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
UIView *obj = self;
do
obj = obj.superview;
while (![obj isKindOfClass:[UITableViewCell class]]);
UITableViewCell *cell = (UITableViewCell*)obj;
do
obj = obj.superview;
while (![obj isKindOfClass:[UITableView class]]);
UITableView *tableView = (UITableView*)obj;
NSIndexPath *indePath = [tableView indexPathForCell:cell];
[[tableView delegate] tableView:tableView didSelectRowAtIndexPath:indePath];
- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange
return YES;
您可以修改它以满足您的需要...
希望对某人有所帮助。
【讨论】:
聪明的解决方法。虽然,当用户只是滚动UITextView
时,此代码也会触发委托,这不是预期的。以您的解决方案为首,我提出了我的另一个答案。
@IkhsanAssaat 即使用手指仔细触摸 TextView 以开始滚动,滚动也没有任何问题...在我的应用程序中它不会滚动和触发的唯一方法是单击TextView 上存在 URL,但最好有更多案例研究,用于不同的实现,谢谢。【参考方案3】:
您的解决方案的问题是,如果您将UITextView
放在UITableViewCell
中,它的超级视图将不是实际的单元格。在单元格的视图结构上,ios 7 和 iOS 8 之间甚至存在细微差别。您需要做的是向下钻取(或向上钻取)层次结构以获取 UITableViewCell
实例。
我正在使用和修改@TheSquad 的while 循环来获取UITableViewCell
,并将其分配给一个属性。然后重写这些 touch 方法,在需要时使用单元格的 touches 方法,并且只需使用 super 的 touch 方法的实现即可获得默认行为。
// set the cell as property
@property (nonatomic, assign) UITableViewCell *superCell;
- (UITableViewCell *)superCell
if (!_superCell)
UIView *object = self;
do
object = object.superview;
while (![object isKindOfClass:[UITableViewCell class]] && (object != nil));
if (object)
_superCell = (UITableViewCell *)object;
return _superCell;
#pragma mark - Touch overrides
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
if (self.superCell)
[self.superCell touchesBegan:touches withEvent:event];
else
[super touchesBegan:touches withEvent:event];
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
if (self.superCell)
[self.superCell touchesMoved:touches withEvent:event];
else
[super touchesMoved:touches withEvent:event];
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
if (self.superCell)
[self.superCell touchesEnded:touches withEvent:event];
else
[super touchesEnded:touches withEvent:event];
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
if (self.superCell)
[self.superCell touchesEnded:touches withEvent:event];
else
[super touchesCancelled:touches withEvent:event];
【讨论】:
以上是关于如何将触摸从 UITextView 传递到 UITableViewCell的主要内容,如果未能解决你的问题,请参考以下文章
将 UITapGestureRecognizer 触摸传递到底层 UITableViewCell