【问题标题】:How do I programatically resize a UIButton that already has constraints?如何以编程方式调整已经有约束的 UIButton 的大小?
【发布时间】:2016-01-24 11:59:04
【问题描述】:

我有一个 UIButton,我已将其设置为距视图左侧 8 点和距视图底部 8 点。我目前将宽度和高度设置为 >= 32 点。

但是,我希望按钮在更大的显示器上更大。我想出了如何设置约束,以便按钮始终处于相同的纵横比(在我的情况下为正方形)并且始终为其父视图宽度的 10%,但这意味着当设备旋转时,按钮会变得越来越小随着视野越来越宽,我不希望那样。我希望它是最短边的 10%。

在封闭的 ViewController 代码中很容易得到我想要的宽度:

let buttonWidth = 0.1 * (self.view.bounds.width < self.view.bounds.height ? self.view.bounds.width : self.view.bounds.height)

但是我如何正确地将它应用到按钮上,以及情节提要中应该设置哪些约束?整个界面当前在情节提要中定义。

我是否直接更新边界?约束?多重约束?在约束的情况下,我完全不熟悉如何在代码中处理它们。

【问题讨论】:

    标签: ios swift uibutton autolayout


    【解决方案1】:

    如果你的按钮有约束,你需要通过这种方式找到它:

    button.superview?.constraints.forEach { constraint in
      if constraint.firstItem === button &&
         constraint.firstAttribute == .width {
         constraint.constant = 20
         return
      } 
    }       
    self.view.layoutIfNeeded() 
    

    或者您可以为您的约束创建一个 IBOutlet 并更改它的常量。

    【讨论】:

      【解决方案2】:

      仅使用情节提要无法实现您想要的,因为您想选择屏幕最小的一侧并获得其中的 10%。在代码中你可以很容易地做到这一点。

      1. 首先,您需要设置宽度约束的 IBOutlet。 See this answer for detailed explanation
      2. 然后根据计算的大小更改 IBOutlet 宽度约束的常数。只要您的纵横比为 1:1,它就会自动将高度更改为宽度。


      let buttonWidth = 0.1 * min(self.view.bounds.width, self.view.bounds.height)
      
      self.yourWidthConstraint.constant = buttonWidth
      
      self.view.layoutIfNeeded()
      

      【讨论】:

      • 啊哈!没有意识到您可以将 constraint 设为 IBOutlet。我会试一试的。
      • 完美!易于实施并完全满足我的需求。
      • @zkarj 我很高兴它对你有用,享受:)
      • 第一行可以是:let buttonWidth = 0.1 * min(self.view.bounds.width, self.view.bounds.height)
      • 是的@kientux 更短的版本。但我只是选择展示如何通过代码修改约束。我没有优化现有代码。不过会更新答案。
      【解决方案3】:

      编辑:如果您想在设备旋转时保持相同的宽度/高度,请忘记故事板中的宽度限制(但保持宽高比为 1)。像这样以编程方式创建宽度约束:

      override func viewDidLoad() {
          super.viewDidLoad()
          // Do any additional setup after loading the view, typically from a nib.
      
          // Equivalent: Width of self.button equals 0.1 * width of self.view
          let widthConstraint = NSLayoutConstraint(item: self.button,
                                              attribute: NSLayoutAttribute.Width,
                                              relatedBy: NSLayoutRelation.Equal,
                                                 toItem: nil,
                                              attribute: NSLayoutAttribute.NotAnAttribute,
                                             multiplier: 1.0,
                                               constant: 0.1 * CGRectGetWidth(self.view.bounds))
      
          self.view.addConstraint(widthConstraint)
          self.view.layoutIfNeeded()
      }
      

      如果您创建宽度约束和纵横比约束,它不会变得越来越宽。

      Ctrl + 拖动按钮到内容视图,然后选择等宽。然后使用 multiplier = 0.1 编辑该约束。所以你的按钮宽度总是等于设备宽度的 10%。

      然后创建一个纵横比约束,按钮不会变窄。

      【讨论】:

      • 肯定会?无论整体尺寸如何,纵横比都将控制按钮的形状。宽度约束将始终应用于包含视图的宽度,它会在旋转时改变大小。还是我错过了什么?
      • 是的,它会改变尺寸,但不会变窄。那是你要的吗?如果要保持相同的大小,则需要以编程方式创建宽度约束(但可以在情节提要中创建纵横比)。我会更新我的答案。
      • 我的目标是在旋转时保持大小相同。您更新的答案将完成这项工作,但我喜欢在情节提要中添加约束以使其满意然后在代码中进行修改的方法。不过,感谢您提供完整的示例 - 以后可能会对更复杂的情况或其他情况有用。
      【解决方案4】:

      我认为您应该探索 Apple 的 size classes API。您可以在 Interface Builder 中为所有特定情况设置按钮的约束,即更小和更大的设备、纵向和横向。

      更多详情:About Designing for Multiple Size Classes

      【讨论】:

      • 我同意尺寸等级是事实上的方法,但是我无法想象它们在这种情况下会如何工作。我希望按钮在大屏幕上大,在小屏幕上小。如果我将大小约束与大小类联系起来,则类可以通过简单的设备旋转而改变。如果我将它绑定到宽度紧凑而不是宽度常规,现在就可以了,它不会在任何现有设备上改变。但展望未来,它似乎不是一种确定性的方法——尽管也许我的要求是它落在哪里。编辑:实际上,6 Plus 和 6S Plus 确实发生了变化。
      • 您的评论不清楚。您可以在具有尺寸等级的特定设备上为两个方向指定相同的按钮尺寸。 “确定性”?你打算如何确定未来要发布的硬件的屏幕尺寸?
      • 忽略我对“确定性”这个词的使用——我认为我过度使用了它。 :-)
      • 我可以为给定的尺寸类指定一个 absolute 按钮尺寸,但我希望它与视图的尺寸相关,因此我必须将其绑定到旋转时将改变其绝对大小的视图。比较横向 iPhone 6 Plus 和横向 iPad。两者都是常规宽度,但尺寸(以磅为单位)大不相同。
      【解决方案5】:

      试试这个:

      your_button.frame.size.width = buttonWidth
      

      或者您可以添加/更改约束:

      let widthConstraint = NSLayoutConstraint (item: your_button, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: buttonWidth)
      your_button.view.addConstraint(widthConstraint)
      

      【讨论】:

        猜你喜欢
        • 2017-03-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-08
        • 1970-01-01
        • 2015-04-13
        • 2011-07-08
        相关资源
        最近更新 更多