我正在创建一个 UISegmentedControl 替代品,以便它可以与您自己的自定义图像一起使用。因为分隔符两侧需要不同的颜色,所以我决定为中间的项目提供两个边框。
现在为了显示 UISegmentedControl 替换,我计算了一项的可用宽度 (frame.size.width/numberOfItems)。然后我创建一个带有自定义背景图像(可拉伸(stretch)的中间部分图像)的 UIButton。接下来的事情是定位一切。因为当您选择一个项目时 1px 分隔符需要可见,所以我给每个项目一个比实际应有的大 1px 的框架。因此下一个项目向左重叠 1px。
segmentRect = CGRectMake(indexOfObject * (self.frame.size.width / numberOfSegments), 0, (self.frame.size.width / numberOfSegments) + 1, self.frame.size.height);
使用这个结果,我得到了几乎完美的自定义UISegmentedControl(视网膜):
现在一切看起来都不错,但是当添加更多/更少的段时,一切都会改变。顺便说一句,这是一个 300 像素宽的控件,因此每个段都有 25 像素的空间。如果我将该数字更改为 13,则会显示:
请注意“3”和“4”之间的边界略有不同。 (实际上由于像素加倍,在非视网膜上更容易发现)我认为这是由于每个部分获得的空间量不太好造成的。 (300/13 = 23,0769)人们应该认为可拉伸(stretch)图像可以适应这一点,不是吗?分隔符的宽度正好是 1 像素,我将框架更改了 1 像素,因此两个分隔符应该恰好放置在彼此的顶部,这绝对不是这里的情况。
有谁能解释为什么会发生这种情况,以及更重要的是解决这个问题的方法吗?
最佳答案
默认情况下,所有坐标都是 float (实际上是 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 也具有整数坐标(在整个屏幕的坐标系中),它们往往看起来更清晰。
关于iphone - 正确定位拉伸(stretch)的 UIImages,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4197417/