ios – 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",[UIScreen mainScreen].scale);
}

@end

在Retina设备上,它打印以下内容:

-[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图像,否则它可以正常工作.我猜这是一个错误.

任何人都可以分享您对contentScaleFactor行为方式的看法吗?它仅适用于iOS 5吗?

解决方法

据推测,如果你没有覆盖drawRect:那么UIKit就知道UIView没有绘制任何东西所以它需要(大概)快速的情况下有一个内容规模为1的图层.一旦你覆盖drawRect:虽然,它知道它需要设置一个具有正确内容比例的图层,如果你愿意,你可以绘制.它不知道你在drawRect中什么都不做:虽然它不能做出和以前一样的假设.

事实上,文档中提到了所有这些:

For views that implement a custom drawRect: method and are associated with a window,the default value for this property is the scale factor associated with the screen currently displaying the view.

为什么不直接覆盖drawRect:并在其中绘制图像?或者你可能会逃脱你目前正在做的事情,并有一个存根drawRect:.鉴于文档所说的内容,我认为假设它将继续工作并且是正确的行为是完全合理的.

相关文章

当我们远离最新的 iOS 16 更新版本时,我们听到了困扰 Apple...
欧版/美版 特别说一下,美版选错了 可能会永久丧失4G,不过只...
一般在接外包的时候, 通常第三方需要安装你的app进行测...
前言为了让更多的人永远记住12月13日,各大厂都在这一天将应...