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

iOS 15及以上Swift中UIButton图片居右设置失效问题

解决iOS 15中UIButton图片居右失效问题

问题描述

在iOS 15版本中设置UIButton图片居右失效,该功能在iOS 15之前可正常工作。

预期效果:
ExpectedResult

实际效果:
ActualResult

原代码

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
    }
}

问题原因

  1. 新旧配置冲突:iOS 15+使用UIButton.Configuration时,setupGeneralSettings中设置的contentHorizontalAlignment = .left会覆盖Configuration的布局逻辑,导致图片无法靠右。
  2. 废弃属性混用:iOS 15已废弃titleEdgeInsets、contentEdgeInsets等属性,继续使用会干扰新配置的布局效果。
  3. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 10:30:56