2017-02-27 45 views
2

在我的基於視圖的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

回答

1

由於文本僅在插入圖像時變得模糊,我首先想到的是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