Swift5中如何通过代码居中子视图?现有代码未达预期求修正
我尝试让子视图在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
相关产品推荐
相关产品推荐

