Обнаружение события backspace в UITextField
Я ищу решения о том, как захватить событие backspace, большинство ответов переполнения стека находятся в Objective-C, но мне нужно на языке Swift.
сначала я установил делегат для UITextField и установил его в self
self.textField.delegate = self;
тогда я знаю, что использовать shouldChangeCharactersInRange
метод делегата, чтобы определить, был ли нажат backspace, - это весь код в Objective-C. Мне нужен в Swift этот следующий метод, как показано ниже.
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
const char * _char = [string cStringUsingEncoding:NSUTF8StringEncoding];
int isBackSpace = strcmp(_char, "b");
if (isBackSpace == -8) {
// NSLog(@"Backspace was pressed");
}
return YES;
}
11 ответов
Надежда поможет вам: p
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
let char = string.cStringUsingEncoding(NSUTF8StringEncoding)!
let isBackSpace = strcmp(char, "\b")
if (isBackSpace == -92) {
println("Backspace was pressed")
}
return true
}
В Swift 3
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
let char = string.cString(using: String.Encoding.utf8)!
let isBackSpace = strcmp(char, "\b")
if (isBackSpace == -92) {
print("Backspace was pressed")
}
return true
}
:)
Если вам нужно обнаружить backspace даже в пустом текстовом поле (например, если вам нужно автоматическое переключение обратно в текстовое поле prev при нажатии backSpace), вы можете использовать комбинацию предлагаемых методов - добавить невидимый знак и использовать стандартный метод делегата textField:shouldChangeCharactersInRange:replacementString:
как следовать
-
создать невидимый знак
private struct Constants { static let InvisibleSign = "\u{200B}" }
-
установить делегат для textField
textField.delegate = self
-
событие
EditingChanged
проверить текст и при необходимости добавить невидимый символ как следовать:@IBAction func didChangeEditingInTextField(sender: UITextField) { if var text = sender.text { if text.characters.count == 1 && text != Constants.InvisibleSign { text = Constants.InvisibleSign.stringByAppendingString(text) sender.text = text } } }
-
добавить реализацию метода делегата
textField:shouldChangeCharactersInRange:replacementString:
extension UIViewController : UITextFieldDelegate { // MARK: - UITextFieldDelegate func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { let char = string.cStringUsingEncoding(NSUTF8StringEncoding)! let isBackSpace = strcmp(char, "\b") if (isBackSpace == -92) { if var string = textField.text { string = string.stringByReplacingOccurrencesOfString(Constants.InvisibleSign, withString: "") if string.characters.count == 1 { //last visible character, if needed u can skip replacement and detect once even in empty text field //for example u can switch to prev textField //do stuff here } } } return true } }
попробуй такое
public func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
if(string == "") {
print("Backspace pressed");
return true;
}
}
Примечание: Вы можете вернуться "правда " если вы хотите разрешить backspace. Еще можно вернуть "false".
Я предпочитаю подклассы UITextField
и переопределить deleteBackward()
потому что это намного надежнее, чем взлом использования shouldChangeCharactersInRange
:
class MyTextField: UITextField {
override public func deleteBackward() {
if text == "" {
// do something when backspace is tapped/entered in an empty text field
}
// do something for every backspace
super.deleteBackward()
}
}
на shouldChangeCharactersInRange
hack в сочетании с невидимым символом, который помещается в текстовое поле, имеет несколько недостатков:
- С помощью клавиатуры можно поместить курсор перед невидимым символом, и backspace больше не обнаруживается,
- пользователь может даже выбрать этот невидимый символ (используя
Shift Arrow
на клавиатуре или нажав на каре) и будет смущен этим странным персонажем, - панель автозаполнения предлагает странные варианты, пока есть только этот невидимый символ,
- the
placeholder
не отображается больше, - кнопка Очистить отображается, даже если она не должна для
clearButtonMode = .whileEditing
.
конечно, переопределение deleteBackward()
немного неудобно из-за необходимости создания подклассов. Но чем лучше UX делает это стоит усилий!
и если подклассы не идут, например, при использовании UISearchBar
благодаря встроенному UITextField
, метод swizzling тоже должен быть в порядке.
Swift 4
Я нахожу сравнение, используя strcmp
неактуально. Мы даже не знаем как!--1--> работает за капюшонами.Во всех остальных ответах при сравнении текущего char и \b
результаты -8
в objective-C и -92
в Swift. Я написал этот ответ, потому что вышеуказанные решения не сработали для меня. ( Xcode Версии 9.3 (9E145)
использование Swift 4.1
)
FYI: каждый символ, который вы фактически вводите, является массивом 1
или более элементов utf8 Encoding
. backSpace символ [0]
. Вы можете попробовать это.
PS: не забудьте назначить правильное delegates
на textFields
.
public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let char = string.cString(using: String.Encoding.utf8)!
if (char.elementsEqual([0])) {
print("Backspace was pressed")
}
else {
print("WHAT DOES THE FOX SAY ?\n")
print(char)
}
return true
}
Swift 4
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let char = string.cString(using: String.Encoding.utf8)!
let isBackSpace = strcmp(char, "\b")
if isBackSpace == -92 {
print("Backspace was pressed")
return false
}
}
Swift 4: если пользователь нажимает кнопку backspace, строка пуста, поэтому этот подход заставляет textField принимать только символы из указанного набора символов (в данном случае символы utf8) и backspaces (string.isEmpty case).
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if string.cString(using: String.Encoding.utf8) != nil {
return true
} else if string.isEmpty {
return true
} else {
return false
}
}
пожалуйста, не мусорите свой код. Просто поместите это расширение где-нибудь в свой код. (Swift 4.1)
extension String {
var isBackspace: Bool {
let char = self.cString(using: String.Encoding.utf8)!
return strcmp(char, "\b") == -92
}
}
а затем просто используйте его в своих функциях
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if string.isBackspace {
// do something
}
return true
}
я реализовал эту функцию:
и в случае, когда последний textFiled пуст, я просто хочу переключиться на предыдущий textFiled. Я пробовал все ответы выше, но никто не работает нормально в моей ситуации. По какой-то причине, если я добавлю больше логики, чем print
на isBackSpace == -92
скобки блокируют этот метод, который просто прекратил работу...
как для меня метод ниже более элегантный и работает как Шарм:
Свифт
class YourTextField: UITextField {
// MARK: Life cycle
override func awakeFromNib() {
super.awakeFromNib()
}
// MARK: Methods
override func deleteBackward() {
super.deleteBackward()
print("deleteBackward")
}
}
спасибо @LombaX за ответ
Swift 4
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
//MARK:- If Delete button click
let char = string.cString(using: String.Encoding.utf8)!
let isBackSpace = strcmp(char, "\b")
if (isBackSpace == -92) {
print("Backspace was pressed")
return true
}
}