永久地将文本附加到UITextView

时间:2017-09-16 21:56:22

标签: ios swift nsattributedstring

我正在尝试创建一个UITextView,在选择时将用户句柄添加到文本的开头。

我知道可以创建另一个UITextView并将其放在第二个UITextView的左侧,使其看起来就像它们属于同一范围一样但是为了格式化目的,它会更容易如果两个部分都是同一文本视图的一部分......

这是我正在使用的功能及其使用的示例。

func addHandle(text:String, handle:String) -> NSAttributedString {

    let convertedText = NSMutableAttributedString()

    let h = NSMutableAttributedString(string: handle)
    h.beginEditing()

    let m = NSMutableAttributedString(string: text)
    m.beginEditing()


    do {
        m.addAttributes([NSFontAttributeName: UIFont.init(name: "PingFangSC-Regular", size: 18)], range: (m.string as NSString).range(of: m.string))
        h.addAttributes([NSFontAttributeName: UIFont.init(name: "PingFangSC-Medium", size: 18)], range: (h.string as NSString).range(of: h.string))

        convertedText.append(h)
        convertedText.append(m)

        m.endEditing()
        h.endEditing()
    }
    return convertedText
}

let myHandle = "Johnny: "
let myMessage = "This is a test"

addHandle(text: myMessage, handle: myHandle)

在这种情况下,句柄和消息都可以连接在一起。

但是当文本被更改时,如下所示,由于句柄是新文本的一部分,它再次运行该函数并再次添加句柄。

func textViewDidBeginEditing(_ textView: UITextView) {
    let currentString: String = textView.text!
    self.t.searchBar.attributedText = addHandle(text: currentString, handle: "Johnny: ")
}

 func textViewDidChange(_ textView: UITextView) {

    let currentString: String = textView.text!
    self.t.searchBar.attributedText = addHandle(text: currentString, handle: "Johnny: ")

    UIView.animate(withDuration: 0.15, delay: 0, options: UIViewAnimationOptions.curveEaseOut, animations: {
        self.view.layoutIfNeeded()
    }, completion: { (completed) in

    })
}

我应该如何修改我的功能或实现以确保

  1. 句柄始终位于消息
  2. 之前
  3. 用户无法从文本中删除句柄
  4. 以下应该是可能的:

    Johhny:测试消息

    约翰尼:

    这不可能

    Johnn

    有什么建议吗?

    修改 这是显示当前行为的屏幕截图。 句柄是“Johnny:”,输入的文本是“This”

    enter image description here

2 个答案:

答案 0 :(得分:1)

我认为你应该使用类似的东西(注意我使用了textField,但你可以为textView做同样的事情):

public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
   var newString = (textField.text! as NSString).replacingCharacters(in: range, with: string)
   if !newString.hasPrefix(handle) {
       newString = "\(handle): \(newString)"
   }
   textView.text = newString

   // Optional font color change for the handle
   let attributedString = NSMutableAttributedString(string: textView.text!, attributes: [ NSFontAttributeName : generalFont, NSForegroundColorAttributeName: textView.textColor ]);
   attributedString.addAttribute(NSFontAttributeName, value: anotherFont, range: NSMakeRange(0, handle.characters.count));
   textView.attributedText = attributedString
   return false
}

如果范围涵盖字符串的第一个字符(放置处理的位置),您也可以尝试检查range并拒绝编辑(返回false)。

答案 1 :(得分:0)

请检查:

funs textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {

    let myHandle = "Johnny: "
    let substringRange: NSRange = (textView.text as NSString).range(of: myHandle)
    if range.location >= substringRange.location && range.location <= substringRange.location + substringRange.length - 1 {
        return false
    }
    return true
}