PDFView setNeedsDisplay:YES在MacOS Sierra 10.12上不起作用

4
我用[PDFView setNeedsDisplay:YES]让PDF视图重绘,在OSX 10.9-10.11系统上效果不错。然而,除非我对PDF页面进行缩放,否则它无法正常工作。 是否还有其他立即重绘的方法?下面是代码:
NSRect      newBounds;
NSRect      currentBounds;
NSRect      dirtyRect;
NSPoint     mouseLoc;
NSPoint     endPt;

// Where is annotation now?
currentBounds = [_activeAnnotation bounds];

// Mouse in display view coordinates.
mouseLoc = [self convertPoint: [theEvent locationInWindow] fromView: NULL];

// Convert end point to page space.
if(activePage == nil)
    activePage =[_activeAnnotation page];

_LinePoint= [self convertPoint: mouseLoc toPage: activePage];
endPt = [self convertPoint: mouseLoc toPage: activePage];
if(_selectedIdx == 3) //ink
{
    [(PDFAnnotationInk*)_activeAnnotation removeBezierPath:_path];

    //endPt.x=_xPoint.x; //竖线
    //endPt.y=_xPoint.y; //横线

    [_path lineToPoint:endPt];  //  普通笔

    [(PDFAnnotationInk*)_activeAnnotation addBezierPath:_path];

    [self annotationChanged];
    [self setNeedsDisplay:YES];

    return;

更新:

我发现setNeedsDisplay调用了drawPage:toContext:,然而绘图代码在drawPage:toContext:中不起作用。

- (void)drawPage:(PDFPage *)pdfPage toContext(CGContextRef)context
{
    [super drawPage: pdfPage toContext:context];
    NSBezierPath *line=[NSBezierPath bezierPath];
    [line moveToPoint:_xPoint];
    [line lineToPoint:NSMakePoint(150, 150)];
    [[NSColor redColor] set];
    [line setLineWidth:50] ;
    [line stroke];
}

调试提示显示CGContextSetFillColorWithColor: invalid context 0x0,以及更多的invalid context 0x0警告。

drawPage:toContext:中的操作是测试,并且只使用BezierPath来绘制一条线。


1
在10.12中,PDFView内部发生了重大变化。现在绘图机制似乎不同了,它异步地在主线程之外绘制页面。似乎没有适当的方法来强制PDFView重新绘制自身或其页面。绘图仅在用户与PDFView本身(滚动、调整大小)交互时调用。可耻的是,苹果并没有认为有必要记录这些更改或为开发人员提供替代方案,一句话也没有。我也在寻找解决PDFView问题的方法(而且有很多问题)。 - danielv
谢谢您的回复...那么我们必须寻找其他方法...有什么建议吗? - SuperBerry
1
此外,在PDFView的drawPage:toContext:或PDFPage的drawWithBox:toContext:中,Cocoa绘图方法不起作用,因为它们在不同的线程上调用,该线程没有设置NSGraphicsContext。您需要显式地使用传递的上下文。 - danielv
有任何更新吗?它还是不工作吗? - Nisba
是的,还是不行。我不知道苹果在想什么。 - SuperBerry
显示剩余7条评论
1个回答

0
我也遇到了同样的问题。第一次添加注释时,PDFView会立即在页面上显示该注释。从那时起,在代码中添加或删除注释都可以正常工作,但是PDFView直到我手动滚动视图才会显示更改。
PDFKit中,我尝试过:
previewView.layoutDocumentView()

for pageIndex in 0...pdf.pageCount - 1 {
  let page = pdf.page(at: pageIndex)!
  previewView.annotationsChanged(on: page)
}

而从 NSView 中,我尝试过:

previewView.needsDisplay = true
previewView.needsLayout = true
previewView.documentView?.needsDisplay = true
previewView.updateLayer()

但是没有运气。我也尝试过使用代码滚动PDFView,但这并不是一种可靠的刷新方式,通常也不应该这样做。


是的...这不是好的方法。我使用放大,0.3秒后再缩小... - SuperBerry
但是很奇怪,我添加了注释后,PDFView 只有在滚动或缩放时才会显示。你能否展示一下你添加注释的代码吗? - SuperBerry
@SuperBerry 我在已经显示在屏幕上的PDFView中添加了这样的注释:pdf.page(at: i)?.addAnnotation(annotation)。该注释是一个文本注释。在这行代码之后,注释立即显示。在此之后,PDFView不会再更新任何添加或删除,直到我手动滚动。 - sahandnayebaziz
另外值得一提的是,我正在将相同的注释添加到PDF的每一页。因此,我使用for循环遍历每一页并对页面进行编号,为每一页添加一个注释。这可能是我第一次看到它的原因。更新注释(同样,在for循环中同时更新所有页面的注释)不会立即显示,我必须滚动视图,并且我的原始响应中的任何方法都不起作用。 - sahandnayebaziz
是的,这就是原因。如果你只添加到一个页面,你是看不到它的... 这让我很困惑... - SuperBerry
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接