我有一个视图,具有类似此视图1的东西,它具有uitextview的子视图。
我不得不在文本视图中启用链接和日期事件,并在其上启用了用户互动。但是,我需要在超级视图上进行一些点击处理,即视图1,所以我在超级视图上也启用了一个点击手势。
使用此设置,我将在文本视图中获得链接检测和处理,如果我没有点击链接,则Tap手势将传递给超级视图。但是,在iOS 11中,这似乎被打破了,我似乎永远无法将水龙头手势传递给超级视图。有人可以帮助我以先前版本的方式恢复iOS 11上的相同行为。
我编写的代码是这样的 -
[V addSubView:tv];
[tv setFrame:[self calculateFrameForTextView]];
[tv setUserInteractionEnabled:YES];
[tv setEditable:NO];
[tv setSelectable:YES];
[tv setDataDetectorTypes:UIDataDetectorTypeAll];
UITapGestureRecognizer *tap= [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doSomething)];
[V addGestureRecognizer:tap];
............................
| UIView (V) |
| |
| |-------------------| |
| | UITextView (tv) | |
| |...................| |
.............................
如果我点击文本视图上的任何内容,这不是链接/其他数据检测器类型,我希望将" dosomething"称为"选择器",并在超级视图上点击注册。这种行为在版本中起作用<ios11
我终于找出了一种从iOS 11中从文本视图中检测触摸的解决方案。尚未在早期版本上进行测试。
点击链接或附件不会触发闭合。
/// Provide a callback when single tapping on a non-attachment area
@IBDesignable class UITextViewFixed: UITextView {
var didTappedOnAreaBesidesAttachment: (() -> ())? = nil
// A single tap won't move.
private var isTouchMoved = false
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesMoved(touches, with: event)
isTouchMoved = true
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesEnded(touches, with: event)
if !isTouchMoved &&
!isTapOnAttachment(touches.first!.location(in: self)) &&
selectedRange.length == 0 {
didTappedOnAreaBesidesAttachment?()
}
isTouchMoved = false
}
override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesCancelled(touches, with: event)
// `UITextView` will cancel the touch then starting selection
isTouchMoved = false
}
private func isTapOnAttachment(_ point: CGPoint) -> Bool {
let range = NSRange(location: 0, length: attributedText.length)
var found = false
attributedText.enumerateAttribute(.attachment, in: range, options: []) { (value, effectiveRange, stop) in
guard value is NSTextAttachment else {
return
}
let rect = layoutManager.boundingRect(forGlyphRange: effectiveRange, in: textContainer)
if rect.contains(point) {
found = true
stop.pointee = true
}
}
return found
}
}