如何获取UITextView中光标之前的Character?

时间:2018-09-26 10:04:18

标签: ios swift uitextview

假设我有以下UITextView对象:

var textView = UITextView()
textView.text = "Hello World!"

现在让我们说我不想允许用户在编辑时删除“ W”字符。我怎么知道哪个字符在光标之前(或被光标选中)?

我正在寻找可以像这样工作的东西:

if textView.characterBeforeCursor() != "W" {
   textView.deleteBackward()
}

或...(当用户选择“ W”字符时):

if textView.selectedTextContains("W") == false {
   textView.deleteBackward()
}

我应该使用哪种方法来完成此任务?

2 个答案:

答案 0 :(得分:3)

这是一个想法,尚未经过充分测试,但似乎可以正常工作...只要抓住将要作用的角色,并在目标为目标的情况下阻止退格...同样对于文本选择,如果选择包含定位,我们阻止了新文本。

import UIKit

class ViewController: UIViewController, UITextViewDelegate {

    @IBOutlet weak var textView: UITextView!

    override func viewDidLoad() {
        super.viewDidLoad()
        self.textView.delegate = self
        // Do any additional setup after loading the view, typically from a nib.
    }

    func characterBeforeCursor() -> String? {
        // get the cursor position
        if let cursorRange = textView.selectedTextRange {
            // get the position one character before the cursor start position
            if let newPosition = textView.position(from: cursorRange.start, offset: -1) {
                let range = textView.textRange(from: newPosition, to: cursorRange.start)
                return textView.text(in: range!)
            }
        }
        return nil
    }

    func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
        if (characterBeforeCursor() == "W") {
            let char = text.cString(using: String.Encoding.utf8)!
            let isBackSpace = strcmp(char, "\\b")
            if (isBackSpace == -92) {
                return false
            }
            return true
        }
        else {
            if let range = textView.selectedTextRange {
                let selectedText = textView.text(in: range)
                if (selectedText!.contains("W")) {
                    return false
                }
            }
            return true
        }
    }
}

答案 1 :(得分:1)

这应该做到:

let forbiddenLetter = "W" 

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

    guard let txt = textView.text, let txtRange = Range(range, in: txt) else {
        return false
    }

    let subString: Substring = txt[txtRange]

    return !subString.contains(forbiddenLetter)
}

let txt = textView.text上面的代码中,为简单起见,我们可以保持强制展开textView.text!,因为.text属性的设计绝不会为非nil返回nil UITextView。

通过let txtRange = Range(range, in: txt),我们得到类型为Range<String.Index>的变量,而不是range的原始NSRange。这样,我们可以获得textView即将更改的txt的子字符串。

最后,返回检查subString是否包含forbiddenLetter的结果。


此代码段将阻止使用以下方法删除W

  • 退格键
  • 删除选择
  • 粘贴选择
  • 自动更正(从弹出窗口中)