Как получить Символ, который находится перед курсором в UITextView? - PullRequest
0 голосов
/ 26 сентября 2018

Допустим, у меня есть следующий 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 голосов
/ 26 сентября 2018

Это должно сделать это:

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 для ненулевого UITextView.

По let txtRange = Range(range, in: txt) мы получаем переменную типа Range<String.Index> вместо ванильного NSRange, которым является range.Таким образом мы можем получить подстроку txt, которую textView собирается изменить.

Наконец, возвращается результат проверки того, содержит ли subString forbiddenLetter.


Этот фрагмент не позволит удалить W с помощью:

  • Клавиша Backspace
  • Удаление выделения
  • Вставка поверх выделения
  • Автозамена (из всплывающего окна)
0 голосов
/ 26 сентября 2018

Вот идея, не полностью проверенная, но, кажется, работает ... Просто возьмите символ, над которым нужно воздействовать, и заблокируйте клавишу возврата, если она является целью ... Также в отношении выделения текста, если выделение содержитЦель вообще, мы блокируем новый текст.

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
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...