正确定位拉伸的UIImages

时间:2010-11-16 18:07:38

标签: iphone

我正在创建一个UISegmentedControl替换,以便它可以与您自己的自定义图像一起使用。因为分隔符在两侧都需要不同的颜色,所以我决定给中间项目两个边框。

现在要显示UISegmentedControl替换,我计算一个项目的可用宽度(frame.size.width / numberOfItems)。然后我创建了一个带有自定义背景图像的UIButton(可伸展的中间段图像)。接下来就是定位一切。因为在选择项目时需要看到1px分隔符,所以我给每个项目的帧数比实际应该大1px。所以下一个项目向左重叠1px。

segmentRect = CGRectMake(indexOfObject * (self.frame.size.width / numberOfSegments), 0, (self.frame.size.width / numberOfSegments) + 1, self.frame.size.height);

使用此结果,我得到几乎完美的自定义UISegmentedControl(视网膜):alt text

现在事情看起来还不错,但是在添加更多/更少的细分时,这一切都会发生变化。顺便说一句,这是一个300px宽的控制,因此每个段获得25px的空间。如果我将该数字更改为13,则会显示:alt text

注意'3'和'4'之间的边界略有不同。 (实际上由于像素倍增,更容易在非视网膜上发现)我认为这是由每个片段获得的空间量不太大而引起的。 (300/13 = 23,0769)人们应该认为可拉伸的图像可以适应这种情况,不是吗?分隔符的宽度恰好是1px,我将帧更改为1px,因此两个分隔符应该完全放在彼此的顶部,这绝对不是这里的情况。

有没有人解释为什么会发生这种情况,更重要的是解决这个问题?

4 个答案:

答案 0 :(得分:2)

默认情况下,所有坐标都是浮点数(实际上是CGFloat's),所以如果您处理系统的非整数坐标,它将尽力使用消除锯齿在像素之间绘制。奇怪的3/4边界可能是由于这个原因。

一种解决方案是为所有段提供整数大小的宽度。这可能听起来有点讨厌,因为它们可能不是全部都是相同的宽度以填充空间(即,如果整体宽度不能被段的数量整除),但是如下的代码显示了如何做到这一点没有太多麻烦:

int totalWidth = self.frame.size.width;
float dx = (float)totalWidth / numSegments;
float lastX = 0.0;
for (int i = 0; i < numSegments; ++i) {
  int thisWidth = round(lastX + dx) - round(lastX);
  CGRect segmentFrame = CGRectMake(round(lastX), 0, thisWidth, height);
  /* do what you will with segmentFrame */
  lastX += dx;
}

我个人喜欢这种技术,因为它会自动均匀地分布比其他宽度稍大的宽度(所有宽度都在彼此的1个像素内)。

此代码不包括1像素重叠,但很容易添加。

另一个好处是,如果你的UILabel或UIImageView也有整数坐标(在整个屏幕的坐标系中),它们往往看起来更清晰。

答案 1 :(得分:0)

是的,我的猜测是UIView子类不喜欢不均匀的帧大小。我经历过这么多次。如果您尝试将分段视图放宽325px怎么办?如果它修复了故障,那么你得到了答案:)

答案 2 :(得分:0)

我不确定答案,我认为必须使用抗锯齿。 (在这种情况下,我们无法改变这一点)。 一种方法可能是:

int x = width%numberOfButtons;
if(x == 0){
    //do as now
}else{
    //make the first x buttons 1px bigger
}

答案 3 :(得分:0)

我设法自己拿出一些东西。我将每个段的宽度放在一边,因此中间的按钮看起来不错。然后我在第一个和最后一个按钮之间划分未使用的空格。 (再次是第一个的舍入值)