1

目前,我有一个带有自定义 NSTextFieldCell 的 NSTableView,其中包含一个 NSAttributedString,其中包含 NSLinkAttribute 的一些范围。我尝试整合 Apple 的TableViewLinks 示例和 Toomas Vather 的HyperlinkTextField中的代码。

我实现了这样的 -trackMouse 函数:

- (BOOL)trackMouse:(NSEvent *)theEvent inRect:(NSRect)cellFrame ofView:(NSView *)controlView untilMouseUp:(BOOL)flag {

BOOL result = YES;
NSUInteger hitTestResult = [self hitTestForEvent:theEvent inRect:cellFrame ofView:controlView];
if ((hitTestResult & NSCellHitContentArea) != 0) {
    result = [super trackMouse:theEvent inRect:cellFrame ofView:controlView untilMouseUp:flag];
    theEvent = [NSApp currentEvent];
    hitTestResult = [self hitTestForEvent:theEvent inRect:cellFrame ofView:controlView];
    if ((hitTestResult & NSCellHitContentArea) != 0) {
        NSAttributedString* attrValue = [self.objectValues objectForKey:@"theAttributedString"];
        NSMutableAttributedString* attributedStringWithLinks = [[NSMutableAttributedString alloc] initWithAttributedString:attrValue];

        //HOW TO GET A RIGHT INDEX?
        NSTableView* myTableView = (NSTableView *)[self controlView];
        NSPoint eventPoint = [myTableView convertPoint:[theEvent locationInWindow] fromView:nil];
        NSInteger myRow = [myTableView rowAtPoint:eventPoint];
        NSRect myBetterViewRect = [myTableView rectOfRow:myRow];


        __block NSTextView* myTextView = [[NSTextView alloc] initWithFrame:myBetterViewRect];
        [myTextView.textStorage setAttributedString:attributedStringWithLinks];

        NSPoint localPoint = [myTextView convertPoint:eventPoint fromView:myTableView];
        NSUInteger index = [myTextView.layoutManager characterIndexForPoint:localPoint inTextContainer:myTextView.textContainer fractionOfDistanceBetweenInsertionPoints:NULL];

        if (index != NSNotFound)
        {
            NSMutableArray* myHyperlinkInfos = [[NSMutableArray alloc] init];
            NSRange stringRange = NSMakeRange(0, [attrValue length]);
            [attrValue enumerateAttribute:NSLinkAttributeName inRange:stringRange options:0 usingBlock:^(id value, NSRange range, BOOL* stop)
             {
                 if (value)
                 {
                     NSUInteger rectCount = 0;
                     NSRectArray rectArray = [myTextView.layoutManager rectArrayForCharacterRange:range withinSelectedCharacterRange:range inTextContainer:myTextView.textContainer rectCount:&rectCount];
                     for (NSUInteger i = 0; i < rectCount; i++)
                     {
                         [myHyperlinkInfos addObject:@{kHyperlinkInfoCharacterRangeKey : [NSValue valueWithRange:range], kHyperlinkInfoURLKey : value, kHyperlinkInfoRectKey : [NSValue valueWithRect:rectArray[i]]}];
                     }
                 }
             }];

            for (NSDictionary* info in myHyperlinkInfos)
            {
                NSRange range = [[info objectForKey:kHyperlinkInfoCharacterRangeKey] rangeValue];
                if (NSLocationInRange(index, range))
                {
                    NSURL* url = [NSURL URLWithString:[info objectForKey:kHyperlinkInfoURLKey]];
                    [[NSWorkspace sharedWorkspace] openURL:url];
                }
            }
        }
    }
}
return result;}

单击单元格(nstextview)文本时的字符索引似乎不适合。所以即使文本中有多个链接,通常也会打开最后一个链接。我的猜测是我没有得到点击单元格的 nsrect 。如果是这样,我怎样才能得到正确的 NSRect?

我很高兴有任何建议、评论、代码片段——或更简单的解决方案(即使这包括切换到基于视图的表格视图)。

谢谢。

4

0 回答 0