【问题标题】:How to programmatically increase the height of UIView with Swift如何使用 Swift 以编程方式增加 UIView 的高度
【发布时间】:2017-08-18 00:31:30
【问题描述】:

在 IB 内部,我有一个带有 segmentedControl 和 2 个 containerViews 的 viewController。在每个 containerView 中我都有一个 tableView。从每个 tableView 我推送一个 detailView。我的自动布局在 IB 中。

一旦我选择了一个段,我就会看到相应的 tableView,我选择一个单元格,正确的 detailView 就会被推送到场景中。

问题是一旦将 detailView 推送到 segmentedControl 上仍然可见。我决定隐藏有效的分段控制,但那里有一个很大的空白空间。我试图以编程方式增加 detailView 视图的大小,但它没有扩大。从我读到的内容来看,这是因为我在情节提要中设置了初始约束。

如何以编程方式扩展 detailView 的视图?

代码:

DetailViewController: UIViewController{

override func viewDidLoad() {
        super.viewDidLoad()

 //this isn't increasing the view's size
 self.view.frame.size.height += 20.0

 //doesn't work. I get an error on the last argument
 self.view.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height += 20.0)

 //doesn't work. I get an error on the last argument
 self.view.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.size.height += 20.0)
 }

}

错误:

//Error for the last argument- height: *self.view.frame.height += 20.0*
self.view.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height += 20.0)

变异运算符的左侧不可变:'height' 是 get-only 属性

//Error for the last argument- *self.view.frame.size.height += 20.0*:
self.view.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.size.height += 20.0)

无法使用参数列表为“CGRect”类型调用初始化程序 type '(x: Int, y: Int, width: CGFloat, height: ())'

【问题讨论】:

    标签: ios swift xcode uiview constraints


    【解决方案1】:

    您需要为详细视图的高度约束创建一个出口,然后您可以像myHeightConstraint.constant += extraHeight 这样以编程方式调整高度,其中extraHeight 是一个数字,表示您希望详细视图有多高。之后您可能还需要致电self.view.layoutIfNeeded()

    要从约束创建出口,请控制从情节提要编辑器中的约束拖动(就像您对 UIView 的出口一样)到您的代码中。

    您是对的 - 因为您使用的是自动布局和约束,所以也需要使用约束进行调整。设置原始帧可能会导致意外行为。如果您有任何其他问题或困难,请告诉我。

    【讨论】:

      【解决方案2】:

      CGRect 初始化器中,您不应使用 +=,而应使用 +

      变化:

      self.view.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height += 20.0)
      

      到:

      self.view.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height + 20.0)
      

      您不应该尝试在初始化程序中更改 self.view.frame.height 的值。

      【讨论】:

      • 感谢您的帮助。错误消失了,但视图没有增加。
      • 您的视图设置是否带有约束?
      • 是的。但是约束是在情节提要中设置的。我将编辑问题,包括隐藏了 segmentedControl 的布局的 3D 镜头,你会看到我想增加视图的大空白空间
      • 您的问题是关于现在已解决的错误。如果需要,您应该创建一个新问题来处理您的新问题(在您首先进行大量研究之后)。但是我相信你的限制会导致试图改变框架的问题。
      • 我明白你的意思,错误已解决,但高度没有增加。无论如何我都赞成你的答案,因为它纠正了错误。不过还是谢谢:)
      【解决方案3】:

      斯威夫特 4.2

      我以编程方式为您创建了一个示例:

          var flowHeightConstraint: NSLayoutConstraint?
      
          override func viewDidLoad() {
              super.viewDidLoad()
              view.backgroundColor = .white
      
              view.addSubview(button)
              button.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
              button.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
              button.widthAnchor.constraint(equalToConstant: 100).isActive = true
              flowHeightConstraint = button.heightAnchor.constraint(equalToConstant: 30)
              flowHeightConstraint?.isActive = true
          }
      
          @objc func animateButtonTapped() {
              UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.5, options: .curveEaseOut, animations: {
                  self.flowHeightConstraint?.constant = 100
                  self.view.layoutIfNeeded()
              }, completion: nil)
          }
      
          lazy var button: UIButton = {
             let button = UIButton()
              button.translatesAutoresizingMaskIntoConstraints = false
              button.backgroundColor = .green
              button.addTarget(self, action: #selector(animateButtonTapped), for: .touchUpInside)
              return button
          }()
      

      这行代码创建了一个按钮,点击时改变按钮的高度并带有动画。

      希望对您有所帮助:)

      【讨论】:

      • 我必须说你解决了我遇到的一个非常有趣的问题。但现在我明白为什么了。一旦你在一个对象上设置了一个激活的约束,你就不能再次设置它,因为它只会产生另一个约束并且两者会发生冲突。但是,您可以将约束分配给变量然后对其进行更改。再次感谢你你是我的救主
      【解决方案4】:

      对我来说,程序化解决方案不需要我为我可能想要修改的每个高度约束创建一个出口。这是一个非常适合我的纯代码解决方案。无论原始约束是在情节提要上创建还是以编程方式创建,它都应该起作用。如果需要,它还提供了一个动画变化的选项——尽管我不确定如果视图嵌套在复杂的层次结构中这是否可行。

      extension UIView {
          func setHeight(_ h:CGFloat, animateTime:TimeInterval?=nil) {
      
              if let c = self.constraints.first(where: { $0.firstAttribute == .height && $0.relation == .equal }) {
                  c.constant = CGFloat(h)
      
                  if let animateTime = animateTime {
                      UIView.animate(withDuration: animateTime, animations:{
                          self.superview?.layoutIfNeeded()
                      })
                  }
                  else {
                      self.superview?.layoutIfNeeded()
                  }
              }
          }
      }
      

      【讨论】:

        【解决方案5】:

        是否为 segmentedControl 设置了任何高度限制,如果有,您可能希望在加载详细视图时删除它们

        【讨论】:

        • 选择分段控件时如何去掉UIView的高度限制?兄弟@Joe
        【解决方案6】:

        使用 self.view.frame.size.height = 80

        【讨论】:

        • 这实际上不起作用,因为size.height 是一个只能获取的属性。
        • 如果这条线不起作用,请告诉我。这将根据需要改变您的身高
        • 它适用于边界,例如 myview.bounds.size.height = 100 ....!!!
        • @EmreA frame.height 是 get-only 属性,size.height 不是,不知道为什么这个答案确实有效。
        猜你喜欢
        • 1970-01-01
        • 2011-04-08
        • 2017-12-29
        • 2017-03-17
        • 2020-07-28
        • 1970-01-01
        • 2014-02-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多