73

Can anyone think of a reason that the blinking cursor would not show up in a UITextView? I have a custom control that is just a subclass of UIView and it has a UITextView in it, but the cursor doesn't appear when it gets focus. The keyboard appears, and the text appears as you type, but there is no cursor, and I can't figure out why.

Any thoughts?...

Suragch
  • 484,302
  • 314
  • 1,365
  • 1,393
SeanT
  • 1,741
  • 1
  • 16
  • 24
  • Is the textview a UITextView or a subclass of UITextView? – Hetal Vora Jan 06 '14 at 21:18
  • The textview is just a standard UITextView. Not a subclass and no custom behavior. – SeanT Jan 06 '14 at 23:09
  • In iOS 7, I've seen the cursor misplaced to the navigation bar in the simulator while the user is typing. The issue disappears on a device. Does your issue occur on a device? – bilobatum Jan 06 '14 at 23:39

11 Answers11

229

You may have changed the tint color in your custom UITextView. If the tint color is the same as the background color (normally white), then it will appear invisible.

lehn0058
  • 19,977
  • 15
  • 69
  • 109
  • That's a good thought, but it's just a standard white UITextView, and the tint color hasn't been changed. – SeanT Jan 06 '14 at 23:12
  • 2
    It also applies to UITextField – Lukasz Aug 14 '14 at 12:11
  • I've got also situation, when in another view some other developer changed tint colour. I don't know why, when I came back to my view to cursor was hidden. I needed to re-set tint in view will appear programatically. – Apan Apr 20 '15 at 12:59
  • Faced that problem with tint color set to default in storyboard. Set another color and default back made cursor appear. Also it is a bit visible due debug view hierarchy session – Dren Oct 09 '15 at 12:29
  • This seemed to be the issue. The tint color was set as "default" which is blue, but I think it was appearing as white, which I've noticed with other controls. I changed it to red in IB and it showed up as red. Then I changed it to blue, not "default" and it finally appeared as blue. – SeanT Jul 26 '16 at 00:36
  • If you want the cursor to be a different color from the tint color (buttons), look at my answer posted here: http://stackoverflow.com/a/42444940/4754881 – Derek Soike Feb 24 '17 at 17:53
9

You might be setting improperly a contentSize and/or frame for the component so it is too small to be visible or the control is out of the screen. Please go in Simulator to Debug->Color Blended Layers to see whether those values are set correctly.

EDIT:

With new Xcodes (probably introduced in Xcode 6) you can debug this kind of issues by clicking "Debug View Hierarchy" (it is one of the icons on the bottom bar)

Julian
  • 9,299
  • 5
  • 48
  • 65
  • 3
    This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post. – Pierre-Luc Pineault Jan 06 '14 at 21:46
  • 7
    author wanted some ideas why he does not see the cursor so my idea is that frames of the whole component or part of it (one of the property) might be badly set. This can solve his problem as it might be his problem in fact. He didn't provide any code fragment so all we can is guessing based on knowledge. If you still feel that I didn't answer please suggest me an edit :) – Julian Jan 06 '14 at 21:57
  • This helped me see the background color issue. – divergio Aug 28 '15 at 03:35
4

The textfield is showing the cursor but you are not able to see the color, just because the tint color of your text field is set to default most probably as in my case it was. Just select you textField in storyboard and Select the link color of your wish. Refer to the image attached.

enter image description here

Kunal Gupta
  • 2,984
  • 31
  • 34
3

I changed the tint color of all of my UITextViews and the cursor started showing on the next build.

1

Simple workaround seems to work by introducing a delay and then calling firstResponder, like so:

-(void)begin{

    [self performSelector:@selector(first) withObject:nil afterDelay:0.01f];
}
-(void)first{

    [tf becomeFirstResponder];
}
Johnny Rockex
  • 4,136
  • 3
  • 35
  • 55
1

In my case, I called becomeFirstResponder in a viewDidLoad method. I moved the call into viewDidAppear and it worked for me.

Vladimir Vlasov
  • 1,860
  • 3
  • 25
  • 38
1

a working crutch for me:

   DispatchQueue.main.async {
           
      self.textView.becomeFirstResponder()
      self.textView.insertText(" ")
      self.textView.deleteBackward()
 }
Dima
  • 61
  • 1
  • 4
0

The solution above did not work in my case. The issue in my case is that the UIView that acts as the cursor has isOpaque set to false when the UITableViewCell's selectionStyle is anything but none. This seems to only occur under a race condition I haven't gotten to the bottom of yet.

FWIW here's how I debugged this:

  1. select your UITextFieldView
  2. open the Debug View Hierarchy. You should see the UIView that would represent the cursor in the correct position, but it does not appear in the UI.
  3. right click the cursor's UIView and select "Print Description...". The description indicates OPAQUE=NO

Unfortunately, the UITextSelectionView class that owns this UIView is private and therefore there is no non-hacky way to programmatically update isOpaque.

This doesn't seem to be an issue in every implementation, however, here's the relationship between my views.

My text view delegate

extension FooViewController: UITextViewDelegate {
    private func updateSelection(selectedIndex indexPath: IndexPath) {
        if let oldSelected = self.table.indexPathForSelectedRow {
            tableDelegate.tableView(table, didDeselectRowAt: oldSelected)
        }
        tableDelegate.tableView(table, didSelectRowAt: indexPath)
    }

    func textViewShouldBeginEditing(_ textView: UITextView) -> Bool {
        guard let rowCell = getParentCell(forTextView: textView), // loops through table row cells
            !rowCell.isSelected,
            let indexPath = self.table.indexPath(for: rowCell)
            else { return true }

        updateSelection(selectedIndex: indexPath)
        return false
    }

and my table delegate:

class TableViewDelegate: NSObject, UITableViewDelegate {
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {       
        tableView.selectRow(at: indexPath, animated: false, scrollPosition: UITableView.ScrollPosition.none)
    }
}
dr_barto
  • 5,723
  • 3
  • 26
  • 47
TolkienWASP
  • 309
  • 1
  • 3
  • 10
0

For me, the problem was caused by embedding a UITextField in a UIToolbar. Once I had replaced the container for a simple UIView, the cursor worked again.

FD_
  • 12,947
  • 4
  • 35
  • 62
0

For me it wasn't the tintColor, it was caused by overriding caretRect method. Removing this method solved my case

open override func caretRect(for position: UITextPosition) -> CGRect {
       return CGRect.zero
   }
bahadir arslan
  • 4,535
  • 7
  • 44
  • 82
0

I also faced same issue and also tried the given answers but was not able to see the cursor in textview. Because the something else was causing the issue. So some of you might have uncommon issue like me than this will be helpful to you.

I was having this method overrided which was causing the cursor visibility issue

override func caretRect(for position: UITextPosition) -> CGRect {
    return .zero
}

So I just commented this lines and it was working fine for me