UIView
的{{1}}始终为1,即使在Retina设备上也是如此,除非您实施contentScaleFactor
。请考虑以下代码:
drawRect:
在Retina设备上,它会打印以下内容:
@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
设置正确,否则图像在Retina设备上无法正确拉伸。确切地说,它正常工作除非使用@2x
图像。我猜这是一个错误。
任何人都可以分享您对@2x
行为方式的看法吗?它仅适用于iOS 5吗?
答案 0 :(得分:10)
据推测,如果你不重写drawRect:
,那么UIKit就知道UIView
没有绘制任何东西,所以它需要(可能)快速的情况下拥有一个层内容比例为1.但是,只要覆盖drawRect:
,它就知道需要设置一个具有正确内容比例的图层,如果您愿意,可以将其绘制。它并不知道你在drawRect:
中什么都不做,但它不能像以前那样做出相同的假设。
事实上,文档中提到了所有这些:
对于实现自定义drawRect:method 且与窗口关联的视图,此属性的默认值是与当前显示视图的屏幕关联的比例因子。
为什么不覆盖drawRect:
并在其中绘制图像?或者你可能会逃脱你当前正在做的事情并拥有一个存根drawRect:
。鉴于文档所说的内容,我可以说假设它会继续工作并且是正确的行为是完全合理的。
答案 1 :(得分:0)
原生绘图技术(如Core Graphics)会将当前比例因子考虑在内。例如,如果您的一个视图实现了drawRect:方法,UIKit会自动将该视图的比例因子设置为屏幕的比例因子。此外,UIKit会自动修改绘图期间使用的任何图形上下文的当前变换矩阵,以考虑视图的比例因子。因此,您在drawRect:方法中绘制的任何内容都会针对底层设备的屏幕进行适当缩放。