【问题标题】:How to center view with dynamic height using auto layout如何使用自动布局以动态高度居中视图
【发布时间】:2018-02-22 16:22:28
【问题描述】:

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

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
}

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

【问题讨论】:

  • 你能否将叠加层的高度锚设置为按钮的高度锚?
  • 如果我这样做而不是顶部/底部锚点,我会得到相同的结果,如果我这样做除了顶部/底部锚点之外,也会得到相同的结果。
  • 我怀疑这与 translatesAutoResizingMaskIntoContraints 摆脱了 UIButton 的固有内容大小有关,但我需要将其设置为 true,否则应用于按钮的所有其他约束都不会'不行。
  • 你在打电话给setNeedsLayoutlayoutIfNeeded吗?
  • 我应该在哪里打这些电话?

标签: ios swift user-interface autolayout constraints


【解决方案1】:

经过大量挖掘,发现问题出在 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。

【讨论】:

    【解决方案2】:

    我遇到了您的问题,您不需要以编程方式获取所有内容并根据您的文本设置大小。

    这里我附上了分步指南,请按此操作。

    Step 1 :- 在 PopupView 中取一个 View(我们称之为 PopupView)和一个 Label 作为 Subview。

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

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

    第 3 步:- 最棘手的 - 按鼠标右键 并将 PopUpview 拖到 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
    

    Step 5 :- 在 ThNe Last Step 中,点击 PopupView 。选择 Top Constrain of view 并将 UILabel 的 Aprroproate Distance 设置为 View from top 并 Follow 同样的 Bottom。

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

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

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

    这里我还附上演示供您参考,UILabel with Center Dynamic Height

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-07
      • 1970-01-01
      • 1970-01-01
      • 2014-01-03
      • 1970-01-01
      相关资源
      最近更新 更多