Ios 如何使用自动布局以动态高度居中视图

Ios 如何使用自动布局以动态高度居中视图,ios,swift,user-interface,autolayout,constraints,Ios,Swift,User Interface,Autolayout,Constraints,我试图以编程方式创建一个以指定的superview为中心的视图。我几乎可以实现这种行为,但是居中视图不尊重其内容的动态高度。以下是我创建的使其实现的函数: static func overlayWithButton(onView view: UIView, buttonText: String, theme: Theme = .dark, action: Action? = nil) -> UIView { // create overlay let overlay = U

我试图以编程方式创建一个以指定的superview为中心的视图。我几乎可以实现这种行为,但是居中视图不尊重其内容的动态高度。以下是我创建的使其实现的函数:

static func overlayWithButton(onView view: UIView, buttonText: String, theme: Theme = .dark, action: Action? = nil) -> UIView {
    // create overlay
    let overlay = UIView()
    overlay.translatesAutoresizingMaskIntoConstraints = false
    let leftInset: CGFloat = 20
    let rightInset: CGFloat = 20

    // Style overlay
    overlay.backgroundColor = theme == .dark ? UIColor.black : UIColor.white
    overlay.alpha = 0.75
    overlay.cornerRadius = 10

    // create button
    let button = UIButton(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
    button.translatesAutoresizingMaskIntoConstraints = false

    // Style Button
    button.backgroundColor = UIColor.clear
    button.setTitle(buttonText, for: .normal)
    button.setTitleColor(theme == .dark ? lightBlueButtonText : UIColor.black, for: .normal)
    button.titleLabel?.lineBreakMode = .byWordWrapping
    button.titleLabel?.textAlignment = .center
    button.titleLabel?.numberOfLines = 0
    button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 20)
    button.isEnabled = true

    // add button action
    if let action = action {
        button.add(for: .touchUpInside, action)
    }

    // add constraints
    overlay.addSubview(button)
    button.centerXAnchor.constraint(equalTo: overlay.centerXAnchor).isActive = true
    button.leftAnchor.constraint(greaterThanOrEqualTo: overlay.leftAnchor).isActive = true
    button.rightAnchor.constraint(lessThanOrEqualTo: overlay.rightAnchor).isActive = true

    button.topAnchor.constraint(equalTo: overlay.topAnchor).isActive = true
    button.bottomAnchor.constraint(equalTo: overlay.bottomAnchor).isActive = true

    view.addSubview(overlay)
    overlay.leftAnchor.constraint(equalTo: view.leftAnchor, constant: leftInset).isActive = true
    overlay.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -rightInset).isActive = true
    overlay.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true

    return overlay
}
这适用于短按钮标题: 但是,如果标题较长,则按钮内容会被剪裁: 使用reveal,我可以看到标题/按钮标签按预期响应。
我已经做了很长一段时间了,我无法让居中的覆盖层扩展其高度以匹配其内容的内在内容大小。有什么想法吗?

经过深入挖掘,发现问题是由于UIButton与其标签之间的一种奇怪的交互作用造成的。有关该特定问题的更多详细信息,请参阅。虽然没有一个最受欢迎的解决方案成功地帮助我解决了这个问题,但确实有一些解决方案帮了我的忙。解决方案在于创建覆盖intrinsicContentSize和LayoutSubView的UIButton子类。此子类的代码如下:

class LongTitleButton: UIButton {

    override var intrinsicContentSize: CGSize {
        return self.titleLabel?.intrinsicContentSize ?? super.intrinsicContentSize
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        if let titleLabel = titleLabel {
            titleLabel.preferredMaxLayoutWidth = titleLabel.frame.size.width
        }
    }

}

或者,因为这个问题似乎是特定于UIButton的,一个同样有效的替代解决方案是简单地使用UILabel而不是UIButton,在标签上放置一个UIGestureRecognitor。

我明白了你的问题,你不需要按照编程的方式获取所有内容并根据文本设置大小

这里我附上了一步一步的Guid,请按照这个。 步骤1:-在PopupView中使用一个视图(我们称之为PopupView)和一个标签作为子视图

步骤2:-将初始约束设置为PopupView和UILabel,如下所述

PopupView = LeadingConstrain(20) and TrialingConstrain(20) (From its Superview = mainview)
  UILabel = LeadingConstrain(10) and TrialingConstrain(10) (From its Superview =popupView)

第3步:-最棘手的-按鼠标右键,将弹出视图拖动到UILabel。现在,您需要按Shift键,然后单击顶部空间到容器,底部空间到容器

 PopupView Topspace to UILabel Top Space
 popupview BottomSpace to UILabel Bottom Space
 set UIlabe number of Line = 0 
 and LineBreak = WordwrapMode

步骤4:-现在将约束设置为PopupView并更新帧

Set Center Horizontally in Container
Set Center Vertically in Container

第5步:-在最后一步中,单击弹出视图。选择视图的“顶部约束”,并设置UILabel从顶部到视图的适当距离,并遵循底部的相同距离

第6步:-现在查看多台设备上短标签的预览

第7步:-现在在UILabel中添加长线文本,在模拟器中运行,并检查纵向和横向两种模式

我希望现在你的问题会清楚。如果您需要任何帮助,请随时发表评论


这里我还附上了演示供您参考,

您能将覆盖层的高度锚定设置为按钮的高度锚定吗?如果我这样做而不是顶部/底部锚定,我会得到相同的结果,如果我在顶部/底部锚之外再这样做,也会得到同样的结果。我怀疑这与TranslatesAutoResilizingMaskintoContrains摆脱UIButton的固有内容大小有关,但我需要将其设置为true,否则,应用于按钮的所有其他约束都不起作用。您是否正在调用
setNeedsLayout
layoutIfNeeded
?我应该在哪里进行这些调用?