UIView的contentScaleFactor依赖于实现drawRect:?
我偶然发现了一件奇怪的事情。 它看起来像UIView
的contentScaleFactor
始终是1,即使在Retina设备,除非你实现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
在Retina设备上打印下列内容:
-[MyView initWithFrame:] 1 1 2 -[MyView didMoveToWindow] 1 1 2
如果我添加一个空的drawRect:
实现drawRect:
像这样:
- (void) drawRect: (CGRect) rect { }
它按预期工作:
-[MyView initWithFrame:] 2 2 2 -[MyView didMoveToWindow] 2 2 2
所以看起来好像这个视图是否在任何视图层次结构中,以及它显示的是什么样的屏幕并不重要。 唯一重要的是如果视图实现drawRect:
或不。
这是一个错误或function? 我知道我可以改变didMoveToWindow
如下来解决它
- (void) didMoveToWindow { if (self.window) self.contentScaleFactor = self.window.screen.scale; }
但默认行为仍然错误我。
如果我没有画任何东西,你可能会问为什么我需要contentScaleFactor
。 这是因为我只是将self.layer.contents
设置为现成的图像,然后使用contentStretch
拉伸图像。 但是,除非使用了@2x
图像,否则图像无法在Retina设备上正常展开,除非contentScaleFactor
设置正确。 确切地说, 除非使用@2x
图像, 否则它可以正常工作。 我想这是一个错误。
任何人都可以分享你的见解,为什么contentScaleFactor
行为? 仅针对iOS 5吗?
据推测,如果你不重写drawRect:
那么UIKit知道一个UIView
不会绘制任何东西,所以它需要一个内容比例为1的图层(假定)。只要你重写drawRect:
尽pipe,它知道需要设置一个正确的内容比例的图层,如果你愿意的话可以绘制成图层。 它并不知道你在drawRect:
什么都不做drawRect:
尽pipe如此,它不能和以前一样。
事实上,在文档中提到了这一切:
对于实现自定义drawRect:方法并与窗口关联的视图,此属性的默认值是与当前显示视图的屏幕相关联的比例因子。
你为什么不重写drawRect:
在那里画图片? 或者你也许可以逃避你正在做的事情,并有一个存根。 根据文档的说法,我认为这是完全合理的假设它将继续工作,是正确的行为。
原生绘图技术(如Core Graphics)会考虑当前的比例因子。 例如,如果其中一个视图实现了drawRect:方法,则UIKit会自动将该视图的比例因子设置为屏幕的比例因子。 此外,UIKit会自动修改绘图过程中使用的任何graphics上下文的当前转换matrix,以考虑视图的比例因子。 因此,您在drawRect:方法中绘制的任何内容都会针对底层设备的屏幕进行适当缩放。