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

Swift5中如何通过代码居中子视图?现有代码未达预期求修正

子视图在UIButton中居中失效的修正方案

我尝试让子视图在UIButton内居中,但未达到预期效果,相关代码如下:

创建按钮的代码:

private lazy var uploadButton: UIButton = {
        let button = UIButton()
        let innerView = UIView(frame: CGRect(x: 0, y: 0, width: 136, height: 63))
        innerView.backgroundColor = .cyan
        innerView.center = CGPoint(x: button.frame.size.width/2, y: button.frame.size.height/2)
        button.addSubview(innerView)
        button.layer.cornerRadius = 30
        button.backgroundColor = .white
        button.layer.shadowColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.25).cgColor
        button.layer.shadowOpacity = 1
        button.layer.shadowOffset = CGSize.zero
        button.layer.shadowRadius = 6
        return button
    }()

按钮的Auto Layout约束代码:

view.addSubview(uploadButton)
uploadButton.translatesAutoresizingMaskIntoConstraints = false
// ...
uploadButton.bottomAnchor.constraint(equalTo: nextButton.topAnchor, constant: -69),
            uploadButton.leftAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leftAnchor, constant: 38),
            uploadButton.rightAnchor.constraint(equalTo: view.safeAreaLayoutGuide.rightAnchor, constant: -38),
            uploadButton.heightAnchor.constraint(equalToConstant: 171)
// all active

当前效果:
子视图未居中效果


问题原因

创建uploadButton时,按钮的frame还未被Auto Layout计算确定,此时button.frame.size.width和button.frame.size.height的值都是0,导致innerView.center被设置为(0,0),子视图只能固定在按钮的左上角,无法随按钮尺寸变化居中。

修正方案

方案一:使用Auto Layout约束子视图(推荐)

直接给innerView添加居中约束和宽高约束,让Auto Layout自动管理其位置,无论按钮尺寸如何变化都能保持居中:

private lazy var uploadButton: UIButton = {
    let button = UIButton()
    button.layer.cornerRadius = 30
    button.backgroundColor = .white
    button.layer.shadowColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.25).cgColor
    button.layer.shadowOpacity = 1
    button.layer.shadowOffset = CGSize.zero
    button.layer.shadowRadius = 6
    
    // 创建innerView并关闭自动转换约束
    let innerView = UIView()
    innerView.backgroundColor = .cyan
    innerView.translatesAutoresizingMaskIntoConstraints = false
    button.addSubview(innerView)
    
    // 激活居中及宽高约束
    NSLayoutConstraint.activate([
        innerView.centerXAnchor.constraint(equalTo: button.centerXAnchor),
        innerView.centerYAnchor.constraint(equalTo: button.centerYAnchor),
        innerView.widthAnchor.constraint(equalToConstant: 136),
        innerView.heightAnchor.constraint(equalToConstant: 63)
    ])
    
    return button
}()

方案二:重写按钮的layoutSubviews方法

如果偏好使用frame布局,可以自定义UIButton子类,在layoutSubviews中更新innerView的位置(该方法会在按钮尺寸变化时被调用):

class CustomButton: UIButton {
    let innerView = UIView()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupView()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        setupView()
    }
    
    private func setupView() {
        innerView.backgroundColor = .cyan
        innerView.frame = CGRect(x: 0, y: 0, width: 136, height: 63)
        addSubview(innerView)
        
        layer.cornerRadius = 30
        backgroundColor = .white
        layer.shadowColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.25).cgColor
        layer.shadowOpacity = 1
        layer.shadowOffset = CGSize.zero
        layer.shadowRadius = 6
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        // 每次布局时更新innerView的中心位置
        innerView.center = CGPoint(x: bounds.midX, y: bounds.midY)
    }
}

// 使用自定义按钮创建uploadButton
private lazy var uploadButton: CustomButton = {
    let button = CustomButton()
    return button
}()

内容的提问来源于stack exchange,提问作者Suee97

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 08:22:56