如何在iOS应用程序中按段落(中等大小)打断选择?

如何在iOS应用程序中按段落(中等大小)打断选择?,ios,objective-c,swift,uitextview,nsattributedstring,Ios,Objective C,Swift,Uitextview,Nsattributedstring,如何将UITextView中的段落分割成完全独立的文本簇,例如在进行选择时,您只能选择该段落中的单词 在这种情况下,您只能选择文本“。” 我正在尝试在段落之外取消选择,做必要的数学来定义段落范围,但到目前为止运气不佳。如果我正确理解你的问题,我会尝试为每个段落创建一个UITextView,并正确定位它们。当用户按enter键时创建一个新视图(并确保在光标后保留文本),如果用户按delete键且光标位于第二个视图的开头,则将两个相邻视图的内容合并 这样,选择将在每个视图中工作,但用户不能同时在两

如何将
UITextView
中的段落分割成完全独立的文本簇,例如在进行选择时,您只能选择该段落中的单词

在这种情况下,您只能选择文本“


我正在尝试在段落之外取消选择,做必要的数学来定义段落范围,但到目前为止运气不佳。

如果我正确理解你的问题,我会尝试为每个段落创建一个
UITextView
,并正确定位它们。当用户按enter键时创建一个新视图(并确保在光标后保留文本),如果用户按delete键且光标位于第二个视图的开头,则将两个相邻视图的内容合并

这样,选择将在每个视图中工作,但用户不能同时在两个视图中进行选择

其思想是从游标定位当前段落的扩展 开始选择文本时的位置。然后只允许 段落范围与所选内容对应的段落范围之间的交点


这是自Swift 3起的解决方案



这是一个非常广泛的问题(@Abizern)你有什么建议?我不知道怎么说得更具体:(.我只想在我的richTextEditor上使用这种功能,我不知道从哪里开始。在我看来,问题是你列出了一组需求并要求解决方案。更好的方法可能是将问题分解为更小的部分。谢谢,我会这样做then@Abizern我已经做了一些改进。我一直在思考我对这种可能性感到担忧,但似乎有点过头了,我想这可能是一种更容易实现的方法。如果你想用代码支持你的想法,我会给你奖金,这样就不会丢失。那太好了。现在我看到了,我想另一个答案对于大多数情况来说是更好的答案。这个答案会给你更多的客户mization,但我认为另一个更好。
class RichTextView: UITextView {...}

extension RichTextView: UITextViewDelegate {

  func textViewDidChangeSelection(_ textView: UITextView) {
    let range = textView.selectedRange
    if range.length > 0 {
     if let maxRange = 
       textView.attributedText.getParagraphRangeContaining(cursorPosition: range.location){
          selectedRange = NSIntersectionRange(maxRange, range)
      }
    }
  }
}

extension NSAttributedString {

    func getParagraphRangeContaining(cursorPosition: Int) -> NSRange? {
        let cursorPosition = cursorPosition - 1

        let nsText = self.string as NSString
        let textRange = NSMakeRange(0, nsText.length)

        var resultRange : NSRange?
        nsText.enumerateSubstrings(in: textRange, options: .byParagraphs, using: {
            (substring, substringRange, _, _) in

            if (NSLocationInRange(cursorPosition , substringRange)) {
                resultRange = substringRange
                return
            }
        })
        return resultRange
    }
}