有没有人知道内置的Notes应用程序如何设法显示数据检测器,但仍然可以编辑其UITextView?
我已经尝试将可编辑的默认设置为NO(因此数据检测器将工作)然后覆盖UITextView的触摸方法并将其设置为YES,但它最终滚动到底部,我必须再次点击以实际开始编辑。 / p>
我还尝试使用轻敲手势识别器,同样的事情发生了。我正在尝试在飞行中看到触摸事件并将可编辑设置为YES,以便UITextView将在分接点开始编辑但没有骰子 - 如果我,我无法通过触摸事件将其传递给UITextView混乱其可编辑的财产。
答案 0 :(得分:1)
一个简单的黑客就是在textview上放置一个透明视图来拦截触摸事件。当有人触及透明度时,将textview设置为可编辑,并使其成为第一个响应者,以便键盘显示。
然后当您辞退键盘的第一响应者状态(即用户完成编辑)时,将可编辑标志设置回NO。
<强> [编辑] 强>
要查找字符串的大小,您可以找出将触摸/光标映射到的位置。使用此:
CGSize *sizeOfString = [YourString sizeWithFont:[UIFont systemFontOfSize:yourTextViewFontSize]
constrainedToSize:CGSizeMake(widthOfYourTextView,
heightOfYourTextView)
lineBreakMode:UILineBreakModeWordWrap];
[编辑x2] 您是否尝试过将两个文本视图放在一起?一个是数据检测器不可编辑的,另一个是可编辑的,但alpha为0.0。当文本在一个文本中更改时,将文本复制到另一个文本。
答案 1 :(得分:0)
只需创建一个UITextView子类,并像这样重写func touchesEnded(_:with:)
(在Swift 4中):
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesEnded(touches, with: event)
// Only triggered when not in editing mode.
if !isEditable {
// Turning off editable will make the data detectors available.
// (I set my data detectors in Interface Builder)
isEditable = true
// Retreive the insert point from touch.
guard let location = touches.first?.location(in: self) else { fatalError() }
guard let position = closestPosition(to: location) else { fatalError() }
guard let range: UITextRange = self.textRange(from: position, to: position) else { fatalError() }
// You will want to make the text view enter editing mode by one tap, not two.
becomeFirstResponder()
// Set the insert point.
selectedTextRange = range
}
}
如果点击链接或选择字符串,则不会调用此函数,因此它适用于数据检测器。
要使数据检测器再次运行,只需将isEditable
设置为false
,可能在委托对象中:
func textViewDidEndEditing(_ textView: UITextView) {
textView.isEditable = false
}
关键是从触摸转动插入点。
答案 2 :(得分:0)
我能够通过结合 yesleon 和这个 answer 的答案来实现这一点。我相信它可以改进,但对我来说是可行的。
下面的代码是我从 ListItemTextView
继承的 UITextView
类的一部分。
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesEnded(touches, with: event)
guard let touchPoint = touches.first?.location(in: self) else { fatalError() }
let glyphIndex = self.layoutManager.glyphIndex(for: touchPoint, in: self.textContainer)
let glyphRect = self.layoutManager.boundingRect(forGlyphRange: NSRange(location: glyphIndex, length: 1), in: self.textContainer)
if glyphIndex < self.textStorage.length,
glyphRect.contains(touchPoint),
self.textStorage.attribute(NSAttributedString.Key.link, at: glyphIndex, effectiveRange: nil) != nil {
// Then touchEnded on url
return
} else {
isEditable = true
// Retreive the insert point from touch.
guard let position = closestPosition(to: touchPoint) else { fatalError() }
guard let range: UITextRange = self.textRange(from: position, to: position) else { fatalError() }
// You will want to make the text view enter editing mode by one tap, not two.
becomeFirstResponder()
// Set the insert point.
selectedTextRange = range
}
}