Question

I have a UITextField which inserts some text and selects all of it immediately, so the user could click off and accept the pre-filled data or type anything else and overwrite everything. I call this to do that:

[myTextField setSelectedTextRange:[myTextField textRangeFromPosition:myTextField.beginningOfDocument toPosition:myTextField.endOfDocument]];

I'm wondering if there is anyway to hide the the handles (circular handle, one top-left, one bottom-right) that come with selecting text, as it does not go with our UI design, and there is no purpose for them.

Was it helpful?

Solution

I don't believe there is a native way to do this in a UITextField/UITextView. You would probably have to build something from scratch with CoreText.

That said, for usability, it's probably a good idea to keep them there?

Alternatively, you could "fake" it by adding a NSBackgroundColorAttributeName to the AttributedText and programmatically clearing it out when the user presses the backspace key?

OTHER TIPS

Here's a simple Swift 3 solution that works nicely for me.

class ViewController: UIViewController, UITextFieldDelegate {
    @IBOutlet weak var textField: UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()

        textField.delegate = self
        textField.addTarget(self, action: #selector(textFieldDidChange(_:)), for: .editingChanged)
    }

    // When editing starts, select all and then make handles (and cursor) invisible
    public func textFieldDidBeginEditing(_ textField: UITextField) {
        DispatchQueue.main.async {
            textField.selectAll(nil)
            textField.tintColor = .clear
        }
    }

    // If user types, restore cursor visibility  
    func textFieldDidChange(_ textField: UITextField) {
        DispatchQueue.main.async {
            textField.tintColor = .blue
        }
    }
}

Note 1: I didn't originally dispatch the changes to the main queue, but I observed that the changes sometimes just didn't get rendered properly. After adding the dispatch to the main queue, I never saw this behavior again.

Note 2: I really wanted to use the UITextFieldDelegate's shouldChangeCharactersIn handler to make the cursor visible again, but for some reason that method was never called when the user typed into the textField. So I used the .editingChanged event instead, this seems to work just fine but isn't quite as clean IMHO. If anyone knows why the following wasn't working as part of the UITextFieldDelegate, please comment. Thanks!

public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        textField.tintColor = .blue
        return true
    }

If it's just for appearance you can subclass the UITextField and override:

- (void)setSelectedTextRange:(UITextRange *)selectedTextRange {
//
[super setSelectedTextRange:selectedTextRange];

self.tintColor = selectedTextRange.empty ? <default cursor color> : [UIColor clearColor];}

The handles still be there, just not visible.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top