You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中如何通过代码修改弹窗内自定义UIButton的尺寸

问题根因

当前代码同时混用Auto Layout约束和frame属性修改,当translatesAutoresizingMaskIntoConstraints设为false时,视图的尺寸、位置完全由激活的约束决定,直接修改frame的代码不会生效。代码中写的button.frame.size.width = 140属于冗余无效代码。
另外当前闭包初始化按钮时调用addTarget(self, ...)存在崩溃风险:非lazy的闭包初始化属性执行时,类实例还未完成初始化,此时self不存在,会导致异常。

方案1:保留Auto Layout布局(推荐,匹配当前代码逻辑)

你当前已经给按钮设置了固定宽度140的约束,要动态修改尺寸,只需要把需要调整的约束存为类属性,后续直接修改约束的constant值即可,不要操作frame属性。
修正后的代码示例:

class SuccessMessageView: UIView, UITextFieldDelegate {
    // 存储按钮宽度约束,方便后续修改
    private var buttonWidthConstraint: NSLayoutConstraint!
    // 高度约束如果需要动态修改也可以同理存储
    // private var buttonHeightConstraint: NSLayoutConstraint!

    // 改为lazy属性,等类实例初始化完成后再创建按钮,避免self引用崩溃
    private lazy var buttonConfirm : UIButton = {
        let button = UIButton()
        button.setTitle("Ok", for: .normal)
        button.backgroundColor = UIColor(rgb: PreferenceManager.shared.hasDevice() ? purpleColour : orangeColour)
        button.setTitleColor(.white, for: .normal)
        button.layer.cornerRadius = 10
        button.addTarget(self, action: #selector(confirmFunc), for: .touchUpInside) // 常规交互建议用touchUpInside,符合iOS交互习惯
        
        button.translatesAutoresizingMaskIntoConstraints = false
        // 初始化默认宽度约束并赋值给类属性
        buttonWidthConstraint = button.widthAnchor.constraint(equalToConstant: 140.0)
        buttonWidthConstraint.isActive = true
        // 高度如果是固定值可以直接在这里设置约束
        button.heightAnchor.constraint(equalToConstant: 44).isActive = true
        return button
    }()

    // 需要修改按钮尺寸时调用该方法
    private func updateButtonSize(width: CGFloat) {
        // 直接修改约束的constant值
        buttonWidthConstraint.constant = width
        // 如果需要动画效果,就把layoutIfNeeded包在UIView.animate闭包中
        self.layoutIfNeeded()
    }
}
方案2:全Frame布局(不推荐,弹窗多屏幕适配成本高)

如果不想使用Auto Layout,需要删除所有约束相关代码,保持translatesAutoresizingMaskIntoConstraints为默认的true状态,之后直接修改frame即可调整尺寸:

class SuccessMessageView: UIView, UITextFieldDelegate {
    private var buttonConfirm : UIButton = {
        // 初始化时直接给默认frame
        let button = UIButton(frame: CGRect(x: 0, y: 0, width: 140, height: 44))
        button.setTitle("Ok", for: .normal)
        button.backgroundColor = UIColor(rgb: PreferenceManager.shared.hasDevice() ? purpleColour : orangeColour)
        button.setTitleColor(.white, for: .normal)
        button.layer.cornerRadius = 10
        // 注意:非lazy闭包初始化不要在这里addTarget,和之前一样会有self引用崩溃问题
        return button
    }()

    // 视图完成布局后再设置位置、绑定事件
    override func layoutSubviews() {
        super.layoutSubviews()
        // 这里设置按钮的位置,保证在弹窗中居中
        buttonConfirm.center = CGPoint(x: self.bounds.midX, y: self.bounds.midY)
        buttonConfirm.addTarget(self, action: #selector(confirmFunc), for: .touchUpInside)
    }

    // 修改尺寸直接调整frame
    private func updateButtonSize(width: CGFloat) {
        buttonConfirm.frame.size.width = width
        // 修改尺寸后重新调整位置,避免错位
        buttonConfirm.center.x = self.bounds.midX
    }
}

内容的提问来源于stack exchange,提问作者Min Thein Win

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 03:15:38