Using stringByReplacingCharactersInRange in Swift
Here's how to calculate the resulting string in various Swift versions.
Note that all methods use -[NSString stringByReplacingOccurrencesOfString:withString:]
in exactly the same way, just differing in syntax.
This is the preferred way to calculate the resulting string. Converting to a Swift Range
and use that on a Swift String
is error prone. Johan's answer for example is incorrect in a couple of ways when operating on non-ASCII strings.
Swift 3:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let result = (textField.text as NSString?)?.replacingCharacters(in: range, with: string) ?? string
// ... do something with `result`
}
Swift 2.1:
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
let result = (textField.text as NSString?)?.stringByReplacingCharactersInRange(range, withString: string)
// ... do something with `result`
}
Swift 1 (only left here for reference):
let result = textField.text.bridgeToObjectiveC().stringByReplacingCharactersInRange(range, withString:string)
How does stringByReplacingCharactersInRange work in swift?
Use bridgeToObjectiveC()
textField.text.bridgeToObjectiveC().stringByReplacingCharactersInRange(range, withString: string)
it will more clarify
var st = "abc"
str.bridgeToObjectiveC().stringByReplacingCharactersInRange(NSMakeRange(2,1), withString:"r")
Explicit casting can also be done to NSString
and it not needs bridgeToObjectiveC
var st = "abc" as NSString
let abc = st.stringByReplacingCharactersInRange(NSMakeRange(2, 3), withString: "abc")
Swift 3: stringByReplacingCharactersInRange alternatives
In Swift 3 it is.
strToSort = strToSort.replacingCharacters(in: range, with: str)
Note: Here range is type of Swift Range<String.Index>
object not NSRange
.
For more details on Range
check Apple Documentation.
Ex:
let str = "Apple"
let i = 3
let range = str.index(str.startIndex, offsetBy: i-1)..<str.index(str.startIndex, offsetBy: i)
let subStringRange = str.index(str.startIndex, offsetBy: i)..<str.index(str.startIndex, offsetBy: i+1)
print(str.replacingCharacters(in: range, with: str.substring(with: subStringRange)))
Output:
Aplle
How shouldChangeCharactersInRange works in Swift?
Swift 4, Swift 5
This method doesn't use NSString
// MARK: - UITextFieldDelegate
extension MyViewController: UITextFieldDelegate {
func textField(_ textField: UITextField,
shouldChangeCharactersIn range: NSRange,
replacementString string: String) -> Bool {
if let text = textField.text,
let textRange = Range(range, in: text) {
let updatedText = text.replacingCharacters(in: textRange,
with: string)
myvalidator(text: updatedText)
}
return true
}
}
Note. Be careful when you use a secured text field.
stringByReplacingCharactersInRange does not work?
You don't need to cast it to NSString to use stringByReplacingCharactersInRange you just need to change the way you create your string range as follow:
update: Xcode 7.2 • Swift 2.1.1
let binaryColor = "000"
let resultString = binaryColor.stringByReplacingCharactersInRange(
Range(start: binaryColor.startIndex, end: binaryColor.startIndex.advancedBy(1)),
withString: "1")
Or simply
let resultString2 = binaryColor.stringByReplacingCharactersInRange(
binaryColor.startIndex..<binaryColor.startIndex.advancedBy(1),
withString: "1")
Is there a difference between the replaceCharactersInRange on NSString and Swift.String
Yes. There is a difference between the two approaches and the second one is more correct. It also handles multi-code characters correctly:
var str = "Hello , playground"
let range = NSMakeRange(0, 8)
let swiftRange = advance(str.startIndex, range.location)..<advance(str.startIndex, range.length) // I hate this.
var newString = str.stringByReplacingCharactersInRange(swiftRange, withString: "goodbye")
// => goodbye playground
newString = (str as NSString).stringByReplacingCharactersInRange(range, withString: "goodbye")
// => "goodbye, playground"
I'm assuming that this is because the range is calculated better, not because there are different implementation of the replacement methods. swiftRange is 0..<15
Is there a stringByReplacingCharactersInRange method of NSString in Monotouch?
Here's some code to do what you need:
string text = field.Text;
string result;
result = text.Substring (0, range.Location) + replacement + text.Substring (range.Location + range.Length);
Using `textField:shouldChangeCharactersInRange:`, how do I get the text including the current typed character?
-shouldChangeCharactersInRange
gets called before text field actually changes its text, that's why you're getting old text value. To get the text after update use:
[textField2 setText:[textField1.text stringByReplacingCharactersInRange:range withString:string]];
Related Topics
Swiftui Set Position to Center of Different View
Inconsistent Scenekit Framerate
How to Create a String from Utf8 in Swift
Can the Conversion of a String to Data with Utf-8 Encoding Ever Fail
Uicollectionviewlayout Not Working with Uiimage in Swift 5 and Xcode 11
Block Scroll Down in Scrollview - Swiftui
Swift Uialertcontroller with Pickerview Button Action Stay Up
How to Copy a Struct and Modify One of Its Properties at the Same Time
Accessing Mkmapview Elements as Uiviewrepresentable in the Main (Contentview) Swiftui View
Grab Frames from Video Using Swift
How to Reference Swift Playground Itself
Swift 4.2 Setter Getter, All Paths Through This Function Will Call Itself
How to Handle Closure Recursivity
Compare Textfield.Text to Firebase String Swift
Uitextfield Setting Maximum Character Length in Swift