按钮和自动布局:两件事……两个问题

Buttons and auto layout: two things... two problems

请看这张图片:

1' 问题:我想在 iPhone SE、8、8 Plus 和 X 中构建它,但我做不到。

2' 问题:我使用图像和文本插入将中心图像放在文本上方。更改 iPhone 设计并更改按钮的比例,是否也会更改文本和图像的排列?

谢谢。

UIImageViewUILabel 开头。将宽度(或高度)限制为您想要的值(稍后您将使用它来更改图像的大小)。在UIImageView中添加一个“宽高比约束”并适当地约束它(我使用了1:1的ratio/multiplier,你需要根据你的原始图像计算它

Select UIImageViewUILabel 并在 UIStackView

中“换行”

根据需要调整 UIStackView 的属性

我使用上面的方法允许文本或图像变大而不限制其他元素

好的,有趣的部分。复制并粘贴 UIStackView,将第二个 UIStackView 对齐到第一个下方,这样它就会生成一个“列”。 Select 两者都包裹在另一个 UIStackView

更新新属性 UIStackView...

同样,我的重点是允许每个组扩展而不限制另一个

现在我有一个容器,看起来像...

好的,现在复制这个新的 UIStackView 并粘贴它,对齐到后缘(这不重要,但它会更容易描述)- 这将给你一个 2x2 的网格。 Select 最上面的两个 UIStackView,然后再次包裹在另一个 UIStackView

再次,我将 UIStackView 属性修改为 AligmentCenterDistributionEqual Centering

好的,现在找点乐子。 Select三个UIImageView(个人而言,我使用top/left一个作为主人)并删除它们的约束(您可以使用“Selected View/Clear约束选项)

Select “clean” UIImageView 之一和 Control+ 拖动到“master” UIImageView 并添加宽度和身高限制,所以他们将等于主人的

提示-可以按住Command来select多个约束

重复其他两个“干净”UIImageViews

我知道将最顶部 UIStackView 约束到视图的中心,或者您可以以任何其他方式约束它,但这使它成为主要锚点。

好的,但是为什么呢?

好了,现在你只需要更新一个约束就可以更新所有的图片了!

试试吧。 Select“主人”UIImageView,找到它的 width 约束(您可能需要转到属性 sheet)并将其常量更改为其他内容。所有 UIImageView 都应该更新!

此时,我会将此约束绑定到 UIViewController,以便您可以在代码中修改它。

为什么要这样堆叠?

这是一个很好的问题,您的选择可能会有所不同,但是,我选择以这种方式构造它,这样如果文本值的宽度不同,各列将保持相互输入。

有没有更简单的方法?

哦,多么希望啊!好吧,这不是一个“坏”的解决方案,但它确实需要一些思考以及如何布局它并且不要问我如果文本被分成多行会发生什么 - 因为它不漂亮。

“不同”的方法可能是使用 UIView 或容器视图,然后尝试生成图像之间的约束(水平和垂直对齐)和约束图像之间的文本有意义的方式,但是很快就会变得非常复杂...

那么如何将它们与父视图对齐?这就是为什么我会使用 UIView 或容器视图,但随后它变得更加复杂,因为您需要停止 API 定义它自己的约束并确保您具有正确的约束顶部、底部、前缘和后缘

当文字 longer/shorter 然后是图像时会发生什么?!因此,如果您只有一些基本文本,那么上面的内容应该可以正常工作并且可以合理维护。

1' 问题:我想在 iPhone SE、8、8 Plus 和 X 中构建它,但我做不到。
=> 为什么?你有什么问题?
2':使用stackview 可以,但触摸时没有效果。您可以创建自定义按钮 class :

class ImageTopButton: UIButton
{
    override func layoutSubviews()
    {
        super.layoutSubviews()
        let size = self.frame.size
        let imageSize = self.imageView!.intrinsicContentSize
        let labelSize = self.titleLabel!.intrinsicContentSize

        let totalHeight = imageSize.height + labelSize.height
        let heightDiff = size.height - totalHeight
        let padding = heightDiff / 2
        let verticalPading:CGFloat = 10

        self.imageView!.center = CGPoint(x: size.width / 2, y: imageSize.height / 2 + padding - verticalPading/2)
        self.titleLabel!.center = CGPoint(x: size.width / 2, y: imageSize.height + padding + labelSize.height / 1.5 + verticalPading/2)
    }
}

您可以更改 verticalPading 并为 UIButton 设置 class ImageTopButton
1' 的任何值:


希望有用