Ios 视网膜问题:如何使UIView的宽度正好为1像素而不是2像素?

Ios 视网膜问题:如何使UIView的宽度正好为1像素而不是2像素?,ios,objective-c,Ios,Objective C,我知道我们是在点而不是像素上操作的,在大多数情况下这很方便,但我需要将UIView设置为1像素而不是2像素的高度。因此,如果您在InterFace builder中拖放一些UIView(分隔线),并将其设置为1px(点)的高度,那么它仍然看起来像视网膜屏幕上的2像素大小的线(在设备和模拟器上) 我知道视图中有contentScaleFactor属性,它显示的是视网膜(2.0f)还是非视网膜(1.0f)。看起来视图的值为1.0f,因此您需要从主屏幕检索该值: [UIScreen mainScree

我知道我们是在点而不是像素上操作的,在大多数情况下这很方便,但我需要将UIView设置为1像素而不是2像素的高度。因此,如果您在InterFace builder中拖放一些UIView(分隔线),并将其设置为1px(点)的高度,那么它仍然看起来像视网膜屏幕上的2像素大小的线(在设备和模拟器上)

我知道视图中有contentScaleFactor属性,它显示的是视网膜(2.0f)还是非视网膜(1.0f)。看起来视图的值为1.0f,因此您需要从主屏幕检索该值:

[UIScreen mainScreen].scale; 
这使我返回2.0f。现在,我添加了此分隔符视图的高度约束,添加了检查isRetina并将线条分割为正好1像素的方法:

- (void)awakeFromNib{

  [super awakeFromNib];

  CGFloat isRetina = ([UIScreen mainScreen].scale == 2.0f) ? YES : NO;

  if (isRetina) {

    self.separatorViewHeightConstraint.constant /= 2;
  }
}
这是可行的,我只是不确定使用0.5值是否是个好主意…

您可以这样做

self.separatorViewHeightConstraint.constant = self.separatorViewHeightConstraint.constant / [UIScreen mainScreen].scale;

是,将值设置为0.5是在视网膜上获得“真实”1px行的唯一方法

您的代码是有效的。使用0.5设置UIView的框架将根据需要工作,因为框架的参数是CGFloat。如果您希望在self.separator viewheightconstraint.constant以外的其他对象中使用以点为单位表示单个像素的CGFloat,则以下代码将起作用

CGFloat scaleOfMainScreen = [UIScreen mainScreen].scale;
CGFloat alwaysOnePixelInPointUnits = 1.0/scaleOfMainScreen;

要支持更新的3x显示器(如iPhone 6+),请使用以下代码:

UIScreen* mainScreen = [UIScreen mainScreen];
CGFloat onePixel = 1.0 / mainScreen.scale;
if ([mainScreen respondsToSelector:@selector(nativeScale)])
    onePixel = 1.0 / mainScreen.nativeScale;

遗憾的是,其他答案都不适用于iphone6plus

iphone6plus上不可能有1px行,因为屏幕在1242x2208中渲染,然后向下采样到1080x1920。有时你会得到一条几乎完美的1px线,有时这条线会完全消失


有关正确的解释,请参阅。

这在3倍显示器上不起作用,线宽有时为1px,但有时为2px,具体取决于其位置。@Aleph7您能解释一下什么时候会出现这种情况吗?啊,对不起,我没有注意到他使用的是
scale
而不是
nativeScale
。我可以确认这适用于2x和3x设备,以创建真正的“1像素”。谢谢。恐怕这在iPhone 6 Plus上不起作用,因为屏幕是在1242x2208中渲染的,然后向下采样到1080x1920。有时你会得到一条几乎完美的1px线,有时这条线会完全消失。这个方法已经在实际的iphone6plus上测试过了吗?有一种方法可以做到:@Quentin你指的是哪个答案?当浏览它们时,我只看到了使用屏幕比例因子的不同版本,正如我在链接中详细描述的那样,它永远不会起作用,虽然有时结果虽然不完美但可能是可以接受的。我成功地实现了NSLayoutConstraint子类technic
@implementation KBHairlineLayoutConstraint#pragma mark---(void)awakeFromNib{[super awakeFromNib];if(self.constant==1)self.constant=1/[UIScreen mainScreen].scale;}@end
正如链接文章中所解释的那样,该方法在6+上不起作用,并且无法回避这一事实。对于您正在做的事情,结果可能已经足够好了,但如果是这样的话,那么这纯粹是运气使然,因为如果线条的排列方式不同,那么它们的抗锯齿效果就会变得非常奇怪。实际上,我只在模拟器上进行了测试(