当图像连续插入时,NSTextField在NSTableView中模糊

时间:2017-02-27 12:39:51

标签: macos cocoa nstableview nstextfield nsimageview

在我的基于视图的NSTableView中,每个视图都有(以及其他内容)NSTextField和文本字段正下方的NSImageView。

有时,当我在表格的顶部插入一个新行,并且该行在其NSImageView中有一个图像时,其他行中的文本会变得模糊/降级。< /强>

滚动几次后,文字再次恢复正常。

不行:

enter image description here

确定:

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: ...)

如何避免此问题?它很难调试,因为它并不总是发生,我不知道它发生的原因是什么。

1 个答案:

答案 0 :(得分:2)

由于文本仅在插入图像时变得模糊,我首先想到的是NSTextField的帧不是&#34;整数&#34; (其像素值不是整数)。这是使文字模糊的一个众所周知的原因。

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

调用它的超级方法(让Cocoa进行所有需要的布局计算),只是将textFiled的框架设置为相同的框架,但是是整体的。

附录:虽然textField本身可能有一个整体框架 - 它仍然可以放置在一个半像素&#34; (在真实的屏幕坐标中)仍然会导致模糊。

TextField是单元格的子视图,因此itss框架不在屏幕坐标中,而是在单元格坐标中。

示例:让我们想象一下,单元格的框架(0.5, 0.5 , 100, 100)不是整数,textField有一个(10,10, 50, 50)的整体框架,这是一体的积分!

但是当textField将被放置在屏幕上时,它将具有以下帧:(10.5, 10.5, 50, 50)这不是整数 - 并且将导致在&#34;半像素&#34;上绘制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)];
    }
    */
}