问题
So I am trying to get either an NSPoint or NSRect corresponding with the location of a specific character in an NSTextView. This is what I have so far (that isn't working very well, the results seem kind of unpredictable.
NSRange theTextRange = [[theTextView layoutManager] glyphRangeForCharacterRange:[theTextStorage editedRange] actualCharacterRange:NULL];
NSRect theTextRect = [[theTextView layoutManager] boundingRectForGlyphRange:theTextRange inTextContainer:[theTextView textContainer]];
回答1:
The rect returned by boundingRectForGlyphRange:inTextContainer:
is in container coordinates. You need to adjust for this if you want to get the rect relative to the text view:
NSRange theTextRange = [[textView layoutManager] glyphRangeForCharacterRange:textRange actualCharacterRange:NULL];
NSRect layoutRect = [[textView layoutManager] boundingRectForGlyphRange:theTextRange inTextContainer:[textView textContainer]];
NSPoint containerOrigin = [textView textContainerOrigin];
layoutRect.origin.x += containerOrigin.x;
layoutRect.origin.y += containerOrigin.y;
回答2:
You can use mouse down event by NSPoint & NSRect
#import <Cocoa/Cocoa.h>
@interface ClickTextView : NSView {
NSMutableArray *texts;
NSPoint currentLocation;
NSCell *cell;
}
@end
#import "ClickTextView.h"
@interface TextClip : NSObject
{
@public
NSString *text;
NSPoint location;
}
@end
@implementation TextClip @end
@implementation ClickTextView
- (void)awakeFromNib
{
texts = [NSMutableArray new];
cell = [[NSTextFieldCell alloc] initTextCell: @""];
[cell setEditable: YES];
}
- (void)drawRect:(NSRect)rect
{
NSRect frame = rect;
[[NSColor whiteColor] set];
[NSBezierPath fillRect: rect];
for (TextClip *clip in texts)
{
[cell setStringValue: clip->text];
frame.origin = clip->location;
[cell drawWithFrame: frame inView: self];
}
}
- (void)mouseDown: (NSEvent*)theEvent
{
currentLocation = [self convertPoint: [theEvent locationInWindow]
fromView: nil];
NSText *fieldEditor = [[self window] fieldEditor: YES
forObject: self];
[cell endEditing: fieldEditor];
[fieldEditor setString: @""];
[cell setStringValue: @""];
NSRect frame = {currentLocation, {400, 400}};
[cell editWithFrame: frame
inView: self
editor: fieldEditor
delegate: self
event: theEvent];
}
- (BOOL)isFlipped
{
return YES;
}
- (void)textDidEndEditing: (NSNotification*)aNotification
{
NSText *text = [aNotification object];
TextClip *clip = [[TextClip alloc] init];
clip->text = [[text string] copy];
clip->location = currentLocation;
[texts addObject: clip];
[cell endEditing: text];
[self setNeedsDisplay: YES];
}
@end
来源:https://stackoverflow.com/questions/5160094/nspoint-nsrect-from-character-in-nstextview