Hide the cursor of a UITextField

IosCocoa TouchUitextfieldUipickerview

Ios Problem Overview


I am using a UITextField with a UIPickerView for its inputView, so that when the user taps the text field, a picker is summoned for them to select an option from.

Nearly everything works, but I have one problem: the cursor still flashes in the text field when it is active, which is ugly and inappropriate, since the user is not expected to type into the field and is not presented with a keyboard. I know I could hackily solve this by setting editing to NO on the text field and tracking touches on it, or by replacing it with a custom-styled button, and summoning the picker via code. However, I want to use the UITextFieldDelegate methods for all the event handling on the text field and hacks such as replacing the text field with a button do not permit this approach.

How can I simply hide the cursor on the UITextField instead?

Ios Solutions


Solution 1 - Ios

Simply subclass UITextField and override caretRectForPosition

- (CGRect)caretRectForPosition:(UITextPosition *)position
{
    return CGRectZero;
}

Solution 2 - Ios

As of iOS 7 you can now just set the tintColor = [UIColor clearColor] on the textField and the caret will disappear.

Solution 3 - Ios

You can just clear the textfield's tintColor

self.textField.tintColor = [UIColor clearColor];

Swift 3.0

self.textField.tintColor = .clear

enter image description here

Solution 4 - Ios

You might also want to stop the user from selecting, copying or pasting any text so that the only text input comes from the picker view.

- (CGRect) caretRectForPosition:(UITextPosition*) position
{
    return CGRectZero;
}

- (NSArray *)selectionRectsForRange:(UITextRange *)range
{
    return nil;
}

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
    if (action == @selector(copy:) || action == @selector(selectAll:) || action == @selector(paste:))
    {
        returnNO;
    }

    return [super canPerformAction:action withSender:sender];
}

http://b2cloud.com.au/tutorial/disabling-the-caret-and-text-entry-in-uitextfields/

Solution 5 - Ios

Check out the property selectedTextRange of the protocol UITextInput, to which the class UITextField conforms. Few! That's a lesson in object-oriented programing right there.

Hide Caret

To hide the caret, nil out the text field's selected text range.

textField.selectedTextRange = nil; // hides caret

Unhide Caret

Here are two ways to unhide the caret.

  1. Set the text field's selected text range to the end of the document.

     UITextPosition *end = textField.endOfDocument;
     textField.selectedTextRange = [textField textRangeFromPosition:end
                                                         toPosition:end];
    
  2. To keep the caret in the same spot, first, store the text field's selected text range to an instance variable.

     _textFieldSelectedTextRange = textField.selectedTextRange;
     textField.selectedTextRange = nil; // hides caret
    

    Then, when you want to unhide the caret, simply set the text field's selected text range back to what it was originally:

     textField.selectedTextRange     = _textFieldSelectedTextRange;
     _textFieldLastSelectedTextRange = nil;
    

Solution 6 - Ios

Answer provided by the OP, copied from the question body to help clean up the ever growing tail of unanswered questions.

I found another solution: subclass UIButton and override these methods

- (UIView *)inputView {
    return inputView_;
}

- (void)setInputView:(UIView *)anInputView {
    if (inputView_ != anInputView) {
        [inputView_ release];
        inputView_ = [anInputView retain];
    }
}

- (BOOL)canBecomeFirstResponder {
    return YES;
}

Now the button, as a UIResponder, have a similar behavior than UITextField and an implementation pretty straightforward.

Solution 7 - Ios

Swift 5 version of Net's post

  override func caretRect(for position: UITextPosition) -> CGRect {
    return .zero
  }
  
  override func selectionRects(for range: UITextRange) -> [UITextSelectionRect] {
    return []
  }
  
  override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
    return false
  }

Solution 8 - Ios

set the tintColor to Clear Color

textfield.tintColor = [UIColor clearColor];

and you can also set from the interface builder

Solution 9 - Ios

If you want to hide cursor, you can easily use this! It worked for me..

[[textField valueForKey:@"textInputTraits"] setValue:[UIColor clearColor] forKey:@"insertionPointColor"]

Solution 10 - Ios

Answer provided by the OP, copied from the question body to help clean up the ever growing tail of unanswered questions.

I think I have the correct solution but If it can be improved will be welcome :) Well, I made a subclass of UITextField and overriden the method that returns the CGRect for the bounds

-(CGRect)textRectForBounds:(CGRect)bounds {
    return CGRectZero;
}

The problem? The text doesn't show because the rect is zero. But I added an UILabel as a subview of the control and overridden the setText method so, as we enter a text as usual, the text field text is nil and is the label which shows the text

- (void)setText:(NSString *)aText {
    [super setText:nil];

    if (aText == nil) {
        textLabel_.text = nil;
    }

    if (![aText isEqualToString:@""]) {
        textLabel_.text = aText;
    }
}

With this the thing works as expected. Have you know any way to improve it?

Solution 11 - Ios

To both disable cursor and menu I use subclass with these 2 methods:

- (CGRect)caretRectForPosition:(UITextPosition *)position {
    return CGRectZero;
}

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
    [UIMenuController sharedMenuController].menuVisible = NO;
    self.selectedTextRange = nil;
    
    return NO;
}

Solution 12 - Ios

I simply subclass UITextField, and override layoutSubviews as follows:

- (void)layoutSubviews
{
	[super layoutSubviews];
	for (UIView *v in self.subviews)
	{
		if ([[[v class] description] rangeOfString:@"UITextSelectionView"].location != NSNotFound)
		{
			v.hidden = YES;
		}
	}
}

It's a dirty hack, and may fail in the future (at which point the cursor will be visible again - your app won't crash), but it works.

Solution 13 - Ios

If you like cleaner = less code, use the interface builder:

Clear color

(Attributes inspector, view section.)

Solution 14 - Ios

You can add a BOOL cursorless property to UITextField in a category via associated objects.

@interface UITextField (Cursorless)

@property (nonatomic, assign) BOOL cursorless;

@end

Then use method swizzling to swizzle caretRectForPosition: with a method that toggles between CGRectZero and its default value using cursorless.

This leads to a simple interface via a drop-in category. This is demonstrated in the following files.

Simply drop them in and get the benefit of this simple interface

UITextField category: https://github.com/rexmas/RexDK/blob/master/RexDK/UI/UITextField%2BRXCursorless.h https://github.com/rexmas/RexDK/blob/master/RexDK/UI/UITextField%2BRXCursorless.m

Method Swizzling: https://github.com/rexmas/RexDK/blob/master/RexDK/Foundation/NSObject%2BRXRuntimeAdditions.h https://github.com/rexmas/RexDK/blob/master/RexDK/Foundation/NSObject%2BRXRuntimeAdditions.m

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionemenegroView Question on Stackoverflow
Solution 1 - IosJoseph ChiuView Answer on Stackoverflow
Solution 2 - IosjamoneView Answer on Stackoverflow
Solution 3 - IosoldmanView Answer on Stackoverflow
Solution 4 - IosNatView Answer on Stackoverflow
Solution 5 - Iosma11hew28View Answer on Stackoverflow
Solution 6 - IosRobert HöglundView Answer on Stackoverflow
Solution 7 - IosRom.View Answer on Stackoverflow
Solution 8 - IosAhmad Al-AttalView Answer on Stackoverflow
Solution 9 - IosGöktuğ AralView Answer on Stackoverflow
Solution 10 - IosRobert HöglundView Answer on Stackoverflow
Solution 11 - IosNatView Answer on Stackoverflow
Solution 12 - IosMark BeatonView Answer on Stackoverflow
Solution 13 - IosDisplay NameView Answer on Stackoverflow
Solution 14 - IosAwesome-oView Answer on Stackoverflow