用Autolayout实现按钮的网格布局

时间:2014-02-16 20:22:37

标签: ios autolayout

我正在尝试实现与Apple的内置计算器应用程序非常相似的按钮布局: Closeup of calc application

我正在使用自动布局来定位按钮,并在每个按钮上绘制0.5px边框,目标是在按钮之间产生1px的间隙(例如calc app,特写显示上面的像素,来自视网膜设备)。

边框适用于:

    btn.layer.borderWidth=0.5f;
    btn.layer.borderColor=[[UIColor blackColor] CGColor];

并使用Interface Builder设置布局。

app screenshot

它几乎可以工作;但是按钮之间的间隙存在一些差异 - 例如“1,2,3,直通”行和“4,5,6和”行之间的间隙是2像素,但是“7”之间的差距,8,9“和”cl,0,@“行只有一个像素。

约束是:

  • 顶部黑色区域具有固定高度
  • 所有按钮高度相同
  • 在数字行中,数字按钮设置为相同的宽度,THRU,AND,ALL OFF和ENTER按钮设置为相同的固定宽度
  • 顶行按钮固定在黑色区域底部,底行固定在superview底部 在IB中,按钮都是相互对接的。

在界面构建器中和运行时,我没有看到任何自动布局错误;并且autolayout信息的调试器转储给了我:

po [[UIWindow keyWindow] _autolayoutTrace]

*<UIWindow:0x10908a560> - AMBIGUOUS LAYOUT
|   *<UILayoutContainerView:0x109136140>
|   |   *<UINavigationTransitionView:0x10908ef80>
|   |   |   *<UIViewControllerWrapperView:0x109138870>
|   |   |   |   *<UIView:0x1090e6d10>
|   |   |   |   |   *<UILabel:0x1090d5bb0>
|   |   |   |   |   *<UIButton:0x1090d27e0>
|   |   |   |   |   |   <UIButtonLabel:0x1091c9190>
|   |   |   |   |   *<UIButton:0x1090844c0>
|   |   |   |   |   |   <UIButtonLabel:0x1091c7990>
|   |   |   |   |   *<UIButton:0x109088b60>
|   |   |   |   |   |   <UIButtonLabel:0x1091c6190>
|   |   |   |   |   *<UIButton:0x1090e2ce0>
|   |   |   |   |   |   <UIButtonLabel:0x1091c4990>
|   |   |   |   |   *<UIButton:0x1090e4e50>
|   |   |   |   |   |   <UIButtonLabel:0x1091c3190>
|   |   |   |   |   *<UIButton:0x1090db730>
|   |   |   |   |   |   <UIButtonLabel:0x1091c1990>
|   |   |   |   |   *<UIButton:0x109068f50>
|   |   |   |   |   |   <UIButtonLabel:0x1091c0190>
|   |   |   |   |   *<UIButton:0x10906db80>
|   |   |   |   |   |   <UIButtonLabel:0x1091be990>
|   |   |   |   |   *<UIButton:0x1090d23a0>
|   |   |   |   |   |   <UIButtonLabel:0x1091bd190>
|   |   |   |   |   *<UIButton:0x1090c8520>
|   |   |   |   |   |   <UIButtonLabel:0x1091bb990>
|   |   |   |   |   *<UIButton:0x1090c9090>
|   |   |   |   |   |   <UIButtonLabel:0x1091ba190>
|   |   |   |   |   *<UIButton:0x1090c5680>
|   |   |   |   |   |   <UIButtonLabel:0x1091b8990>
|   |   |   |   |   *<UIButton:0x1090d7fa0>
|   |   |   |   |   |   <UIButtonLabel:0x1091b7190>
|   |   |   |   |   *<UIButton:0x1090cc820>
|   |   |   |   |   |   <UIButtonLabel:0x1091b5990>
|   |   |   |   |   *<UIButton:0x10909dda0>
|   |   |   |   |   |   <UIButtonLabel:0x1091b4190>
|   |   |   |   |   *<UIButton:0x1090c8090>
|   |   |   |   |   |   <UIButtonLabel:0x1091b2990>
|   |   |   |   |   *<UIButton:0x1090c8e30>
|   |   |   |   |   |   <UIButtonLabel:0x1091b1190>
|   |   |   |   |   *<UIButton:0x1090d5390>
|   |   |   |   |   |   <UIButtonLabel:0x1091af990>
|   |   |   |   |   *<UIButton:0x10d30d260>
|   |   |   |   |   |   <UIButtonLabel:0x1091ae190>
|   |   |   |   |   *<UIButton:0x10909a6a0>
|   |   |   |   |   |   <UIButtonLabel:0x1091ac990>
|   |   |   |   |   *<UIButton:0x1090cca40>
|   |   |   |   |   |   <UIButtonLabel:0x109161160>
|   |   |   |   |   *<UIButton:0x10d30ea90>
|   |   |   |   |   |   <UIButtonLabel:0x109156460>
|   |   |   |   |   *<UIButton:0x1090da9e0>
|   |   |   |   |   |   <UIButtonLabel:0x109177ad0>
|   |   |   |   |   *<_UILayoutGuide:0x1090e6dd0> - AMBIGUOUS LAYOUT
|   |   |   |   |   *<_UILayoutGuide:0x1090ce080> - AMBIGUOUS LAYOUT
|   |   <UINavigationBar:0x10907da60>
|   |   |   <_UINavigationBarBackground:0x109087240>
|   |   |   |   <_UIBackdropView:0x1090899f0>
|   |   |   |   |   <_UIBackdropEffectView:0x10908b110>
|   |   |   |   |   <UIView:0x10908bbb0>
|   |   |   |   <UIImageView:0x1090877a0>
|   |   |   <UINavigationItemView:0x10916bc30>
|   |   |   |   <UILabel:0x10917f810>
|   |   |   <UINavigationItemButtonView:0x1090ee060>
|   |   |   |   <UILabel:0x1090ee5d0>
|   |   |   <_UINavigationBarBackIndicatorView:0x109098c80>

任何人都可以提供有关如何使用Autolayout实现像素完美“布局的任何提示吗?或者我应该以编程方式进行此操作吗?

2 个答案:

答案 0 :(得分:4)

在视图边界内绘制图层边框,因此您不会看到按钮之间的“间隙”,而是两个边框相互邻接的效果。这在非视网膜模拟器或设备中不起作用,因为它无法绘制半像素,而Autolayout不会在半像素上对齐视图。

对于像上面这样的布局,我会给按钮一个固定的高度(或一个按钮,让其他按钮相等)并让黑色视图占据剩余的空间。最好在全屏布局中至少有一个(理想情况下,恰好一个)可变元素,基本上可以覆盖舍入误差。

此刻听起来就像你有一个固定元素(黑色视图),按钮基本上是“取剩余高度并在它们之间划分”,这只有在剩余高度完全分开时才有效。

答案 1 :(得分:1)

我试图在视图之间设置等于0.5的水平/垂直空间。父视图的颜色充当边框颜色。它在IB中看起来很丑陋,它无法正确布局视图,但设备上的结果布局看起来很完美。

在界面构建器中:

in interface builder

在模拟器上:

on device

约束有点棘手。对于每一行

  • 设置第一个按钮的高度
  • 为所有按钮设置相等的高度
  • 为所有按钮设置相等的宽度(对于带有橙色按钮的行,略有不同)
  • 对齐所有按钮的上边缘
  • 对齐所有按钮的底边
  • 将所有按钮(包括空格到superview)之间的前导和尾随空格设置为0.5
  • 将第一个按钮的顶部空间(到前一行)设置为0.5

您可以一次对多个项目应用约束。要在按钮之间应用前导/尾随空格,请在应用之前按所需顺序放置它们。