Swift以编程方式制作宽度百分比

Posted

技术标签:

【中文标题】Swift以编程方式制作宽度百分比【英文标题】:Swift make percentage of width programmatically 【发布时间】:2016-05-03 13:50:02 【问题描述】:

我以编程方式在 Swift 中为 UITableViewCell 创建多个按钮,并希望将它们的宽度设置为 UITableViewCell 的某个百分比宽度,以便它们占用所有空间。现在我正在 for 循环中创建按钮(我希望能够创建可变数量的按钮)并且正在使用

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

其中 button 是 UIButton 而 self 是 UITableViewCell 而 numberOfButtons 显然是按钮的数量。我也试过:

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

以及使用/不使用 .size 和使用/不使用 contentView 的每种组合。然而,这些似乎不起作用,因为按钮太大了。有谁知道如何做到这一点?

注意:我不能在情节提要中使用自动布局,因为我正在创建可变数量的按钮。

【问题讨论】:

你不能使用自动布局的理由是无效的,你绝对可以使用它,你不能做的是在故事板或xib中指定约束... 你说得对——这就是我的意思,就是我不能使用情节提要。不过,我不知道如何以编程方式使用自动布局,所以如果有人可以以编程方式使用自动布局来回答,我会很高兴。我不想要有人向我展示如何在情节提要中使用自动布局,这就是我到目前为止所看到的一切。我将编辑问题 以编程方式自动布局:developer.apple.com/library/ios/documentation/UserExperience/…。您也可以将水平UIStackView 设置为Fill Equally,然后将UIStackView 的边缘固定到UITableViewCell 的边缘。这是UIStackView 开箱即用的众多功能之一。 【参考方案1】:

你说:

注意:我不能在情节提要中使用自动布局,因为我正在创建可变数量的按钮。

您无法直接在 Interface Builder 中添加可变数量的按钮,但没有什么可以阻止您使用自动布局。您需要设置的基本自动布局约束是:

将按钮设置为相同宽度; 设置按钮,使其前导约束连接到前一个按钮的尾随约束; 第一个按钮的前导约束应该连接到容器视图;和 最后一个按钮的尾随约束也应连接到容器。

因此,例如,在 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

或者,在 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

而且,您也可以使用UILayoutGuide,而不是按钮之间的固定间距(使参考线彼此大小相同,但按钮宽度的百分比,无论父视图的宽度)。

您也可以使用UIStackView,这是使控件在视图中均匀分布的另一种好方法。

归根结底,使用自动布局有很多方法可以实现这一点。

【讨论】:

【参考方案2】:

可能是因为您在单元格布局其子视图之前执行此操作,并且它的大小与在 Any-Any 大小类 600 * 600 中设置的大小相同。

尝试在layoutSubviews 方法中添加按钮,如下所示:

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

    // add your buttons here


【讨论】:

这正是正在发生的事情。谢谢。【参考方案3】:

您好,有多种方法可以解决您的问题:

    使用 Autolayout,您可以在代码和 StoryBoard 中使用 Autolayout ;-)。忍耐一下,我没有检查 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)
    
    

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

    使用 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)
        
    
    

来源:http://snapkit.io/docs/

我首选的版本是 Snapkit,因为它比 Autolayout 更简洁。

【讨论】:

您可以使用 iOS 9 约束语法来代替 Snapkit,它同样具有表达力和简洁性,但不需要第三方库。 这是一个很好的答案。 Hossam 的答案恰好最适合我正在构建的这个特定应用程序,但这通常更有用,并且在未来的应用程序中对我有用。非常感谢。【参考方案4】:

UIStackView 正是您所需要的。在下面查看我的教程:

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

【讨论】:

以上是关于Swift以编程方式制作宽度百分比的主要内容,如果未能解决你的问题,请参考以下文章

几种网页布局方式

如何制作具有相同宽度百分比的响应式表格?

当宽度根据百分比动态变化时,制作一个 <div> 正方形 [重复]

06.网页布局

我可以将 div 高度编程为当前宽度的一定百分比吗? [复制]

如何在给定的分钟内以编程方式更新圆形百分比指示器的进度颜色?