2012-02-28 92 views
7

我偶然發現了一件奇怪的事情。它看起來像UIViewcontentScaleFactor始終是1,即使在Retina設備上,除非您實施drawRect:。考慮以下代碼:UIView的contentScaleFactor依賴於實現drawRect:?

@interface MyView : UIView 
@end 

@implementation MyView 

- (id) initWithFrame: (CGRect) frame 
{ 
    self = [super initWithFrame: frame]; 
    if (self) { 
     NSLog(@"%s %g %g %g", __PRETTY_FUNCTION__, self.contentScaleFactor, self.layer.contentsScale, [UIScreen mainScreen].scale); 
    } 
    return self; 
} 

- (void) didMoveToWindow 
{ 
    if (self.window) 
     NSLog(@"%s %g %g %g", __PRETTY_FUNCTION__, self.contentScaleFactor, self.layer.contentsScale, [UIScreen mainScreen].scale); 
} 

@end 

在視網膜上的裝置,它打印如下:

-[MyView initWithFrame:] 1 1 2 
-[MyView didMoveToWindow] 1 1 2 

如果我添加一個空的實現drawRect:這樣的:

- (void) drawRect: (CGRect) rect 
{ 
} 

它按預期工作:

-[MyView initWithFrame:] 2 2 2 
-[MyView didMoveToWindow] 2 2 2 

因此,如果視圖位於任何視圖層次結構中,並且它顯示的是何種屏幕,它看起來並不重要。唯一重要的是如果視圖實現drawRect:或不。

這是一個錯誤或功能?我知道我可以如下改變didMoveToWindow修復它

- (void) didMoveToWindow 
{ 
    if (self.window) 
     self.contentScaleFactor = self.window.screen.scale; 
} 

但默認的行爲仍然錯誤我。

你可能會問,爲什麼我需要contentScaleFactor,如果我什麼都沒畫。這是因爲我只是將self.layer.contents設置爲現成的圖像,然後用contentStretch將圖像拉伸。但是,除非contentScaleFactor設置正確,否則即使使用@2x圖像,圖像在Retina設備上的伸展也不正確。準確地說,它可以正常工作,除非使用 a @2x圖像。我猜這是一個錯誤。

任何人都可以分享你的見解,爲什麼contentScaleFactor表現這樣?它僅針對iOS 5嗎?

回答

10

據推測,如果不重寫drawRect:然後UIKit的知道,所以只要你需要覆蓋具有具有1的含量規模層(大概)快速情況下UIView不畫任何東西不過,它知道需要設置一個具有正確內容比例的圖層,並且可以根據需要進行繪製。它不知道你在drawRect:裏什麼都不做,儘管如此它不能做出和以前一樣的假設。

其實所有這一切都是在文檔提到:

對於實現自定義的drawRect觀點:法並與窗口關聯,此屬性的默認值是相關聯的比例因子當前屏幕顯示視圖。

爲什麼不重寫drawRect:並在此畫圖?或者你可能會逃避你目前正在做的事情,並有一個存根drawRect:。根據文檔的說法,我會說這是完全合理的假設它將繼續工作,並且是正確的行爲。

+0

非常感謝!實質上,我也這麼認爲,但「對於實現自定義'drawRect:'方法和**與窗口**相關聯的視圖」(強調我的意思)意味着只有在將視圖添加到窗口。正如你所看到的,它與一個被忽略的窗口相關聯。也許只是一個文檔錯誤。至於繪製'drawRect:',我避免了它,因爲視圖非常大,我有十幾個,而我拉伸的圖像是31x31像素。基本上,我只是儘量保持內存佔用儘可能低。 – Costique 2012-02-28 13:07:19

+0

謝謝。我在自定義CALayer中完成所有繪圖,並且始終將其contentScale重置爲1.現在,它看起來非常漂亮,視網膜清晰。 – 2013-11-29 16:07:08

0

原生繪圖技術,例如Core Graphics,會考慮當前的比例因子。例如,如果其中一個視圖實現了drawRect:方法,則UIKit會自動將該視圖的比例因子設置爲屏幕的比例因子。另外,UIKit會自動修改繪圖期間使用的任何圖形上下文的當前變換矩陣,以考慮視圖的比例因子。因此,您在drawRect:方法中繪製的任何內容都會針對底層設備的屏幕進行適當縮放。