我们可以在 iOS 6 自动布局生成的帧上产生 CGRectIntegral 的效果吗?

Posted

技术标签:

【中文标题】我们可以在 iOS 6 自动布局生成的帧上产生 CGRectIntegral 的效果吗?【英文标题】:Can we have the effect of CGRectIntegral on iOS 6 auto-layout generated frames? 【发布时间】:2012-11-30 22:25:29 【问题描述】:

ios 6 自动布局非常方便。但是,自动生成的帧可能具有非整数值。如何使用自动布局强制输出最终帧位置和大小的整数?

【问题讨论】:

IMO,你不应该首先编写以半像素结束的约束。 @CodaFi 很可能有一个约束导致半像素。例如,如果 view2 以 view1 为中心垂直居中,并且 view1 的高度为奇数,则 view2 的中心位于半像素上。 所以只要加一个就可以了! 如果您必须在这里和那里按像素调整每个容器以使其显示对齐的内容,那么自动布局似乎不是很有用。当您的应用从上到下自动布局并且内容仍然未对齐时会发生什么?你不应该为任何自动布局内容调整框架,我应该去我所有的用户那里并在他们的显示器上物理添加像素吗? 我认为这是一个错误。我希望在绘制之前所有坐标和尺寸都将四舍五入到最近的像素。这个问题不仅存在于自动布局中,也存在于手动布局中。带有width/3 的按钮将导致亚像素渲染按钮 - 模糊。 【参考方案1】:

AutoLayout 比你想象的更智能。

虽然自动生成的帧确实可以有小数值,但它们会四舍五入以匹配设备的像素比率。在配备 Retina 显示屏 (2x) 的设备上,允许使用 0.5 的分数。在较旧的设备上,似乎根本没有任何小数值。

这意味着您将始终获得像素完美的布局。

我花了很长时间才弄清楚这一点。 :)

【讨论】:

这不是真的——我在非视网膜设备上创建了布局,其中生成的帧具有小数值,因此会导致像素错位。就像在其容器中将视图居中一样简单。 @ArieLitovsky 在我的大量测试中,情况并非如此。你有例子吗? 请记住,如果它是连接到视网膜设备的非视网膜显示器,您仍然会在显示器上看到抗锯齿效果。 @AndreasLey 在尝试将NSTextFieldNSLayoutAttributeBaseline 与其父视图的NSLayoutAttributeCenterY 对齐时,我可以在非视网膜设备上系统地生成小数像素。 @Dalzhim 您是否以编程方式添加了此约束?超级视图也有基线吗? Apple 的 Pin 约束文档指出,Baseline 属性仅在您选择两个或多个项目并且都具有基线时可用。【参考方案2】:

除非您接受作为答案,否则我无法回答您的问题。

我在使用手动布局时遇到了类似的问题,而不是使用自动布局。我的解决方案可能对某人有用。

此代码会将坐标四舍五入到屏幕比例。换句话说,在标准显示上显示为整数,在 Retina 上显示为一半 (0.5; 1; 1.5; ...)。

CGFloat roundToScreen(CGFloat value) 
    CGFloat scale = [[UIScreen mainScreen] scale];
    CGFloat result = round(value * scale) / scale;
    // example value: 3.61
    // on standard display: 4
    // on Retina display: 3.5
    return result;

这里有一些CGRectCGPointCGSize 的辅助函数:Gist on GitHub

【讨论】:

以上是关于我们可以在 iOS 6 自动布局生成的帧上产生 CGRectIntegral 的效果吗?的主要内容,如果未能解决你的问题,请参考以下文章

自动布局:ViewDidAppear 中的帧大小不正确

自动布局:无法获取 UICollectionViewCell 子视图的帧大小

EaselJS 动画虽然基于当前帧的帧

在 iOS 6 中启用自动布局,在 < iOS6 中禁用自动布局

Flash中帧的类型有( )种。

XCode 6.0.1 ios 7 自动布局