2012-02-28 49 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:方法中绘制的任何内容都会针对底层设备的屏幕进行适当缩放。