12

在一个空白的 UIViewController 中,我通过以下方式更改屏幕颜色:

self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"blackPattern.png"]];

然后我用我的 iPhone 5 截屏。图像看起来像:

在此处输入图像描述

如果您以 100% 的比例查看图像,您将看到三个条(顶部、左侧和底部)。但是,我的图案图像非常简单(blackPattern@2x.png):

在此处输入图像描述

这是用于视网膜显示的 8x8 png。

具有讽刺意味的是,当应用程序在模拟器上运行时,这些栏是不可见的。它是 iPhone 5 硬件特定的症状吗?

ps 如果你想看到它运行,你可以下载我的应用程序:这里

4

3 回答 3

2

有趣的。我可以在 iPhone 5 上重现该问题(不在模拟器上,甚至在视网膜模式下)。

一些想法和观察: 小图案图像中的颜色恰好是黑色和白色(0 和 255,每个 r、b 和 g)。在全屏图像中它不是。中间是 8 和 247,底部是 12,243,侧面是 4,251。

这看起来很像一个插值工件:当 Core Graphics 将图像中的像素绘制到设备像素上并且像素不完全匹配时,它会根据相邻源像素计算插值颜色。黑色和白色会产生深灰色和亮灰色:我们在这种情况下看到的效果。

我仍然不知道为什么这只发生在设备上。

玩一点这个问题我没有找到原因,但解决了您的问题:自己创建棋盘图案颜色:

static void patternDrawPatternCallback(void *info, CGContextRef c)
{
    for (int y = 0; y < 8; ++y) {
        for (int x = 0; x < 8; ++x) {
            CGFloat v = (x + y) & 1;
            CGContextSetRGBFillColor(c, v, v, v, 1);
            CGContextFillRect(c, (CGRect){{x, y}, {1, 1}});
        }
    }
}

static void patternReleaseInfoCallback(void *info)
{
}

static UIColor *checkerColor()
{
    CGPatternCallbacks callbacks = {
        .drawPattern = patternDrawPatternCallback,
        .releaseInfo = patternReleaseInfoCallback,
    };

    CGFloat scale = 1.0f / [UIScreen mainScreen].scale;
    CGPatternRef pattern = CGPatternCreate(NULL,
                                           (CGRect){.size={8, 8}},
                                           CGAffineTransformMakeScale(scale, scale),
                                           8, 8,
                                           kCGPatternTilingConstantSpacing,
                                           YES,
                                           &callbacks);

    CGFloat components[] = {1, 1, 1, 1};
    CGColorSpaceRef colorspace = CGColorSpaceCreatePattern(NULL);
    CGColorRef color = CGColorCreateWithPattern(colorspace, pattern, components);
    CGColorSpaceRelease(colorspace);
    CGPatternRelease(pattern);

    UIColor *checkerColor = [UIColor colorWithCGColor:color];
    CGColorRelease(color);

    return checkerColor;
}

使用此代码中的颜色我无法重现该问题(即使我使用了图案平铺并将平铺的大小设置为略微偏离)。

于 2013-02-15T11:10:39.487 回答
0

我不知道这是否是您的确切问题,但是这一行:

self.view.backgroundColor = [UIColor colorWithPatternImage:
    [UIImage imageNamed:@"blackPattern.png"]];

...意味着您正在使用名为“blackPattern.png”的文件,无论设备是否为视网膜。该行应该是:

self.view.backgroundColor = [UIColor colorWithPatternImage:
    [UIImage imageNamed:@"blackPattern"]];

...(.png最后没有)。这样,如果设备是视网膜,您的程序将使用“blackPattern.png”(如果非视网膜)和“blackPattern@2x.png”。

可能您运行此代码的模拟器不是视网膜,所以看起来不错;您看到问题的只是视网膜设备。

于 2013-02-14T02:18:48.857 回答
0

看起来您正在创建 UIImageView 或 UIView 并具有透明背景。由于您使用的图像包含不透明和透明的颜色,您仍然可以看穿它。

于 2013-02-19T15:13:10.420 回答