Reputation: 5698
I am creating a NSTextView
, and I want to change the size of the insertion point when the NSTextView is empty.
It appears that the caret cursor (I-Beam / IBeam cursor) size is based off of the current font size attribute on the attributedString
property of the NSTextView
.
The problem is that because the NSTextView
has an empty attributedString
, there can be no attributes on the string. This means that I can't apply a font size.
However, I can change the typingAttributes
to have the fontSize be correct-- but the Insertion Point Cursor does not update size until I start typing
See these screenshots:
Notice here the textview on the right has a small insertion point cursor:
I start typing, and it updates in size:
So my question is, is there a property that I need to set on the NSTextView
when I initialize it, in order to get the initial Insertion Point Cursor the correct Size? (I want it to match the typingAttributes
font)
EDIT: @Mark Bessey brought up a good question-- what is the order that I'm setting the typing attributes:
[_textEditor setTypingAttributes:typingAttributes];
[_textEditor setDelegate:self];
[view addSubview:_textEditor];
[self updateInsertionPointColor];
[[view window] makeFirstResponder:_textEditor];
[view setNeedsDisplay:YES];
Upvotes: 2
Views: 1279
Reputation: 146
I just ran into the same problem and – after not finding a good solution anywhere – managed to force the NSTextView to update its pointer by inserting a character and then replacing that character with an empty string in the same cycle.
I'm doing this in textView(_:shouldChangeTextIn:replacementString:), but I guess it works elsewhere just as fine.
let attributedString = NSAttributedString(string: " ", attributes: attributes)
let range = someRange
let insertLocation = range.location + range.length
textView.textStorage?.insert(attributedString, at: insertLocation)
textView.typingAttributes = attributes
textView.replaceCharacters(in: range, with: "")
Upvotes: 1
Reputation: 3365
To changed the attributes when there is no text, using typingAttributes.
Typing attributes are reset automatically whenever the selection changes. However, if you add any user actions that change text attributes, the action should use this method to apply those attributes afterwards. User actions that change attributes should always set the typing attributes because there might not be a subsequent change in selection before the next typing.
@IBOutlet var targetTextView: NSTextView!{
didSet {
let attributes:[NSAttributedString.Key:Any] = [
.font:NSFont.userFont(ofSize: 16.0) ?? NSFont.systemFont(ofSize: 16.0),
.foregroundColor:NSColor(named: "targetColor")!
]
targetTextView.typingAttributes = attributes
}
}
Upvotes: 0
Reputation: 19782
Doing this works in a simple test app, in my applicationDidFinishLaunching method:
NSFont *font = [NSFont fontWithName:@"Marker Felt" size:24.0];
NSDictionary *attr = @{
NSFontAttributeName: font
};
[self.textView setTypingAttributes:attr];
I get the large I-beam cursor that I'd expect.
This is basically the same as what TextEdit does (sample code here), so it doesn't look like you're doing anything wrong, as far as setting the typingAttributes goes.
I wonder if perhaps you're setting the attributes at the wrong time. When do you set the typingAttributes? Is the view on-screen? Is it the first responder?
Upvotes: 0