iphone – 正确定位拉伸UIImages

我正在创建一个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(视网膜):

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

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

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

最佳答案 默认情况下,所有坐标都是浮点数(实际上是CGFloat),所以如果你正在处理系统的非整数坐标,它将尽可能使用抗锯齿在像素之间绘制.奇怪的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也有整数坐标(在整个屏幕的坐标系中),它们往往看起来更清晰.

点赞