11

I'm trying to set the cursor color of a UITextView based on a user's preferences. They select what color they want with a button.

By default, the textview's cursor color is white. When the user presses the button, it might change to green:

[_textView setTintColor:[UIColor greenColor]];
[_textView setTextColor:[UIColor greenColor]];

I am sure that this method call is working because the textview's text changes color, just not the cursor...

vikingosegundo
  • 52,040
  • 14
  • 137
  • 178
Apollo
  • 8,874
  • 32
  • 104
  • 192
  • My experience shows that calling `setTintColor:` changes the color of the text view's caret. – rmaddy May 18 '14 at 18:48
  • @rmaddy I think this might be a bug in iOS 7.1 regarding global tints such as [UIView appearance] because there's nothing I'm doing that's out of the ordinary. This should work... – Apollo May 18 '14 at 18:50
  • From my experience (in iOS7.1 as well), indeed tintColor sets the cursor color. – Léo Natan May 18 '14 at 18:52
  • I just checked it: if I am not just in change mode, press the button, they text and the caret will change color. If I have the text in change mode, the caret's color will stay blue. – vikingosegundo May 18 '14 at 18:53
  • @vikingosegundo not sure what you mean by change mode – Apollo May 18 '14 at 18:54

3 Answers3

22

I was able to recreate your behavior: If I change the tint and text color while the text view isn't selected (aka: not first responder), everything will work as expected.

But if I first select it, by tapping it and than change the color by button press, they caret's (tint) color won't change.

Here is a workaround:

- (IBAction)changeColor:(id)sender 
{
    [_textView setTextColor:[UIColor greenColor]];
    [_textView setTintColor:[UIColor greenColor]];

    if([_textView isFirstResponder]){
        [_textView resignFirstResponder];
        [_textView becomeFirstResponder];
    }
}
vikingosegundo
  • 52,040
  • 14
  • 137
  • 178
  • 2
    I have views that are affected by keyboard appearance transitions and the resign/become calls above would cause some undesirable behavior. I was able to eliminate this by wrapping the calls like so: `[UIView setAnimationsEnabled:NO]; [_textView resignFirstResponder]; [_textView becomeFirstResponder]; [UIView setAnimationsEnabled:YES];` – Travis Mar 16 '15 at 16:45
  • 1
    You don't need to make this trick with changing responder status you just need to call `textView.tintColorDidChange()`. See details here https://stackoverflow.com/a/53332199/2742194 – Ilia Nov 16 '18 at 05:57
6

I'm using small hack in UITextViewDelegate method:

func textViewDidBeginEditing(_ textView: UITextView) {
    let color = textView.tintColor
    textView.tintColor = .clear
    textView.tintColor = color
}

UPD

more technological way:

1) implement method in extension:

extension UITextView {
    func resetTintColor(){
        let color = tintColor
        tintColor = .clear
        tintColor = color
    }
}

2) in an UITextViewDelegate implementation:

func textViewDidBeginEditing(_ textView: UITextView) {
    textView.resetTintColor()
}
dr OX
  • 4,671
  • 1
  • 17
  • 9
2

You can use

[_textView reloadInputViews];

And in Swift

textView. reloadInputViews()

Then you won't need to handle keyboard incoming and going.

Nikhil Manapure
  • 3,748
  • 2
  • 30
  • 55
  • It had worked for me very fine, `resignFirstResponder` and `becomeFirstResponder` was making keyboard view go and come back. May I know how are you implementing the solution and for what? – Nikhil Manapure Jul 25 '17 at 08:21
  • Basically, I set the text view's tintColor, then resignFirstResponder and becomeFirstResponder, then I call reloadInputViews after that. The animation is not happening, but the cursor is not changing its tint color. – Boon Jul 25 '17 at 11:22
  • I guess you have implemented it rightly, I will check the solution again for you and get back to you. But it had worked for me for the same scenario. – Nikhil Manapure Jul 25 '17 at 11:24