Короткий ответ: вам нужно выполнить обратный вызов следующим образом:
function callback(response) {
// Here you can do what ever you want with the response object.
console.log(response);
}
$.ajax({
url: "...",
success: callback
});
Версия NSString
(в отличие от Swift String) replacingCharacters(in: NSRange, with: NSString)
принимает NSRange
, поэтому одно простое решение - сначала конвертировать String
в NSString
. Названия делегатов и методов замены немного отличаются в Swift 3 и 2, поэтому в зависимости от того, какой Swift вы используете:
func textField(_ textField: UITextField,
shouldChangeCharactersIn range: NSRange,
replacementString string: String) -> Bool {
let nsString = textField.text as NSString?
let newString = nsString?.replacingCharacters(in: range, with: string)
}
func textField(textField: UITextField,
shouldChangeCharactersInRange range: NSRange,
replacementString string: String) -> Bool {
let nsString = textField.text as NSString?
let newString = nsString?.stringByReplacingCharactersInRange(range, withString: string)
}
В Swift 2.0, предполагающем func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
:
var oldString = textfield.text!
let newRange = oldString.startIndex.advancedBy(range.location)..<oldString.startIndex.advancedBy(range.location + range.length)
let newString = oldString.stringByReplacingCharactersInRange(newRange, withString: string)
Этот ответ от Martin R кажется правильным, потому что он учитывает Unicode.
Однако во время сообщения (Swift 1) его код не компилируется в Swift 2.0 (Xcode 7), поскольку они удалили функцию advance()
. Обновленная версия приведена ниже:
extension String {
func rangeFromNSRange(nsRange : NSRange) -> Range<String.Index>? {
let from16 = utf16.startIndex.advancedBy(nsRange.location, limit: utf16.endIndex)
let to16 = from16.advancedBy(nsRange.length, limit: utf16.endIndex)
if let from = String.Index(from16, within: self),
let to = String.Index(to16, within: self) {
return from ..< to
}
return nil
}
}
extension String {
func rangeFromNSRange(nsRange : NSRange) -> Range<String.Index>? {
if let from16 = utf16.index(utf16.startIndex, offsetBy: nsRange.location, limitedBy: utf16.endIndex),
let to16 = utf16.index(from16, offsetBy: nsRange.length, limitedBy: utf16.endIndex),
let from = String.Index(from16, within: self),
let to = String.Index(to16, within: self) {
return from ..< to
}
return nil
}
}
extension String {
func rangeFromNSRange(nsRange : NSRange) -> Range<String.Index>? {
return Range(nsRange, in: self)
}
}
Я нашел, что самое чистое решение только для swift2 - создать категорию на NSRange:
extension NSRange {
func stringRangeForText(string: String) -> Range<String.Index> {
let start = string.startIndex.advancedBy(self.location)
let end = start.advancedBy(self.length)
return Range<String.Index>(start: start, end: end)
}
}
И затем вызвать его для функции делегирования текстового поля:
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
let range = range.stringRangeForText(textField.text)
let output = textField.text.stringByReplacingCharactersInRange(range, withString: string)
// your code goes here....
return true
}
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
let strString = ((textField.text)! as NSString).stringByReplacingCharactersInRange(range, withString: string)
}
Это похоже на ответ Эмили, однако, поскольку вы специально спросили, как преобразовать NSRange
в Range<String.Index>
, вы сделали бы что-то вроде этого:
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
let start = advance(textField.text.startIndex, range.location)
let end = advance(start, range.length)
let swiftRange = Range<String.Index>(start: start, end: end)
...
}
Начиная с Swift 4 (Xcode 9) стандартная библиотека Swift предоставляет методы для преобразования между диапазонами строк Swift (Range<String.Index>
) и NSString
(NSRange
). Пример:
let str = "a
В принятом ответе я нахожу, что варианты громоздки. Это работает с Swift 3 и, похоже, не имеет проблем с emojis.
func textField(_ textField: UITextField,
shouldChangeCharactersIn range: NSRange,
replacementString string: String) -> Bool {
guard let value = textField.text else {return false} // there may be a reason for returning true in this case but I can't think of it
// now value is a String, not an optional String
let valueAfterChange = (value as NSString).replacingCharacters(in: range, with: string)
// valueAfterChange is a String, not an optional String
// now do whatever processing is required
return true // or false, as required
}
Официальная документация Swift 3.0 beta предоставила стандартное решение для этой ситуации под заголовком String.UTF16View в разделе Элементы UTF16View Элементы соответствия NSString Название персонажей
Рифф на большой ответ от @Emilie, а не на альтернативный / конкурирующий ответ. (Xcode6-Beta5)
var original = "