Swift:根据屏幕尺寸动态约束按钮尺寸

标签 swift

我试图根据屏幕的大小动态限制 stackView 中的按钮。最终目标是将按钮的半径限制为 stackView 中每个堆栈的 50%。

我在 stackView 中有三个按钮。到目前为止我的代码:

class PeopleContainerView: UIView {

    let stackContainerView: UIView = {
        let v = UIView()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.backgroundColor = .blue
        return v
    }()

    let stackView: UIStackView = {
        let sv = UIStackView()
        sv.translatesAutoresizingMaskIntoConstraints = false
        sv.distribution = .fillEqually
        sv.backgroundColor = .gray
        return sv
    }()

    let previousButton: UIButton = {
        let b = UIButton()
        b.translatesAutoresizingMaskIntoConstraints = false
        b.backgroundColor = .faintGray
        b.setImage(UIImage(named: "ic_keyboard_arrow_left"), for: .normal)
        return b
    }()

    let nextButton: UIButton = {
        let b = UIButton()
        b.translatesAutoresizingMaskIntoConstraints = false
        b.backgroundColor = .faintGray
        b.setImage(UIImage(named: "ic_keyboard_arrow_right"), for: .normal)
        return b
    }()

    let chatButton: UIButton = {
        let b = UIButton()
        b.translatesAutoresizingMaskIntoConstraints = false
        b.backgroundColor = .customPink
        b.setImage(UIImage(named: "ic_forum"), for: .normal)
        return b
    }()

    override init(frame: CGRect) {
        super.init(frame: frame)

        setupViews()
    }

    func setupViews() {
        addSubview(stackContainerView)
        stackContainerView.addSubview(stackView)

        stackContainerView.topAnchor.constraint(equalTo: collectionView.bottomAnchor).isActive = true
        stackContainerView.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 15).isActive = true
        stackContainerView.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -15).isActive = true
        stackContainerView.heightAnchor.constraint(equalTo: self.heightAnchor, multiplier: 0.3).isActive = true

        stackView.topAnchor.constraint(equalTo: stackContainerView.topAnchor).isActive = true
        stackView.heightAnchor.constraint(equalTo: stackContainerView.heightAnchor).isActive = true
        stackView.widthAnchor.constraint(equalTo: stackContainerView.widthAnchor, multiplier: 0.75).isActive = true
        stackView.centerXAnchor.constraint(equalTo: stackContainerView.centerXAnchor).isActive = true

        stackView.addArrangedSubview(previousButton)
        stackView.addArrangedSubview(chatButton)
        stackView.addArrangedSubview(nextButton)

        //Below two lines break the constraints
        previousButton.widthAnchor.constraint(equalTo: stackView.widthAnchor, multiplier: 0.3 * 0.5).isActive = true
        previousButton.heightAnchor.constraint(equalTo: stackView.widthAnchor, multiplier: 0.3 * 0.5).isActive = true

    }

}

此后,在 viewController 中,我将对此 View 执行 addSubview() 操作。我当前代码的最后两行此时确实调整了按钮的大小,但打破了其他限制。最终,我还需要动态添加一个cornerRadius。请看截图:

最后两行 -

enter image description here

没有最后两行 -

enter image description here

如果有人能建议我这里哪里出了问题,那就太好了,谢谢。

编辑1: 我的最终目标是实现以下 UI: enter image description here

编辑2: 我对 Rikesh 建议的尝试

class PeopleContainerView: UIView {

    let stackContainerView: UIView = {
        let v = UIView()
        v.translatesAutoresizingMaskIntoConstraints = false
        return v
    }()

    let stackView: UIStackView = {
        let sv = UIStackView()
        sv.translatesAutoresizingMaskIntoConstraints = false
        sv.distribution = .fillEqually
        return sv
    }()

    let previousButton: UIButton = {
        let b = UIButton()
        b.translatesAutoresizingMaskIntoConstraints = false
        b.backgroundColor = .faintGray
        b.setImage(UIImage(named: "ic_keyboard_arrow_left"), for: .normal)
        return b
    }()

    let nextButton: UIButton = {
        let b = UIButton(frame: CGRect(x: 0, y: 0, width: 20, height: 20))
        b.translatesAutoresizingMaskIntoConstraints = false
        b.backgroundColor = .faintGray
        b.setImage(UIImage(named: "ic_keyboard_arrow_right"), for: .normal)
        return b
    }()

    //New attempt to create a custom Wrapper View
    let chatButton: ButtonView = {
        let b = ButtonView()
        b.translatesAutoresizingMaskIntoConstraints = false
        return b
    }()

    override init(frame: CGRect) {
        super.init(frame: frame)
        setupViews()
    }

    func setupViews() {
        addSubview(stackContainerView)
        stackContainerView.addSubview(stackView)

        stackContainerView.topAnchor.constraint(equalTo: collectionView.bottomAnchor).isActive = true
        stackContainerView.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 15).isActive = true
        stackContainerView.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -15).isActive = true
        stackContainerView.heightAnchor.constraint(equalTo: self.heightAnchor, multiplier: 0.3).isActive = true

        stackView.topAnchor.constraint(equalTo: collectionView.bottomAnchor).isActive = true
        stackView.heightAnchor.constraint(equalTo: self.heightAnchor, multiplier: 0.2).isActive = true
        stackView.widthAnchor.constraint(equalTo: self.widthAnchor, multiplier: 0.75).isActive = true
        stackView.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true

        stackView.addArrangedSubview(previousButton)
        stackView.addArrangedSubview(chatButton)
        stackView.addArrangedSubview(nextButton)
    }
}

class ButtonView: UIView {
    let containerView: UIView = {
        let v = UIView()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.backgroundColor = .customPink
        return v
    }()

    let button: UIButton = {
        let b = UIButton()
        b.translatesAutoresizingMaskIntoConstraints = false
        b.layer.cornerRadius = 30
        return b
    }()

    override init(frame: CGRect) {
        super.init(frame: frame)

        setupViews()
    }

    func setupViews() {
        addSubview(containerView)
        containerView.addSubview(button)

        containerView.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
        containerView.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
        containerView.widthAnchor.constraint(equalToConstant: 20).isActive = true
        containerView.heightAnchor.constraint(equalToConstant: 20).isActive = true

        button.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
        button.widthAnchor.constraint(equalToConstant: 20).isActive = true
        button.heightAnchor.constraint(equalToConstant: 20).isActive = true
        button.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
    }

打开 peopleContainerView 时的结果:

enter image description here

未打开时的结果:

enter image description here

最佳答案

enter image description here

如果我正确理解了您的问题,我想建议如下解决方案:

  1. 首先将 1 个 View 添加到 stackview 中
  2. 使 stackview 等于间距
  3. 在 View 中添加按钮
  4. 向按钮添加约束

    a.纵横比 1:1

    b. height = 0.6 * 父 View 高度

    c.水平居中

    d.垂直居中

  5. 在 stackview 中创建 3 个 View 副本

关于Swift:根据屏幕尺寸动态约束按钮尺寸,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48502672/

相关文章:

ios - 运行 pod update 后构建失败

swift - 将按钮放置在节页眉/页脚上时,iOS 14 上出现奇怪的 UI 渲染问题

ios - UIViewController 多重继承

core-data - 检查零核心数据属性导致 EXC_BAD_ACCESS

Swift:打印存储在变量中的函数的名称

ios - 如何增加 UIButton 的点击区域?

ios - NSPredicate 在 NSFetchRequest 中等于 nil

json - 获取对象的索引返回 nil

swift - 部署自定义运行时 lambda 时 sam 包太大

SwiftUI:NavigationButton 初始值设定项给出错误