Change UITextField and UITextView Cursor / Caret Color
Asked Answered
A

16

250

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?

Anthropogeography answered 23/7, 2012 at 3:9 Comment(3)
Detailed answer for UITextField, including how to do this in Interface Builder, at https://mcmap.net/q/118728/-change-color-of-cursor-in-uitextfieldKary
Simple and complete answer at https://mcmap.net/q/115815/-change-uitextfield-and-uitextview-cursor-caret-color ;)Anthropogeography
2023 its now trivial, set accent color. You can set it in storyboard no problem.Upshaw
S
573

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]];
Sethrida answered 22/9, 2013 at 16:10 Comment(8)
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.Lipetsk
This works, but only if you do it in didFinishLaunching? Or can you do it based on user interaction, e.g. press a button?Blade
@SteffenAndersen it should behave according to the UIAppearance proxy API documentation.Sethrida
[[UITextView appearance] setTintColor:teal]; for some reason this changes the color of my navbarbuttons, how did you set indidividually?Incoherent
@DiscDev: This works but as soon as UITextView loses focus and then regains focus, the caret color changes to grey. Any idea why?Rhebarhee
@Rhebarhee I haven't seen this happen. Perhaps you have other code triggering this to happen somehow.Sethrida
On Swift 3.0 use this: UITextField.appearance().tintColor = UIColor.blackMcgough
myTextField.tintColor = .black has no effect for me.Activist
C
45

With iOS7 you can simply change tintColor of the textField

Cristoforo answered 12/9, 2013 at 8:51 Comment(0)
H
23

Swift 3:

  UITextField.appearance().tintColor = UIColor.black
  UITextView.appearance().tintColor = UIColor.black
Heed answered 12/3, 2015 at 20:15 Comment(1)
On Swift 3.0 use this: UITextField.appearance().tintColor = UIColor.blackMcgough
C
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.

Cowherb answered 30/4, 2015 at 13:25 Comment(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.Staves
@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.Prison
I
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.

Implead answered 21/1, 2013 at 12:37 Comment(4)
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!Anthropogeography
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!Anthropogeography
@Anthropogeography 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.Implead
It's much easier in iOS 7 - see my answer below: https://mcmap.net/q/115815/-change-uitextfield-and-uitextview-cursor-caret-colorSethrida
I
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).

Icsh answered 16/11, 2018 at 5:55 Comment(0)
B
4

This worked for me in swift:

UITextField.tintColor = UIColor.blackColor()

You can also set this in storyboard: https://mcmap.net/q/118728/-change-color-of-cursor-in-uitextfield

Bedazzle answered 8/6, 2016 at 2:14 Comment(4)
This doesn't work. I got the error: Instance member 'tintcolor' cannot be used on type 'UITextField'Morris
@Morris The above was with Swift 2. Maybe you are using Swift 3 now?Bedazzle
I tried on Swift 3 and Swift 2.3, I'm not sure if on Swift 2.2 and lower it worksMorris
pableiros' issue is that the answer should have someTextFieldInstance instead of UITextField, because tintColor is an instance memberThierry
S
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.

Self answered 4/10, 2013 at 14:38 Comment(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.Sethrida
+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]Guillema
P
2

Try, Its working for me.

[[self.textField valueForKey:@"textInputTraits"] setValue:[UIColor redColor] strong textforKey:@"insertionPointColor"];
Passifloraceous answered 7/6, 2013 at 10:24 Comment(1)
That's using a private method, but thank you for the suggestion. This can easily get an application rejected.Anthropogeography
H
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

Hammertoe answered 23/9, 2012 at 13:1 Comment(0)
D
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

Detain answered 2/8, 2019 at 12:23 Comment(0)
P
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.

Patio answered 16/9, 2013 at 18:41 Comment(7)
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.Anthropogeography
Then I have about 10 kind reviewers :) and my numerous colleagues too.Patio
Could you please give a link to allowed list of documented keys.Patio
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.Anthropogeography
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.Anthropogeography
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.Patio
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.Anthropogeography
D
0

For Interface Builder version with Swift

@IBOutlet weak var tvValue: UITextView! {
        didSet {
            tvValue.tintColor = .black
        }
    }
Diogenes answered 3/3, 2018 at 6:48 Comment(0)
P
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
Pleurodynia answered 22/8, 2018 at 5:45 Comment(0)
E
0

Swift 4

In viewDidLoad() just call below code:

CODE SAMPLE

//txtVComplaint is a textView

txtVComplaint.tintColor = UIColor.white

txtVComplaint.tintColorDidChange()
Encroachment answered 21/2, 2019 at 8:47 Comment(0)
U
0

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

TextField("Label", text: $self.textToBind).accentColor(Color.red)
Unfounded answered 28/5, 2020 at 1:43 Comment(1)
He asked about UITextField (UIKit), not SwiftUI.Berchtesgaden

© 2022 - 2024 — McMap. All rights reserved.