如何使用自动布局使动态高度居中

时间:2017-09-13 20:27:37

标签: ios swift user-interface autolayout constraints

我尝试以编程方式创建一个位于指定超级视图中心的视图。我几乎可以实现这种行为,但是居中的视图不尊重其内容的动态高度。以下是我为实现这一目标而创建的功能:

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
}

这适用于短按钮标题: it works! 但是,如果标题较长,则会剪切按钮内容: enter image description here 使用显示我可以看到标题/按钮标签按预期响应。 it does not work 我已经有很长一段时间了,而且我无法获得居中的叠加层以扩展其高度以匹配其内容的内在内容大小。有什么想法吗?

2 个答案:

答案 0 :(得分:0)

经过大量挖掘,结果证明问题是由于UIButton与其标签之间的时髦交互。有关该特定问题的详细信息,请参阅this stack overflow post。虽然最高投票的解决方案都没有成功帮助我解决问题,但a solution further down确实有所帮助。解决方案在于创建一个覆盖intrinsicContentSize和layoutSubviews的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,而是在标签上放置UIGestureRecognizer。

答案 1 :(得分:0)

我遇到了你的问题,你不需要以编程方式采取所有方法,并根据你的文字设置大小。

这里我已经附上了一步一步的指导,请关注此事。

步骤1: - 在PopupView中将一个视图(我们称之为PopupView)和一个标签作为子视图。

enter image description here

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

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

enter image description here

第3步: 最棘手 - 按鼠标右键并将PopUpview拖到UILabel.Now您需要按Shift键键和点击顶部空间到容器和底部空间到容器 ..

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

enter image description here

第4步: - 现在将限制设置为PopupView和更新帧。

Set Center Horizontally in Container
Set Center Vertically in Container

enter image description here

步骤5: - 在ThNe Last Step中,单击PopupView。选择Top Toprain of view并将UILabel的Aprroproate距离设置为从顶部查看,并按下相同的底部。

enter image description here

第6步: - 现在请参阅预览多个设备上的短标签。

enter image description here

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

enter image description here

我希望你的问题能够得到解决。如果您需要任何帮助,请随时在评论中提问。

此处我还附上了参考演示,UILabel with Center Dynamic Height