正确定位拉伸的UIImage图像

4
我正在创建一个UISegmentedControl替代品,以便它可以与您自己的自定义图像一起使用。由于分隔符需要在两侧具有不同的颜色,因此我决定给中间项目两个边框。
现在要显示UISegmentedControl替代品,我计算了一个项目可用的宽度(frame.size.width / numberOfItems)。然后我创建了一个带有自定义背景图像(可拉伸的中间段图像)的UIButton。下一步是定位所有内容。因为当您选择一个项目时,1像素的分隔符需要可见,所以我给每个项目比实际应该有的大1像素的框架。因此,下一个项目向左重叠1像素。
segmentRect = CGRectMake(indexOfObject * (self.frame.size.width / numberOfSegments), 0, (self.frame.size.width / numberOfSegments) + 1, self.frame.size.height);

使用此结果,我获得了一个几乎完美的自定义UISegmentedControl (retina):alt text 现在看起来非常好,但是当添加更多/少的分段时,一切都会改变。顺便说一下,这是一个300像素宽的控件,所以每个段落占据25像素的空间。如果我将该数字更改为13,则会显示如下内容:alt text 请注意,“3”和“4”之间的轻微不同边框。(因为像素加倍,在非retina上更容易发现) 我认为这是由于每个段落得到的空间不太好造成的。(300 / 13 = 23.0769)应该认为可拉伸图像会适应此问题,对吗?分隔符的宽度恰好为1px,我将帧更改1px,因此两个分隔符应该被放置在彼此完全重合的位置,但实际情况绝对不是如此。
有人知道为什么会出现这种情况,更重要的是有没有办法解决这个问题?
4个回答

2
默认情况下,所有坐标都是浮点数(实际上是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也具有整数坐标(在整个屏幕的坐标系中),它们倾向于看起来更加清晰。


这正是我一直在寻找的!我不知道你可以将整数传递给它以防止使用抗锯齿。非常感谢。 - Cedric Vandendriessche

0

是的,我的猜测是UIView子类不喜欢不均匀的框架大小。我已经遇到过这种情况很多次了。如果您尝试使您的分段视图宽度为325像素,会发生什么情况?如果它修复了故障,那么您就有了答案 :)


当然,这解决了问题,因为帧大小是偶数。我想找出是否有可能使用其他方法来修复并获得相同的结果... - Cedric Vandendriessche
调整框架大小以适应段数怎么样?还是宽度必须保持不变? - samvermette
当某人使用这个组件并且想要一个300像素宽的控件时,最好选择那个尺寸的控件。如果他不能选择自己的框架尺寸,他的用户界面将不太好看。 - Cedric Vandendriessche

0

我成功地自己想出了一些东西。我将每个段落的宽度向下取整,这样中间的按钮看起来就可以了。然后我在第一个和最后一个按钮之间分配未使用的空间。(再次对第一个按钮进行四舍五入)


0

我不确定答案,我认为这可能与抗锯齿有关(在这种情况下我们无法更改)。 一种方法可能是:

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

这是我无法做到的事情。当点击它时,UIButton的完整框架变得可见。当边框完全对齐时,你不会注意到这一点。当你开始调整宽度时,你会在点击时看到它改变。 - Cedric Vandendriessche

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接