7

I'm ashamed to admit that I don't know how to clear a UITextView.

By clearing, I mean leaving its text blank and removing all of its attributes. I thought setting it to nil would be enough, but the attributes of the first character remain there, silently waiting until I type again to be added.

For example, the following code has a vanilla UITextView that can be cleared on double tap (doubleTapAction:). When loaded, I add a custom attribute that should also be removed when the UITextView is cleared.

@implementation HPViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:@"test"];
    [attributedString addAttributes:@{@"attribute" : @"value"} range:NSMakeRange(0, 1)];
    self.textView.attributedText = attributedString;
}

- (IBAction)doubleTapAction:(id)sender
{
    self.textView.text = nil;
    // Also tried:
    // self.textView.text = @"";
    // self.textView.attributedText = nil;
    // self.textView.attributedText = [[NSAttributedString alloc] initWithString:@""];
}

- (void)textViewDidChange:(UITextView *)textView
{
    NSLog(@"%@", textView.attributedText);
}

@end

Clearing the UITextView and then typing the letter "d" logs the following:

d{
    NSFont = "<UICTFont: 0x8a7e4e0> font-family: \"Helvetica\"; font-weight: normal; font-style: normal; font-size: 12.00pt";
    NSParagraphStyle = "Alignment 4, LineSpacing 0, ParagraphSpacing 0, ParagraphSpacingBefore 0, HeadIndent 0, TailIndent 0, FirstLineHeadIndent 0, LineHeight 0/0, LineHeightMultiple 0, LineBreakMode 0, Tabs (\n    28L,\n    56L,\n    84L,\n    112L,\n    140L,\n    168L,\n    196L,\n    224L,\n    252L,\n    280L,\n    308L,\n    336L\n), DefaultTabInterval 0, Blocks (null), Lists (null), BaseWritingDirection 0, HyphenationFactor 0, TighteningFactor 0, HeaderLevel 0";
    attribute = value;
}

My custom attribute is still there!

Is this a bug or expected behaviour?

hpique
  • 119,096
  • 131
  • 338
  • 476
  • +1 for yet another bizarre issue in UITextView. For the last couple of days, I have been stuck with the usage of UITextView and found 3-4 major issues, like extra padding, size, and this one. – Shivam Pokhriyal Jun 14 '19 at 06:31

5 Answers5

9

This awful hack does the trick:

self.textView.text = @"Something, doesn't matter what as long as it's not empty";
self.textView.text = @"";

Still, it would be nice to confirm if this is a bug or expected behaviour. I couldn't find anything in the documentation about it.

hpique
  • 119,096
  • 131
  • 338
  • 476
4
textView.text=@"";
[textView insertText:@""];

try this!

user3044484
  • 463
  • 5
  • 7
1

You have to manually reset font, text color etc. to your default values. Setting attributedText always sets the UITextView's "global" attributes to those of the first letter in the attributed string.

johnyu
  • 2,152
  • 1
  • 15
  • 33
  • Would that reset custom attributes? Edit: nope, it doesn't. I'm asking about all attributes, not just paragraph, color and font. – hpique Feb 12 '14 at 14:51
  • Just add self.textView.textColor = , and things like that for every attribute that might have been changed by NSAttributedString. – johnyu Feb 12 '14 at 14:53
  • UITextView only exposes a handful of attributes. It's not enough. – hpique Feb 12 '14 at 14:55
  • If there are attributes that can be only set with NSAttributedString but not for UITextView (which sounds odd), you can try "hacky" approach - when you remove your attributed string, create a new one with the default attributes you like (text doesn't matter, just don't make its length 0), set it as text view's attributedText and then remove it again. – johnyu Feb 12 '14 at 14:57
  • Found a solution. Thanks for trying to help anyway. +1 – hpique Feb 12 '14 at 15:07
1

In my app I was seeing poor performance from the hack suggested by hpique:

self.textView.text = @"Something, doesn't matter what as long as it's not empty";
self.textView.text = @"";

The first line forces the UITextView to layout everything again. This is costly if the UITextView is used in a reused cell (in a UITableView for example).

In iOS 8 and later I found it much more performant with the following reset method on my UITextView subclass:

- (void)reset
{    
    self.text = nil;
    self.font = nil;
    self.textColor = nil;
    self.textAlignment = NSTextAlignmentLeft;
}
Nicolai Dahl
  • 259
  • 3
  • 9
1

There is one property which can be useful in this situation. It's typingAttributes.

let textView = UITextView()
let attributes: [NSAttributedString.Key: Any] = [
    .font: UIFont.systemFont(ofSize: 16, weight: .regular),
    .foregroundColor: UIColor.black,
]
textView.typingAttributes = attributes
DZoki019
  • 382
  • 2
  • 13