iOS 15及以上Swift中UIButton图片居右设置失效问题
问题描述
在iOS 15版本中设置UIButton图片居右失效,该功能在iOS 15之前可正常工作。
预期效果:
实际效果:
原代码
import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() let btnDropdown = getDropdownButton() btnDropdown.translatesAutoresizingMaskIntoConstraints = false view.addSubview(btnDropdown) NSLayoutConstraint.activate([ btnDropdown.heightAnchor.constraint(equalToConstant: 44), btnDropdown.leadingAnchor.constraint(equalTo: view.layoutMarginsGuide.leadingAnchor), btnDropdown.trailingAnchor.constraint(equalTo: view.layoutMarginsGuide.trailingAnchor), btnDropdown.topAnchor.constraint(equalTo: view.layoutMarginsGuide.topAnchor, constant: 30) ]) } fileprivate func getDropdownButton() -> UIButton { var button: UIButton! if #available(iOS 15.0, *), let btnConfig = getButtonConfiguration() { button = UIButton(configuration: btnConfig) } else { button = UIButton(type: .custom) } button.setTitle("Select Tags", for: .normal) setupGeneralSettings(for: button) return button } fileprivate func setupGeneralSettings(for button: UIButton) { button.titleEdgeInsets = UIEdgeInsets(top: 0, left: 8, bottom: 0, right: 8) button.contentEdgeInsets = UIEdgeInsets(top: 0, left: 8, bottom: 0, right: 8) button.contentHorizontalAlignment = .left button.layer.borderWidth = 1 button.layer.cornerRadius = 8 button.clipsToBounds = true button.backgroundColor = .lightGray.withAlphaComponent(0.3) button.titleLabel?.font = UIFont.systemFont(ofSize: 14, weight: .medium) button.setTitleColor(UIColor.black, for: .normal) } @available(iOS 15.0, *) fileprivate func getButtonConfiguration() -> UIButton.Configuration? { var btnConfig = UIButton.Configuration.plain() btnConfig.buttonSize = .medium btnConfig.titleAlignment = .leading btnConfig.imagePlacement = .trailing btnConfig.image = UIImage(systemName: "arrowtriangle.down.circle") btnConfig.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 8, bottom: 0, trailing: 8) btnConfig.titleTextAttributesTransformer = UIConfigurationTextAttributesTransformer { incoming in var outgoing = incoming outgoing.font = UIFont.systemFont(ofSize: 14, weight: .medium) return outgoing } return btnConfig } }
问题原因
- 新旧配置冲突:iOS 15+使用
UIButton.Configuration时,setupGeneralSettings中设置的contentHorizontalAlignment = .left会覆盖Configuration的布局逻辑,导致图片无法靠右。 - 废弃属性混用:iOS 15已废弃
titleEdgeInsets、contentEdgeInsets等属性,继续使用会干扰新配置的布局效果。 - Configuration配置不全:原配置缺少图片与标题的间距设置,且未通过Configuration统一管理背景色、边框等样式。
解决方案
修改setupGeneralSettings方法
针对iOS版本做分支处理,iOS 15+不再设置废弃的布局属性,避免干扰Configuration:
fileprivate func setupGeneralSettings(for button: UIButton) { button.layer.borderWidth = 1 button.layer.cornerRadius = 8 button.clipsToBounds = true button.backgroundColor = .lightGray.withAlphaComponent(0.3) if #unavailable(iOS 15.0) { // iOS 15以下保留旧方法配置 button.titleEdgeInsets = UIEdgeInsets(top: 0, left: 8, bottom: 0, right: 8) button.contentEdgeInsets = UIEdgeInsets(top: 0, left: 8, bottom: 0, right: 8) button.contentHorizontalAlignment = .left button.titleLabel?.font = UIFont.systemFont(ofSize: 14, weight: .medium) button.setTitleColor(UIColor.black, for: .normal) } }
完善getButtonConfiguration方法
通过Configuration统一管理所有样式,添加图片间距并确保布局逻辑正确:
@available(iOS 15.0, *) fileprivate func getButtonConfiguration() -> UIButton.Configuration? { var btnConfig = UIButton.Configuration.plain() btnConfig.buttonSize = .medium btnConfig.titleAlignment = .leading btnConfig.imagePlacement = .trailing btnConfig.imagePadding = 8 // 控制标题与图片的间距 btnConfig.image = UIImage(systemName: "arrowtriangle.down.circle") btnConfig.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 8, bottom: 0, trailing: 8) // 统一配置文字样式 btnConfig.titleTextAttributesTransformer = UIConfigurationTextAttributesTransformer { incoming in var outgoing = incoming outgoing.font = UIFont.systemFont(ofSize: 14, weight: .medium) outgoing.foregroundColor = UIColor.black return outgoing } // 统一配置背景与边框 btnConfig.background.backgroundColor = .lightGray.withAlphaComponent(0.3) btnConfig.background.cornerRadius = 8 btnConfig.background.strokeWidth = 1 btnConfig.background.strokeColor = UIColor.black // 根据需求调整边框颜色 return btnConfig }
调整getDropdownButton方法
iOS 15+的Button无需额外调用setTitle,通过Configuration统一设置标题:
fileprivate func getDropdownButton() -> UIButton { var button: UIButton! if #available(iOS 15.0, *), let btnConfig = getButtonConfiguration() { btnConfig.title = "Select Tags" // 通过Configuration设置标题 button = UIButton(configuration: btnConfig) } else { button = UIButton(type: .custom) button.setTitle("Select Tags", for: .normal) } setupGeneralSettings(for: button) return button }
修改后,iOS 15+的Button完全通过UIButton.Configuration管理布局与样式,避免新旧属性冲突,图片会自动靠右对齐,符合预期效果。
内容的提问来源于stack exchange,提问作者Rajat Mishra
相关产品推荐
相关产品推荐

