【问题标题】:Get frame of NSTextAttachmentCell in NSTextView在 NSTextView 中获取 NSTextAttachmentCell 的框架
【发布时间】:2013-02-09 10:40:49
【问题描述】:

我有一个带有图像的 NSTextView。我想为这些图像添加跟踪区域。我需要保存图像的单元格框架以创建跟踪区域。

所以我的问题是:如何在 NSTextView 的坐标系中获取 NSTextAttachments 的框架?

我正在以编程方式更改文本视图中图像的大小,此时我需要创建这个新的跟踪区域。我正在执行以下操作来创建带有文本附件的属性字符串,然后以编程方式将其插入到我的文本视图的属性字符串中。但是一旦我完成了这一切,我就不知道如何为新附件创建我的跟踪区域。

-(NSAttributedString*)attributedStringAttachmentForImageObject:(id)object {
    NSFileWrapper* fileWrapper = [[NSFileWrapper alloc] initRegularFileWithContents:[object TIFFRepresentationUsingCompression:NSTIFFCompressionLZW factor:1.0]];
    [fileWrapper setPreferredFilename:@"image.tiff"];
    NSTextAttachment* attachment = [[NSTextAttachment alloc] initWithFileWrapper:fileWrapper];
    NSAttributedString* aString = [NSAttributedString attributedStringWithAttachment:attachment];
    [fileWrapper release];
    [attachment release];
    return aString;
}

【问题讨论】:

    标签: objective-c cocoa nstextview nstextattachment


    【解决方案1】:

    由于附件由单个(不可见)字形 (0xFFFC) 组成,因此您可以使用字形消息来获取边界框。这是我用来根据鼠标位置(需要获取附件边界)在 NSTextView 中突出显示附件的代码:

    /**
     * Determines the index under the mouse. For highlighting we use the index only if the mouse is actually
     * within the tag bounds. For selection purposes we return the index as it was found even if the mouse pointer
     * is outside the tag bounds.
     */
    - (NSUInteger)updateTargetDropIndexAtPoint: (NSPoint)point
    {
        CGFloat fraction;
        NSUInteger index = [self.layoutManager glyphIndexForPoint: point
                                                  inTextContainer: self.textContainer
                                   fractionOfDistanceThroughGlyph: &fraction];
        NSUInteger caretIndex = index;
        if (fraction > 0.5) {
            caretIndex++;
        }
    
        // For highlighting a tag we need check if the mouse is actually within the tag.
        NSRect bounds = [self.layoutManager boundingRectForGlyphRange: NSMakeRange(index, 1)
                                                      inTextContainer: self.textContainer];
        NSUInteger newIndex;
        if (NSPointInRect(point, bounds)) {
            newIndex = index;
        } else {
            newIndex = NSNotFound;
        }
        if (hotTagIndex != newIndex) {
            NSRect oldBounds = [self.layoutManager boundingRectForGlyphRange: NSMakeRange(hotTagIndex, 1)
                                                             inTextContainer: self.textContainer];
            [self setNeedsDisplayInRect: oldBounds];
            hotTagIndex = newIndex;
            [self setNeedsDisplayInRect: bounds];
        }
    
        return caretIndex;
    }
    

    此代码用于 NSTextView 后代,因此是 self.layoutManager 访问权限。

    【讨论】:

    • 嗨,迈克,我有一个简短的问题要问你。 hotTagIndex 只是您在其他地方声明的 ivar 吗? “热”是指最近的/当前的/活跃的/突出显示的/其他词,对吗?不管怎样,感谢sn-p!很高兴看到一些 NSLayoutManager 代码在运行。
    • @BenStock:是的,热标签索引是鼠标当前悬停的标签的索引(iVar)。它用于突出显示标签并具有用于拖动的索引。
    • 感谢您的解释。我一直在尝试为我的NSTextView 子类中的几个NSTextAttachment 对象实现拖放目标突出显示,而您上面的代码使我免于很多麻烦。在您的代码之前,只有一半的附件会突出显示。我认为这与我对方法签名的fractionOfDistanceThroughGlyph: 部分缺乏了解有关。看到你所做的之后,它有很大帮助。再次感谢您的代码和快速响应!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-09
    相关资源
    最近更新 更多