Replacing character after each type in UITextField?
Asked Answered
P

2

2

I have a UITextField in which the user is expected to type a sentence which we tell the user to type. So the sentence to type is already known to us. Midway of the sentence, the user has to secretly pass a message. The way to do this is by typing a few letters of the already known sentence and then type '&' followed by WhichEverMessageUserWantsToPass and '&' to end.

The catch is the moment the user presses '&', whatever he types after that should not be displayed, instead each letter he types after that should be replaced by the letter in the already known sentence.

For example:

String - Which city did I live in 2 years ago?

User types - Which city di&Deteroit&n 2 yea

UITextField should show - Which city did I live in 2 yea

The part between the two '&' is essentially the answer by itself, so I do not want it to be shown in the text field.

My approach currently is:

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    
    var addString = String(self.character[self.textLength])
    
    var start = textField.text.endIndex // Start at the string's end index as I only want the most recent character to be replaced
    var end = textField.text.endIndex // Take the string's end index as I only want one character to be changes per type
    var nextRange: Range<String.Index> = Range<String.Index>(start: start,end: end)
    
    textField.text.stringByReplacingCharactersInRange(nextRange, withString: addString)
    
    
    return true
}

However, this does not seem to replace any letter currently. Kindly help if any one knows the implementation. Thank you

Parbuckle answered 19/7, 2015 at 14:15 Comment(4)
From your example data it is VERY unclear what you are trying to do, very unclear - I have no idea how the input and the output are related in any way. Your replace some strings with some other, omit something, insert something and tadaaaa, something should come out.Scorpius
HI @luk2303, I hope this is better. Please feel free to tell me if it is still unclear. I apologise or the ambiguity.Parbuckle
It actually does clarify it, let me code a bit ;)Scorpius
Thank you. Looking forward to your answer. :).Parbuckle
S
3

There you go - try it out!

let initialString = "my question to be answered"
var inputString = NSString()

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    inputString = inputString.stringByReplacingCharactersInRange(range, withString: string)

    textField.text = inputString as String
    var range = Range<String.Index>(start: (textField.text?.startIndex)!,end: (textField.text?.endIndex)!)

    while true {
        if let firstIndex = textField.text!.rangeOfString("&", options: [], range: range, locale: nil) {
            range = Range<String.Index>(start: firstIndex.startIndex.successor(), end: (textField.text?.endIndex)!)
            var endIndex : String.Index?
            if let index = textField.text!.rangeOfString("&", options: [], range: range, locale: nil) {
                endIndex = index.endIndex
                range = Range<String.Index>(start: index.startIndex.successor(), end: (textField.text?.endIndex)!)
            } else {
                endIndex = textField.text?.endIndex
            }

            let relevantRange = Range(start: firstIndex.startIndex,end: endIndex!)
            let repl = initialString.substringWithRange(relevantRange)

            print("would replace the \(relevantRange) with \(repl)")

            textField.text!.replaceRange(relevantRange, with: repl)
        } else {
            break
        }
    }
    return false
}

I think that is pretty much exactly what you wanted plus very clean, you can remove or add & mid-sentence and everything works as desired.

Example output for the input of "&X&ghj&X&ui&X&.." would be

would replace the 0..<3 with my
would replace the 6..<9 with sti
would replace the 11..<14 with to

And the text displayed in the text-field "my ghjstiui to.." (the bold text is the one being read from the actual question and matches the &X& sections of the input.)

Note: for swift 1 replace the [] with nil.

Scorpius answered 19/7, 2015 at 15:36 Comment(9)
I really admire your effort. Just that the moment I paste this code, an error in the first line of while true loop occurs, i.e. if let firstIndex = ... "Error: Cannot invoke rangOfString with argument list of type (String, options:NSArray,range:Range<String.Index>, locale: nil)Parbuckle
@Parbuckle Hmmm, what version of swift are you using? For me it is apparently working, I can test it on the simulator.Scorpius
@Parbuckle yeiks :/ that is swift 1.1??? I am using 1.2. Try to replace the [] with nil and see if that fixes the error.Scorpius
@Parbuckle try typing xcrun swift --version in the terminal and tell me what version comes up - I am confused which xcode version comes with which swiftScorpius
Yes replacing [ ] with nil removed the error. Now trying out the code. I'm really hoping to become near as skilled as you are man! Will check out the code and update you. Thank you.Parbuckle
Works like a charm. Thank you!!Parbuckle
@Parbuckle you are welcome. Funny thing is, I did never learn to program swift, just happened... :D I have yet to use it in my first own project...Scorpius
Let us continue this discussion in chat.Parbuckle
Something worth pointing out is that returning false in this method prevents UIControlEvents to fire. So if you depend on anything like .EditingChanged you'll need to have a way to fire those off yourself.Timeserver
T
0

During TextField Editing if you want replace characters

@IBAction func editingChanged(_ sender: UITextField) {
    sender.text = sender.text?.replacingOccurrences(of: ".", with: "")
}
Torrefy answered 3/2, 2023 at 20:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.