NSTextField在NSTableView中模糊,当图像插入一行时

问题描述:

在我的基于视图的NSTableView中,每个视图(除其他外)都有一个NSTextField和一个位于文本字段下方的NSImageView。NSTextField在NSTableView中模糊,当图像插入一行时

有时候,当我在表的顶部插入新行,此行中的NSImageView有图像,在其他行文本变得模糊/降级。

滚动数次后,文字再次变为正常。

不正常:

enter image description here

OK:

enter image description here

一个例子,其中的文本仅仅是行模糊所述一个与后我法师:

enter image description here

这真的让我觉得这是从.insertRowsnoteHeightOfRows未来的问题。

所有元素都在IB中设置了自动布局约束。

滚动视图在IB中设置CoreAnimation图层。在制备细胞时,我也使用层:

cell.layer?.isOpaque = true 
cell.textLabel.layer?.isOpaque = true 

有时

cell.layer?.borderColor = someColor 
cell.layer?.borderWidth = someWidth 

enter image description here

行是插入有:

// update the model, then: 
NSAnimationContext.runAnimationGroup({ (context) in 
    context.allowsImplicitAnimation = true 
    self.table.insertRows(at: index, withAnimation: [.effectGap]) 
}) 

更新与所述图像的行:

// in tableViewCell, while populating the table 
cell.postImage.image = img 
cell.postImage.needsDisplay = true 

// once the image is downloaded 
table.reloadData(forRowIndexes: ..., columnIndexes: ...) 
table.noteHeightOfRows(withIndexesChanged: ...) 

如何避免此问题?这很难调试,因为它不总是发生,我不明白什么时候它发生的原因。

+0

你好,也许图像推文半像素远离它是不可或缺的位置 - 而这些事情是造成模糊的文本。 – ColdSteel

+0

哦,有趣的想法。也许自动布局的问题呢?我不知道我应该如何调试这个,虽然... – Moritz

+0

你可以用非常简单的方式进行测试 - 在表视图绘制之后(布局子视图或任何它调用的对象(对不起,我不是AutoLayout风扇,因为这样的事情))只是将文本框的框架重置为整体框架 - 并强制显示... 这样的事情 '[myTetxField setFrame:NSIntegralRect(myTextField.frame)];' – ColdSteel

由于文本仅在插入图像时变得模糊,我首先想到的是NSTextField的帧不是“整数”(其像素值不是整数)。这是获取模糊文本的众所周知的原因。

您正在使用Cocoa的自动布局功能,所以我的建议是覆盖基于视图的表格视图单元格中的void layout()方法。

调用它的超级方法(让Cocoa做所有需要的布局计算),并将textFiled的框架设置为相同的框架,但不可或缺。


附录:当文本字段本身可能有一个整体框架 - 它仍然可以在“半像素”(实际屏幕坐标),这仍然会导致模糊来奠定的。

TextField是单元格的子视图,所以它的框架不在屏幕坐标中,而是在单元格坐标中。

例如:我们假设单元格的框架为(0.5, 0.5 , 100, 100),它不是整数,而textField的整数框架为(10,10, 50, 50),它是所有方法都必需的!

但是,当textField放在屏幕上时,它将具有以下帧:(10.5, 10.5, 50, 50)它不是整数 - 并且将导致在“半像素”(不是整数)上绘制textField,从而导致文本模糊。

所以在你的情况下,单元格本身必须放置在一个整体框架以及textField上,以确保textField在屏幕坐标系中的整体框架上。


在你tableViewCell子类:

void layout() 
{ 
    [super layout]; 

    //**** We have to ensure that the cell is also layed on an integral frame ****// 

    [self setFrame:NSIntegralRect(self.frame)]; 

    //At this point after calling the [super layout]; myTextField will have a valid (autolayoutwise) frame so all you have to do is to ensure that it is indeed an integral frame doing so by calling NSIntegralRect(NSRect rect); method of Cocoa framework. 
    [myTetxField setFrame:NSIntegralRect(myTextField.frame)]; 

    //Maybe optionally you will want to set everything to the integral rect :-) 
    /* 
    for(NSView * view in self.subViews) 
    { 
     [view setFrame:NSIntegralRect(view.frame)]; 
    } 
    */ 
} 
+0

我发现这不适用于10.11(但在10.12上效果很好,这是我在与您一起调试时遇到的问题)。所以你的回答仍然有效,而且非常有用,我实际上正在使用它 - 但如果你碰巧对这个问题有另一个想法,我就会全神贯注。 ;)有趣的是,在10.11之后,带图像的* whole *单元格变得模糊:textFields,imageViews等等。在我这边,我会尝试组合我们讨论过的东西(canDrawSubviewsIntoLayer等),并且会给反馈如果我找到了一些东西 – Moritz

+0

我会那样做的。之前我没有注意到,因为我在这台10.11机器上测试的时间非常有限。无论如何,与10.11的完全兼容性对于此应用程序的优先级列表来说很低,所以我没有想到要验证解决方案。 //是的,绝对的,下一次我可以访问10.11,我将准备日志和截图。这可能会成为一个新问题,将其称为“10.12工作”。谢谢。 :) – Moritz

+0

@EricAya好吧,对不起,它没有作为一个银色的子弹工作:-(。在我的大多数情况下'NStextFields'工作〜类似从操作系统到操作系统...可能有一些与层(它建议图像也是模糊的) 也许你可以尝试指定一个背景颜色,所以你将受益于抗锯齿,但不知道必须看到它 – ColdSteel