iOS自动布局未在底部固定空间显示按钮

Posted

技术标签:

【中文标题】iOS自动布局未在底部固定空间显示按钮【英文标题】:iOS auto layout not displaying button at fixed space from bottom 【发布时间】:2014-01-28 12:38:21 【问题描述】:

我想在距屏幕底部固定距离处显示一个按钮(下图中的蓝色方块)。

以下是限制条件:

在不同的模拟器上运行应用时,按钮显示在不同的位置。看看下面的图片,看看有什么区别。

iOS 6.1 和 4 英寸模拟器:

iOS 7 和 4 英寸模拟器:

iOS 6.1 和 3.5 英寸模拟器:

iOS 7 和 3.5 英寸模拟器上,此按钮不可见。即其origin.y 大于屏幕高度。

知道为什么会这样吗?

编辑:已编辑的约束(仍然无效)

更新:我可以缩小问题的范围。在情节提要中,我在主视图中有这个按钮和其他子视图。以编程方式,我将 mapView 添加到这个主视图,并将所有主视图的子视图添加到 mapView,如下所示。

// Add mapView to main view
mapView = ...;
[self.view addSubview:self.mapView];

// Remove subviews from main view
[self.button removeFromSuperview];
...

// Add subviews into mapView so that they are visible on map
[self.mapView addSubview:self.button];
...

现在,如果我注释上面的代码并运行应用程序,那么按钮会显示在正确的位置,但是上面的代码未注释我会遇到按钮错位的问题。

更新:这个问题的部分答案是以编程方式添加约束。我说的是部分,因为我有其他视图,以及这个按钮,它们可以正确显示。我在代码中没有他们的限制。因此,仍有一些东西需要探索。

【问题讨论】:

底部与什么对齐? @footyapps27 问题出在按钮的origin.y 值中,并且没有与按钮左/右对齐的视图。所有视图都在此按钮的上方或下方。 您是否使用 X-Code 5.x 进行设计? @footyapps27 是的,它的 5.0.2 Xcode 5 有一种方法可以预览 ios 6 中 Storyboard/XIB 的布局。当你这样做时,你会看到什么?您可能还需要上传一个精简的项目来表明您的问题。 【参考方案1】:

您将 Button 与底部布局指南对齐,这与我在这种情况下建议的将其对齐到 superview 的底部不同。将其与垂直布局指南对齐取决于 iOS6/7 以及是否允许视图控制器的内容位于导航栏/底栏下方。

将其与超级视图(容器)对齐可以解决您的问题。但是解决这个问题的正确方法是设置视图控制器的正确“扩展边缘”。我假设您在 iOS7 上启用了“顶栏下方”和“底栏下方”,这将解释偏移量。例如,禁用它们会模仿与 iOS6 相同的行为,并且您最终不会得到那些不同的偏移量。

这实际上取决于您的视图控制器(导航栏、底栏等)以及您如何设置视图控制器的“edgesForExtendedLayout”。

编辑: 打电话 [self.button removeFromSuperview];

不仅会从视图中移除按钮,还会移除您之前设置的所有约束!因此,您必须再次设置约束 - 手动或避免从其超级视图中删除按钮。我猜这就是为什么它在 Interface Builder 中看起来不错,但在运行时却搞砸了!

Documentation:

调用此方法会删除任何引用您的视图的约束 正在删除,或者引用您视图的子树中的任何视图 正在删除。

【讨论】:

我已经使用了self.edgesForExtendedLayout = UIRectEdgeNone;,我尝试从superview的底部而不是底部指南设置约束,但没有奏效。 您是否有任何不明确的布局规则,或缺少您所注意的约束?通常你可以在日志中找到一些相关的信息 另外,请比较 iOS 6.1 和 2 种不同屏幕尺寸设备的照片。 日志中没有自动布局问题。 根据您提供的信息很难弄清楚为什么这不起作用。也许还有另一个具有更高优先级的约束已被满足。对您的视图层次结构和其他约束有更多的了解会很有趣。我重新测试了按钮的约束,通过将内容扩展设置为“无”,它们在空白视图控制器上完美运行【参考方案2】:

当您以编程方式添加按钮时,您需要添加 以编程方式自动布局约束

Apple Doc for Autolayout

*** post

【讨论】:

我没有以编程方式添加按钮。 @Geek 此代码出现在您的问题中 - 它有什么作用? / 从主视图中移除子视图 [self.button removeFromSuperview]; ... // 将子视图添加到 mapView 中,以便它们在地图上可见 [self.mapView addSubview:self.button]; 好的。您正在谈论添加到 mapView。有没有办法复制约束而不是以编程方式重新添加? @Geek - 不,没有解决方法 - 理想的方法是通过代码使用一种方法,否则你会遇到一些难以修复的问题 好的。在这里,我没有 mapView 的选项。因为它是谷歌地图,所以我必须通过代码添加。我尝试通过调用self.button.constraints 来保存按钮的约束。但是这个属性只返回宽度和高度约束,而不是 x 和 y 原点值的其他 2 个约束。【参考方案3】:

由于您使用的是X-Code 5.0.2,默认情况下xib's 接口生成器会自动作为Retina 4 inch full screen 出现!!

尝试将 Attributes Inspector 中的内容更改为 Retina 3.5 inch full screen

然后相应地更改您的约束。

尝试更改此设置并查看需要如何更改 3.5 inch screen 的约束。

【讨论】:

我在 IB 中设置了view as iOS 6.1 and earlier。所以我看到的都是 3.5 英寸的屏幕。

以上是关于iOS自动布局未在底部固定空间显示按钮的主要内容,如果未能解决你的问题,请参考以下文章

如何使用自动布局将按钮放在屏幕底部

iOS 开发的大小类和自动布局

将 UILabel 固定到 UICollectionViewCell contentView 按钮的自动布局约束

iOS 视图高度和自动布局

自动布局降低某些视图的高度

iOS底部对齐具有编程自动布局约束的对象