简体   繁体   English

Swift以编程方式创建宽度百分比

[英]Swift make percentage of width programmatically

I am programmatically creating multiple buttons in Swift for a UITableViewCell, and would like to set their widths to be a certain percentage width of the UITableViewCell so that they use up all of the space. 我正在以编程方式在Swift中为UITableViewCell创建多个按钮,并且希望将它们的宽度设置为UITableViewCell的特定百分比宽度,以便它们耗尽所有空间。 Right now I am creating the buttons in a for loop (I want to be able to create a variable amount of buttons) and am using 现在我在for循环中创建按钮(我希望能够创建可变数量的按钮)并且正在使用

button.buttonWidth = self.contentView.frame.width / numberOfButtons

where button is a UIButton and self is a UITableViewCell and numberOfButtons is obviously the number of buttons. 其中button是UIButton,self是UITableViewCell,numberOfButtons显然是按钮的数量。 I have also tried: 我也尝试过:

button.buttonWidth = self.frame.size.width / numberOfButtons

and every combination of using/not using .size and using/not using contentView. 以及使用/不使用.size和使用/不使用contentView的每个组合。 These don't seem to work, however, as the buttons are too big. 然而,这些似乎不起作用,因为按钮太大了。 Anyone know how to accomplish this? 有谁知道怎么做到这一点?

NOTE: I CAN'T use Autolayout in the storyboard, as I'm creating a variable number of buttons. 注意:我不能在故事板中使用Autolayout,因为我正在创建可变数量的按钮。

You say: 你说:

NOTE: I CAN'T use Autolayout in the storyboard, as I'm creating a variable number of buttons. 注意:我不能在故事板中使用Autolayout,因为我正在创建可变数量的按钮。

You can't add the variable number of buttons right in Interface Builder, but there's nothing to stop you from using autolayout. 您无法在Interface Builder中添加可变数量的按钮,但没有什么可以阻止您使用autolayout。 The basic autolayout constraints you need to set up are: 您需要设置的基本自动布局限制是:

  • Set buttons to have same width; 将按钮设置为具有相同的宽度;
  • Set buttons to have their leading constraint connected to the previous button's trailing constraint; 设置按钮使其前导约束连接到前一个按钮的尾随约束;
  • The first button should have its leading constraint connected to the container view; 第一个按钮应该将其前导约束连接到容器视图; and
  • The last button should have its trailing constraint connected to the container, too. 最后一个按钮也应该将其尾部约束连接到容器。

So, for example, in Swift 3, you could do something like: 因此,例如,在Swift 3中,您可以执行以下操作:

var previousButton: UIButton?
for _ in 0 ..< count {
    let button = ...
    button.translatesAutoresizingMaskIntoConstraints = false            
    view.addSubview(button)

    // if no "previous" button, hook leading constraint to its superview;
    // otherwise hook leading constraint and width to previous button

    if previousButton == nil {
        button.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 5).isActive = true
    } else {
        NSLayoutConstraint.activate([
            button.leadingAnchor.constraint(equalTo: previousButton!.trailingAnchor, constant: 5),
            button.widthAnchor.constraint(equalTo: previousButton!.widthAnchor, constant: 5)
        ])
    }

    // add vertical constraints

    NSLayoutConstraint.activate([
        button.topAnchor.constraint(equalTo: view.topAnchor, constant: 50),
        view.bottomAnchor.constraint(equalTo: button.bottomAnchor, constant: 5)
    ])

    previousButton = button
}

// make sure to hook last button's trailing anchor to superview, too

view.trailingAnchor.constraint(equalTo: previousButton!.trailingAnchor, constant: 5).isActive = true

Or, in Swift 2: 或者,在Swift 2中:

var previousButton: UIButton?
for _ in 0 ..< buttonCount {
    let button = ...
    button.translatesAutoresizingMaskIntoConstraints = false            
    view.addSubview(button)

    // if no "previous" button, hook leading constraint to its superview;
    // otherwise hook leading constraint and width to previous button

    if previousButton == nil {
        button.leadingAnchor.constraintEqualToAnchor(view.leadingAnchor, constant: 5).active = true
    } else {
        NSLayoutConstraint.activateConstraints([
            button.leadingAnchor.constraintEqualToAnchor(previousButton!.trailingAnchor, constant: 5),
            button.widthAnchor.constraintEqualToAnchor(previousButton!.widthAnchor, constant: 5)
        ])
    }

    // add vertical constraints

    NSLayoutConstraint.activateConstraints([
        button.topAnchor.constraintEqualToAnchor(view.topAnchor, constant: 5),
        view.bottomAnchor.constraintEqualToAnchor(button.bottomAnchor, constant: 5)
    ])

    previousButton = button
}

// make sure to hook last button's trailing anchor to superview, too

view.trailingAnchor.constraintEqualToAnchor(previousButton!.trailingAnchor, constant: 5).active = true

And, instead of fixed spacing between the buttons, you also could use UILayoutGuide , too (making the guides the same size as each other but a percent of the width of the buttons, achieving a more natural spacing regardless of the width of the superview). 并且,除了按钮之间的固定间距,您也可以使用UILayoutGuide (使导轨的尺寸彼此相同但是按钮宽度的百分比,无论超视图的宽度如何都能实现更自然的间距) 。

You also can use UIStackView , which is another great way to get controls evenly spaced in a view. 您还可以使用UIStackView ,这是另一种在视图中均匀分布控件的好方法。

Bottom line, there are many ways to achieve this using autolayout. 最重要的是,有很多方法可以使用autolayout实现这一目标。

Maybe because you're doing this before the cell layouts its subviews and it's size is the same as size set in Any-Any size class 600 * 600. 也许是因为您在单元格布局其子视图之前执行此操作,并且它的大小与Any-Any size class 600 * 600中设置的大小相同。

Try doing adding your buttons in layoutSubviews method, like this: 尝试在layoutSubviews方法中添加按钮,如下所示:

override func layoutSubviews() {
    super.layoutSubviews()
    self.layoutIfNeeded()

    // add your buttons here

}

Hi there is multiple ways of solving your problem: 您好,有多种方法可以解决您的问题:

  1. Using Autolayout, you can using Autolayout in code and in StoryBoard ;-). 使用Autolayout,您可以在代码和StoryBoard中使用Autolayout ;-)。 Bear with me, I didn't check the code of Autolayout but the logic is here… 忍受我,我没有检查Autolayout的代码,但逻辑在这里......

     let button1: UIButton!, button2: UIButton!, button3: UIButton! convenience init() { self.init(frame:CGRectZero) contentView.addSubview(button1) contentView.addSubview(button2) contentView.addSubview(button3) button1.translatesAutoresizingMaskIntoConstraints = false button2.translatesAutoresizingMaskIntoConstraints = false button3.translatesAutoresizingMaskIntoConstraints = false addConstraint( item: button1, attribute: .Left, relatedBy: .Equal, toItem: self, attribute: .Left, multiplier: 1, constant: 8) ) addConstraint( item: button2, attribute: .Left, relatedBy: .Equal, toItem: button1, attribute: .Right, multiplier: 1, constant: 8) ) addConstraint( item: button1, attribute: .Left, relatedBy: .Equal, toItem: button2, attribute: .Right, multiplier: 1, constant: 8) } 

Source: https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/ProgrammaticallyCreatingConstraints.html https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/ 资料来源: https//developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/ProgrammaticallyCreatingConstraints.html https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/

  1. Using Snapkit 使用Snapkit

     let button1: UIButton!, button2: UIButton!, button3: UIButton! override init(style: UITableViewCellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) button1 = UIButton() button1.setTitle("Button 1", forState: .Normal) contentView.addSubview(button1) button1.snp_makeConstraints { (make) in make.bottom.equalTo(contentView.snp_botton) make.left.equalTo(contentView.snp_left) make.height.equalTo(20) } button2 = UIButton() button2.setTitle("Button 2", forState: .Normal) contentView.addSubview(button2) button2.snp_makeConstraints { (make) in make.bottom.equalTo(contentView.snp_botton) make.left.equalTo(button2.snp_right) make.height.equalTo(20) } button1 = UIButton() button1.setTitle("Button 3", forState: .Normal) contentView.addSubview(button2) button1.snp_makeConstraints { (make) in make.bottom.equalTo(contentView.snp_botton) make.left.equalTo(button2.snp_right) make.height.equalTo(20) } } 

Source: http://snapkit.io/docs/ 资料来源: http//snapkit.io/docs/

My preferred version is Snapkit because it is less verbose than Autolayout. 我首选的版本是Snapkit,因为它比Autolayout更简洁。

UIStackView is exactly what you need. UIStackView正是您所需要的。 Check out my tutorial below: 看看我的教程如下:

http://www.raizlabs.com/dev/2016/04/uistackview/ http://www.raizlabs.com/dev/2016/04/uistackview/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM