234

I'm wondering about changing the color of the cursor / caret in a UITextField (And UITextView if its the same answer) in iOS. I've seen answers for OSX development, but nothing for iOS.

Is this even possible?

TheNeil
  • 1,985
  • 2
  • 17
  • 36
RileyE
  • 10,308
  • 12
  • 60
  • 103
  • 1
    Detailed answer for `UITextField`, including how to do this in Interface Builder, at http://stackoverflow.com/a/18759577/1709587 – Mark Amery May 13 '14 at 19:19
  • 1
    Simple and complete answer at http://stackoverflow.com/a/18945907/1292230 ;) – RileyE May 13 '14 at 21:20

16 Answers16

538

If you're targeting iOS 7+, this has been made much easier. Simply change the tintColor of the field with a cursor using the appearance proxy and it will apply throughout the app:

Swift 3.0:

UITextField.appearance().tintColor = .black 

Objective-C:

[[UITextField appearance] setTintColor:[UIColor blackColor]];

Same answer applies for an individual UITextField:

Swift 3.0:

myTextField.tintColor = .black 

Objective-C

[myTextField setTintColor:[UIColor blackColor]];
shim
  • 7,170
  • 10
  • 62
  • 95
DiscDev
  • 36,864
  • 20
  • 113
  • 130
  • 13
    I found this caused my UIBarButton item tint colors to become fixed to their default values even if I set the tint color to something entirely different. I solved the problem by setting the tint color of the UITextFields individually when they are created. – willtalmadge Jan 09 '14 at 05:48
  • This works, but only if you do it in didFinishLaunching? Or can you do it based on user interaction, e.g. press a button? – Steffen Andersen Apr 09 '14 at 07:08
  • @SteffenAndersen it should behave according to the UIAppearance proxy API documentation. – DiscDev Apr 29 '14 at 15:36
  • [[UITextView appearance] setTintColor:teal]; for some reason this changes the color of my navbarbuttons, how did you set indidividually? – John Apr 07 '15 at 00:28
  • @DiscDev: This works but as soon as UITextView loses focus and then regains focus, the caret color changes to grey. Any idea why? – Kashif Apr 10 '16 at 17:42
  • @Kashif I haven't seen this happen. Perhaps you have other code triggering this to happen somehow. – DiscDev Apr 12 '16 at 20:23
  • 3
    On Swift 3.0 use this: UITextField.appearance().tintColor = UIColor.black – Lucas Torquato Oct 06 '16 at 01:16
  • `myTextField.tintColor = .black ` has no effect for me. – ScottyBlades Mar 15 '19 at 21:13
44

With iOS7 you can simply change tintColor of the textField

Mark Amery
  • 110,735
  • 57
  • 354
  • 402
Cap
  • 1,694
  • 13
  • 14
22

Swift 3:

  UITextField.appearance().tintColor = UIColor.black
  UITextView.appearance().tintColor = UIColor.black
Peter Kreinz
  • 6,544
  • 1
  • 51
  • 45
14
yourTextField.tintColor = [UIColor whiteColor];

It works if you set it in code, 'cos somehow color trigger doesn't do it in the Interface Builder (Xcode 6.1.1). It suited well without a need to change any appearance proxy.

David
  • 1,031
  • 11
  • 17
  • 2
    For some unknown reason it does not work for me with whiteColor but does work with every other color (testing on iOS 8). I had to set color that is almost white but not white to make it work. – Leszek Szary Feb 15 '17 at 18:15
  • @LeszekSzary Hey! You saved my day! I was trying nearly 4 hours and your words were the clue! Apple should fix this crazy bug which indeed drives the developer crazy. – Karthick Ramesh Jul 24 '19 at 08:05
13

Note: This answer is out of date and should be used for pre-iOS 7 development only. See other answers for a 1 line solution using the appearance proxy in iOS 7.

I arrived at this question after I faced the same problem in a project I was working on.

I managed to create a solution that will be accepted by the AppStore review team as it does not use any existing Private APIs.

I have created a control called DGTextField that extends UITextField.

RileyE
  • 10,308
  • 12
  • 60
  • 103
Dov
  • 161
  • 1
  • 5
  • This is great. Honestly, because of this, I'll definitely be keeping a closer eye on "Conforms to" in the docs. However, I'm glad only one person had to spend the time reading and tinkering on this. Hopefully other people will be able to see and use this! – RileyE Jan 21 '13 at 21:11
  • However, I might recommend animation options, removing the @propery and just creating setters and getters as well as a setter and getter for the custom caret width. You may not be interested, but I always love the little tweaks! – RileyE Jan 21 '13 at 21:14
  • @RileyE I am glad you were able to benefit from my solution. Feel free to fork the repo and add any tweaks you would like to share. – Dov Jan 23 '13 at 07:34
  • 3
    It's much easier in iOS 7 - see my answer below: http://stackoverflow.com/a/18945907/1103584 – DiscDev Sep 24 '13 at 02:54
13

Setting tintColor for UITextField and UITextView works differently. While for UITextField you don't need to call additional code after updating tintColor to change cursor color, but for UITextView you need.

So after setting tintColor for UITextView (it doesn't matter in IB or in code) you need to call textView.tintColorDidChange() in order to apply it (actually it will pass text view's config down to its subviews hierarchy).

ilya
  • 1,384
  • 13
  • 21
4

This worked for me in swift:

UITextField.tintColor = UIColor.blackColor()

You can also set this in storyboard: https://stackoverflow.com/a/18759577/3075340

Community
  • 1
  • 1
Micro
  • 9,083
  • 8
  • 68
  • 104
  • This doesn't work. I got the error: `Instance member 'tintcolor' cannot be used on type 'UITextField'` – pableiros Nov 02 '16 at 16:55
  • @pableiros The above was with Swift 2. Maybe you are using Swift 3 now? – Micro Nov 02 '16 at 17:43
  • I tried on Swift 3 and Swift 2.3, I'm not sure if on Swift 2.2 and lower it works – pableiros Nov 02 '16 at 17:47
  • pableiros' issue is that the answer should have `someTextFieldInstance` instead of `UITextField`, because `tintColor` is an instance member – Marmoy Jul 21 '20 at 11:48
3

A more general approach would be to set the UIView's appearance's tintColor.

UIColor *myColor = [UIColor purpleColor];
[[UIView appearance] setTintColor:myColor];

Makes sense if you're using many default UI elements.

arnekolja
  • 1,629
  • 5
  • 21
  • 29
  • 2
    Hmmm...this has many other side-effects...the question is only asking about changing the caret color, and your answer is going to tint every single UIView in the app...this is probably not the approach most people want to take. – DiscDev Oct 04 '13 at 15:26
  • +1 on that, too many side effects, if the goal is just to change the caret color. Setting UIView tintColor IS useful when you're styling a container (but then I wouldn't use `[UIView appearance]` – colinta Jan 18 '14 at 01:02
2

Try, Its working for me.

[[self.textField valueForKey:@"textInputTraits"] setValue:[UIColor redColor] strong textforKey:@"insertionPointColor"];
Dhara
  • 4,085
  • 2
  • 33
  • 68
Durgesh
  • 113
  • 1
  • 1
  • 6
    That's using a private method, but thank you for the suggestion. This can easily get an application rejected. – RileyE Jun 07 '13 at 15:51
1

It is only possible by accessing a private property and therefore may cause an Apple AppStore app rejection.

take a look at this Stackoverflow question

Community
  • 1
  • 1
Max Ballo
  • 881
  • 10
  • 21
1

I think If you want some custom colors you can go to Assets.xcassets folder, right click and select New Color Set, once you created you color you set, give it a name to reuse it.

And you can use it just like this :

import UIKit 

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        UITextField.appearance().tintColor = UIColor(named: "YOUR-COLOR-NAME")  #here
    }
}

Tested on macOS 10.15 / iOS 13 / Swift 5

0

Durgesh's approach does work.

I also used such KVC solutions many times. Despite it seems to be undocumented, but it works. Frankly, you don't use any private methods here - only Key-Value Coding which is legal.

P.S. Yesterday my new app appeared at AppStore without any problems with this approach. And it is not the first case when I use KVC in changing some read-only properties (like navigatonBar) or private ivars.

malex
  • 9,374
  • 3
  • 53
  • 71
  • 1
    It's not using a private method, but rather that the keys are undocumented, which means they aren't to be used for applications on the App Store. Your application may get rejected subjectively. You must have had a kind reviewer, as many have been rejected for using that method. – RileyE Sep 16 '13 at 18:48
  • Then I have about 10 kind reviewers :) and my numerous colleagues too. – malex Sep 16 '13 at 19:02
  • Could you please give a link to allowed list of documented keys. – malex Sep 16 '13 at 19:02
  • Could you please provide a list of documented keys? That's your list. I'm not trying to be rude; I'm just stating my knowledge based on my own and others' experiences, hopefully for your own and others' benefit. – RileyE Sep 16 '13 at 19:05
  • 1
    Just to clarify, the "Key-Value Coding" in this case is assigning a value to a property using the convenience method. The reason that we're using that, versus a setter, is because the property is inaccessible/hidden/private. – RileyE Sep 16 '13 at 19:09
  • 1
    Here I mean (maybe I don't know something important) only that documentation on KVC doesn't imply any restrictions literally. So I successfully use all of these. And hopefully can others. – malex Sep 16 '13 at 19:14
  • 1
    Appreciated. However, Apple, in their 'Terms of Use Agreement' states that we are allowed to use and openly discuss anything included in their documentation and prohibits the use of undocumented methods (Accessing the 'textInputTraits' setter method through KVC would be included, as the property is undocumented). Essentially, if you can't find the method in the documentation, it's prohibited. Prohibited doesn't guarantee rejection, though. I've had some applications get rejected for reasons included in some of my apps that make it to the store. It's hit and miss with undocumented methods. – RileyE Sep 16 '13 at 19:21
0

For Interface Builder version with Swift

@IBOutlet weak var tvValue: UITextView! {
        didSet {
            tvValue.tintColor = .black
        }
    }
Mike Glukhov
  • 1,493
  • 16
  • 15
0

If the UITextField is from UISearchBar then first get the textField from searchBar and then apply tintColor property:

let textFieldInsideSearchBar = searchBar.value(forKey: "searchField") as? UITextField
textFieldInsideSearchBar?.tintColor = UIColor.lightGray
0

Swift 4

In viewDidLoad() just call below code:

CODE SAMPLE

//txtVComplaint is a textView

txtVComplaint.tintColor = UIColor.white

txtVComplaint.tintColorDidChange()
dpapadopoulos
  • 1,748
  • 4
  • 20
  • 29
Shamshad
  • 111
  • 1
  • 6
0

For people searching the equivalent in SwiftUI for Textfield this is accentColor:

TextField("Label", text: $self.textToBind).accentColor(Color.red)
Beninho85
  • 2,977
  • 23
  • 21