如何将UITextView中的触摸传递给UITableViewCell

时间:2010-03-19 14:55:37

标签: iphone uitableview uitextview

我在自定义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

3 个答案:

答案 0 :(得分:33)

尝试[theTextView setUserInteractionEnabled:NO];如果用户需要能够编辑TextView的内容,那么您可能会遇到设计问题。

Swift 3:theTextView.isUserInteractionEnabled = false

故事板:勾选“启用用户交互”复选框。

答案 1 :(得分:2)

我知道这个问题已在5年前被问到,但是某些应用程序仍然非常需要具有UIDataDetectors的可点击单元格。

所以这里是UITextView子类,我在UITableView中适应这种特殊行为

-(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;
}

您可以修改它以满足您的需求......

希望它有所帮助。

答案 2 :(得分:1)

您的解决方案存在的问题是,如果您将UITextView置于UITableViewCell内,其超级视图将不再是实际的单元格。在单元格的视图结构中,iOS 7和iOS 8之间甚至存在细微差别。您需要做的是在层次结构中向下钻取(或向上钻取)以获取UITableViewCell实例。

我正在使用和修改@TheSquad的while循环以获取UITableViewCell,并将其分配给属性。然后覆盖这些触摸方法,在需要时使用单元格的触摸方法,并使用超级触摸方法的实现来获取默认行为。

// 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];
    }

}