iOS 代码设置UIButton字体后Background Configuration丢失问题
问题描述
在UICollectionView中使用UIButton时,通过代码修改按钮字体会导致Xcode属性检查器中的*Background Configuration(背景配置)*区域消失,问题效果见下图:
该现象的触发逻辑为:若要让直接修改titleLabel.font的代码生效,按钮文本样式需设置为Default,但设置后无法通过Storyboard的背景配置区域调整按钮圆角样式。手动通过代码添加圆角样式未生效,相关逻辑位于代码段靠近底部的if语句区域,原有实现代码如下:
import UIKit class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource { @IBOutlet weak var collectionViewButtons: UICollectionView! override func viewDidLoad() { super.viewDidLoad() collectionViewButtons.delegate = self collectionViewButtons.dataSource = self } func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return 6 // 按钮总数 } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! ButtonCollectionViewCell cell.buttonLive.setTitle("Handling a Breakup", for: .normal) // 设置按钮标题 cell.buttonLive.titleLabel!.font = UIFont(name: "Marker Felt", size: 20) _ = UIButton.Configuration.CornerStyle.large if indexPath.item == 0 { // 第一个按钮 cell.buttonLive.backgroundColor = UIColor.darkGray // 设置按钮背景色 } else if indexPath.item == 1 { // 第二个按钮 cell.buttonLive.backgroundColor = UIColor.systemGray cell.buttonLive.setTitle("Good Work", for: .normal) } else if indexPath.item == 2 { // 第三个按钮 cell.buttonLive.backgroundColor = UIColor.darkGray } else { // 其余按钮 cell.buttonLive.backgroundColor = UIColor.darkGray } return cell } func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { if indexPath.item == 0 { // 点击第一个按钮跳转对应页面 // let vc = storyboard?.instantiateViewController(withIdentifier: "anyVC1") as! ViewController1 // navigationController?.pushViewController(vc, animated: true) } // else if indexPath.item == 1 { // let vc = storyboard?.instantiateViewController(withIdentifier: "anyVC2") as! ViewController2 // navigationController?.pushViewController(vc, animated: true) // } // else if indexPath.item == 2 { // let vc = storyboard?.instantiateViewController(withIdentifier: "anyVC3") as! ViewController3 // navigationController?.pushViewController(vc, animated: true) // } // else { // let vc = storyboard?.instantiateViewController(withIdentifier: "anyVC4") as! ViewController4 // navigationController?.pushViewController(vc, animated: true) // } } // 修改return后的数值即可调整展示的按钮总数 }
问题原因
- Xcode属性检查器的Background Configuration区域,仅在按钮使用iOS 15及以上版本新增的
UIButton.Configuration样式时显示。当按钮文本样式设为Default、直接通过titleLabel属性修改字体时,系统会自动将按钮切换回旧版传统UIButton渲染模式,背景配置区域会自动隐藏。 - 代码中
_ = UIButton.Configuration.CornerStyle.large仅读取了圆角样式的枚举值,未将其赋值给按钮的配置对象,因此圆角设置不会生效。
修复方案
不需要将按钮切回旧版样式,直接基于UIButton.Configuration接口修改字体和圆角属性,即可同时保留Storyboard配置能力、实现自定义样式效果,核心修改点在cellForItemAt方法的按钮配置逻辑:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! ButtonCollectionViewCell // 读取当前按钮已有的配置,若不存在则初始化filled类型配置 var config = cell.buttonLive.configuration ?? .filled() // 设置大圆角样式 config.cornerStyle = .large // 通过配置的文本属性转换器设置自定义字体,无需直接修改titleLabel.font config.titleTextAttributesTransformer = UIConfigurationTextAttributesTransformer { attributes in var updatedAttributes = attributes updatedAttributes.font = UIFont(name: "Marker Felt", size: 20) return updatedAttributes } // 按位置设置按钮标题和背景色 switch indexPath.item { case 1: config.title = "Good Work" config.baseBackgroundColor = .systemGray default: config.title = "Handling a Breakup" config.baseBackgroundColor = .darkGray } // 将修改后的配置重新赋值给按钮 cell.buttonLive.configuration = config return cell }
- 使用Configuration样式的按钮,不要直接修改
backgroundColor属性,需通过config.baseBackgroundColor设置背景色,否则会出现样式覆盖异常。 - Storyboard中按钮的Style选项保持
Plain/Filled等Configuration类型即可,不需要切换为Default,背景配置区域会正常显示。
内容的提问来源于stack exchange,提问作者Dakota Davis
相关产品推荐
相关产品推荐

